package com.njcn.rdms.module.project.service.project;

import com.njcn.rdms.framework.test.core.ut.BaseMockitoUnitTest;
import com.njcn.rdms.module.project.controller.admin.project.execution.vo.execution.ProjectExecutionStatusBoardReqVO;
import com.njcn.rdms.module.project.controller.admin.project.execution.vo.execution.ProjectExecutionStatusBoardRespVO;
import com.njcn.rdms.module.project.controller.admin.project.task.vo.ProjectTaskStatusBoardReqVO;
import com.njcn.rdms.module.project.controller.admin.project.task.vo.ProjectTaskStatusBoardRespVO;
import com.njcn.rdms.module.project.dal.dataobject.status.ObjectStatusModelDO;
import com.njcn.rdms.module.project.dal.mysql.project.execution.ProjectExecutionMapper;
import com.njcn.rdms.module.project.dal.mysql.project.task.ProjectTaskMapper;
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusModelMapper;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;

import java.time.LocalDateTime;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

class ProjectStatusBoardServiceTest extends BaseMockitoUnitTest {

    @InjectMocks
    private ProjectStatusBoardServiceImpl projectStatusBoardService;
    @Mock
    private ObjectStatusModelMapper objectStatusModelMapper;
    @Mock
    private ProjectExecutionMapper projectExecutionMapper;
    @Mock
    private ProjectTaskMapper projectTaskMapper;

    @Test
    void getExecutionStatusBoard_shouldReturnEnabledStatusesInSortOrderAndSumCounts() {
        when(objectStatusModelMapper.selectListByObjectTypeEnabled("execution")).thenReturn(List.of(
                createStatus("pending", "待开始", 10, false),
                createStatus("active", "进行中", 20, false),
                createStatus("paused", "已暂停", 30, false),
                createStatus("completed", "已完成", 40, true),
                createStatus("cancelled", "已取消", 50, true),
                createStatus("disabled", "已停用", 60, false, 1)
        ));
        when(projectExecutionMapper.countByProjectIdAndStatusCode(eq(2001L),
                any(ProjectExecutionStatusBoardReqVO.class), eq("pending"),
                any(), any(), any(), any())).thenReturn(3);
        when(projectExecutionMapper.countByProjectIdAndStatusCode(eq(2001L),
                any(ProjectExecutionStatusBoardReqVO.class), eq("active"),
                any(), any(), any(), any())).thenReturn(8);
        when(projectExecutionMapper.countByProjectIdAndStatusCode(eq(2001L),
                any(ProjectExecutionStatusBoardReqVO.class), eq("paused"),
                any(), any(), any(), any())).thenReturn(2);
        when(projectExecutionMapper.countByProjectIdAndStatusCode(eq(2001L),
                any(ProjectExecutionStatusBoardReqVO.class), eq("completed"),
                any(), any(), any(), any())).thenReturn(4);
        when(projectExecutionMapper.countByProjectIdAndStatusCode(eq(2001L),
                any(ProjectExecutionStatusBoardReqVO.class), eq("cancelled"),
                any(), any(), any(), any())).thenReturn(1);

        ProjectExecutionStatusBoardReqVO reqVO = new ProjectExecutionStatusBoardReqVO();
        reqVO.setKeyword("接口");
        reqVO.setExecutionType("feature");
        reqVO.setOwnerId(3001L);
        reqVO.setUpdateTime(new LocalDateTime[]{LocalDateTime.of(2026, 5, 1, 0, 0), LocalDateTime.of(2026, 5, 31, 23, 59, 59)});

        ProjectExecutionStatusBoardRespVO result = projectStatusBoardService.getExecutionStatusBoard(2001L, reqVO);

        assertEquals(18L, result.getTotal());
        assertEquals(5, result.getItems().size());
        assertEquals("pending", result.getItems().get(0).getStatusCode());
        assertEquals("active", result.getItems().get(1).getStatusCode());
        assertEquals("paused", result.getItems().get(2).getStatusCode());
        assertEquals("completed", result.getItems().get(3).getStatusCode());
        assertEquals("cancelled", result.getItems().get(4).getStatusCode());
        assertTrue(result.getItems().get(3).getTerminal());
        assertFalse(result.getItems().get(0).getTerminal());
        assertEquals(10, result.getItems().get(0).getSort());
    }

    @Test
    void getTaskStatusBoard_shouldReturnEnabledStatusesInSortOrderAndSumCounts() {
        when(objectStatusModelMapper.selectListByObjectTypeEnabled("task")).thenReturn(List.of(
                createStatus("pending", "待开始", 10, false),
                createStatus("active", "进行中", 20, false),
                createStatus("paused", "已暂停", 30, false),
                createStatus("completed", "已完成", 40, true),
                createStatus("cancelled", "已取消", 50, true)
        ));
        when(projectTaskMapper.countByProjectIdAndExecutionIdAndStatusCode(eq(2001L), eq(5001L),
                any(ProjectTaskStatusBoardReqVO.class), eq("pending"))).thenReturn(5);
        when(projectTaskMapper.countByProjectIdAndExecutionIdAndStatusCode(eq(2001L), eq(5001L),
                any(ProjectTaskStatusBoardReqVO.class), eq("active"))).thenReturn(12);
        when(projectTaskMapper.countByProjectIdAndExecutionIdAndStatusCode(eq(2001L), eq(5001L),
                any(ProjectTaskStatusBoardReqVO.class), eq("paused"))).thenReturn(2);
        when(projectTaskMapper.countByProjectIdAndExecutionIdAndStatusCode(eq(2001L), eq(5001L),
                any(ProjectTaskStatusBoardReqVO.class), eq("completed"))).thenReturn(4);
        when(projectTaskMapper.countByProjectIdAndExecutionIdAndStatusCode(eq(2001L), eq(5001L),
                any(ProjectTaskStatusBoardReqVO.class), eq("cancelled"))).thenReturn(1);

        ProjectTaskStatusBoardReqVO reqVO = new ProjectTaskStatusBoardReqVO();
        reqVO.setKeyword("任务");
        reqVO.setParentTaskId(9001L);
        reqVO.setOwnerId(3002L);
        reqVO.setUpdateTime(new LocalDateTime[]{LocalDateTime.of(2026, 5, 1, 0, 0), LocalDateTime.of(2026, 5, 31, 23, 59, 59)});

        ProjectTaskStatusBoardRespVO result = projectStatusBoardService.getTaskStatusBoard(2001L, 5001L, reqVO);

        assertEquals(24L, result.getTotal());
        assertEquals(5, result.getItems().size());
        assertEquals("pending", result.getItems().get(0).getStatusCode());
        assertEquals("active", result.getItems().get(1).getStatusCode());
        assertEquals("paused", result.getItems().get(2).getStatusCode());
        assertEquals("completed", result.getItems().get(3).getStatusCode());
        assertEquals("cancelled", result.getItems().get(4).getStatusCode());
    }

    private ObjectStatusModelDO createStatus(String statusCode, String statusName, int sort, boolean terminalFlag) {
        return createStatus(statusCode, statusName, sort, terminalFlag, 0);
    }

    private ObjectStatusModelDO createStatus(String statusCode, String statusName, int sort,
                                             boolean terminalFlag, int status) {
        ObjectStatusModelDO statusModel = new ObjectStatusModelDO();
        statusModel.setStatusCode(statusCode);
        statusModel.setStatusName(statusName);
        statusModel.setSort(sort);
        statusModel.setTerminalFlag(terminalFlag);
        statusModel.setStatus(status);
        return statusModel;
    }

}
