package com.ruoyi.ccdi.project.controller;

import com.ruoyi.ccdi.project.domain.dto.CcdiProjectImportHistoryDTO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectVO;
import com.ruoyi.ccdi.project.service.ICcdiProjectService;
import com.ruoyi.common.core.domain.AjaxResult;
import io.swagger.v3.oas.annotations.Operation;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;

import java.lang.reflect.Method;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;

@ExtendWith(MockitoExtension.class)
class CcdiProjectControllerTest {

    @InjectMocks
    private CcdiProjectController controller;

    @Mock
    private ICcdiProjectService projectService;

    @Test
    void shouldArchiveProject() throws Exception {
        try (MockedStatic<com.ruoyi.common.utils.SecurityUtils> mocked = mockStatic(com.ruoyi.common.utils.SecurityUtils.class)) {
            mocked.when(com.ruoyi.common.utils.SecurityUtils::getUsername).thenReturn("tester");

            AjaxResult result = controller.archiveProject(40L);

            assertEquals(200, result.get("code"));
            assertEquals("项目归档成功", result.get("msg"));
            verify(projectService).archiveProject(40L, "tester");
        }

        Method method = CcdiProjectController.class.getMethod("archiveProject", Long.class);
        PostMapping postMapping = method.getAnnotation(PostMapping.class);
        PreAuthorize preAuthorize = method.getAnnotation(PreAuthorize.class);
        Operation operation = method.getAnnotation(Operation.class);

        assertNotNull(postMapping);
        assertEquals("/{projectId}/archive", postMapping.value()[0]);
        assertNotNull(preAuthorize);
        assertEquals("@ss.hasPermi('ccdi:project:edit')", preAuthorize.value());
        assertNotNull(operation);
        assertEquals("归档项目", operation.summary());
    }

    @Test
    void shouldImportFromHistoryAndReturnCreatedProject() {
        CcdiProjectImportHistoryDTO dto = new CcdiProjectImportHistoryDTO();
        dto.setProjectName("新建项目");

        CcdiProjectVO project = new CcdiProjectVO();
        project.setProjectId(88L);
        project.setProjectName("新建项目");
        when(projectService.importFromHistory(eq(dto), eq("tester"))).thenReturn(project);

        try (MockedStatic<com.ruoyi.common.utils.SecurityUtils> mocked = mockStatic(com.ruoyi.common.utils.SecurityUtils.class)) {
            mocked.when(com.ruoyi.common.utils.SecurityUtils::getUsername).thenReturn("tester");

            AjaxResult result = controller.importFromHistory(dto);

            assertEquals(200, result.get("code"));
            assertEquals("项目创建成功", result.get("msg"));
            assertSame(project, result.get("data"));
            verify(projectService).importFromHistory(dto, "tester");
        }
    }
}
