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

import com.njcn.rdms.framework.common.exception.ServiceException;
import com.njcn.rdms.framework.test.core.ut.BaseMockitoUnitTest;
import com.njcn.rdms.module.project.controller.admin.product.vo.setting.ProductSettingLifecycleRespVO;
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 ProductStatusViewServiceTest extends BaseMockitoUnitTest {

    @InjectMocks
    private ProductStatusViewService productStatusViewService;
    @Mock
    private ObjectStatusModelMapper objectStatusModelMapper;
    @Mock
    private ObjectStatusTransitionMapper objectStatusTransitionMapper;

    @Test
    void getLifecycle_shouldReturnStatusMetadataAndActions() {
        ObjectStatusModelDO statusModel = new ObjectStatusModelDO();
        statusModel.setObjectType("product");
        statusModel.setStatusCode("active");
        statusModel.setStatusName("启用");
        statusModel.setTerminalFlag(false);
        statusModel.setAllowEdit(true);
        statusModel.setStatus(0);

        ObjectStatusTransitionDO transition = new ObjectStatusTransitionDO();
        transition.setActionCode("pause");
        transition.setActionName("暂停");
        transition.setNeedReason(true);

        when(objectStatusModelMapper.selectByObjectTypeAndStatusCodeEnabled("product", "active"))
                .thenReturn(statusModel);
        when(objectStatusTransitionMapper.selectListByObjectTypeAndFromStatus("product", "active"))
                .thenReturn(List.of(transition));

        ProductSettingLifecycleRespVO result =
                productStatusViewService.getLifecycle("active", "恢复正常推进");

        assertEquals("active", result.getStatusCode());
        assertEquals("启用", result.getStatusName());
        assertFalse(result.getTerminal());
        assertTrue(result.getAllowEdit());
        assertEquals("恢复正常推进", result.getLastStatusReason());
        assertEquals(1, result.getAvailableActions().size());
        assertEquals("pause", result.getAvailableActions().get(0).getActionCode());
    }

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

        ServiceException ex = assertThrows(ServiceException.class,
                () -> productStatusViewService.getLifecycle("active", null));
        assertEquals(ErrorCodeConstants.PRODUCT_STATUS_MODEL_NOT_EXISTS_OR_DISABLED.getCode(), ex.getCode());
    }

}
