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

import com.njcn.rdms.framework.common.exception.ServiceException;
import com.njcn.rdms.framework.test.core.ut.BaseMockitoUnitTest;
import com.njcn.rdms.module.project.dal.dataobject.status.ObjectStatusModelDO;
import com.njcn.rdms.module.project.dal.dataobject.status.ObjectStatusTransitionDO;
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusModelMapper;
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusTransitionMapper;
import com.njcn.rdms.module.project.enums.ErrorCodeConstants;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;

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.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.when;

class ProjectStatusViewServiceTest extends BaseMockitoUnitTest {

    @InjectMocks
    private ProjectStatusViewService projectStatusViewService;
    @Mock
    private ObjectStatusModelMapper objectStatusModelMapper;
    @Mock
    private ObjectStatusTransitionMapper objectStatusTransitionMapper;

    @Test
    void getLifecycle_shouldReturnStatusMetadataAndActions() {
        ObjectStatusModelDO statusModel = new ObjectStatusModelDO();
        statusModel.setObjectType("project");
        statusModel.setStatusCode("pending");
        statusModel.setStatusName("待开始");
        statusModel.setTerminalFlag(false);
        statusModel.setAllowEdit(true);
        statusModel.setStatus(0);

        ObjectStatusTransitionDO autoStartTransition = new ObjectStatusTransitionDO();
        autoStartTransition.setActionCode("auto_start");
        autoStartTransition.setActionName("自动进入进行中");
        autoStartTransition.setNeedReason(false);
        ObjectStatusTransitionDO transition = new ObjectStatusTransitionDO();
        transition.setActionCode("cancel");
        transition.setActionName("取消");
        transition.setNeedReason(true);

        when(objectStatusModelMapper.selectByObjectTypeAndStatusCodeEnabled("project", "pending"))
                .thenReturn(statusModel);
        when(objectStatusTransitionMapper.selectListByObjectTypeAndFromStatus("project", "pending"))
                .thenReturn(List.of(autoStartTransition, transition));

        ProjectStatusViewService.ProjectLifecycleView result = projectStatusViewService.getLifecycle("pending");

        assertEquals("待开始", result.statusName());
        assertFalse(result.terminal());
        assertTrue(result.allowEdit());
        assertEquals(1, result.availableActions().size());
        assertEquals("cancel", result.availableActions().get(0).getActionCode());
    }

    @Test
    void getLifecycle_whenStatusModelMissing_shouldThrowException() {
        when(objectStatusModelMapper.selectByObjectTypeAndStatusCodeEnabled("project", "pending"))
                .thenReturn(null);

        ServiceException ex = assertThrows(ServiceException.class,
                () -> projectStatusViewService.getLifecycle("pending"));
        assertEquals(ErrorCodeConstants.PROJECT_STATUS_MODEL_NOT_EXISTS_OR_DISABLED.getCode(), ex.getCode());
    }

}
