package com.ycwl.basic.face.pipeline.stages;

import com.ycwl.basic.biz.FaceStatusManager;
import com.ycwl.basic.enums.FaceCutStatus;
import com.ycwl.basic.face.pipeline.core.FaceMatchingContext;
import com.ycwl.basic.pipeline.core.StageResult;
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.service.pc.helper.ScenicConfigFacade;
import com.ycwl.basic.service.task.TaskService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

/**
 * CreateTaskStage 单元测试
 */
@ExtendWith(MockitoExtension.class)
class CreateTaskStageTest {

    @Mock
    private ScenicConfigFacade scenicConfigFacade;

    @Mock
    private TaskService taskService;

    @Mock
    private FaceStatusManager faceStatusManager;


    @InjectMocks
    private CreateTaskStage stage;

    private FaceMatchingContext context;
    private FaceEntity face;

    @BeforeEach
    void setUp() {
        context = FaceMatchingContext.forAutoMatching(1L, true);

        face = new FaceEntity();
        face.setId(1L);
        face.setMemberId(100L);
        face.setScenicId(10L);

        context.setFace(face);
    }

    @Test
    void testExecute_AutoCreateTask_Success() {
        // Given: 配置为自动创建任务(faceSelectFirst = false)
        when(scenicConfigFacade.isFaceSelectFirst(10L))
                .thenReturn(false);

        // When
        StageResult<FaceMatchingContext> result = stage.execute(context);

        // Then
        assertTrue(result.isSuccess());
        assertTrue(result.getMessage().contains("自动创建任务成功"));
        verify(scenicConfigFacade, times(1)).isFaceSelectFirst(10L);
        verify(taskService, times(1)).autoCreateTaskByFaceId(1L);
        verify(faceStatusManager, never()).setFaceCutStatus(anyLong(), any(FaceCutStatus.class));
    }

    @Test
    void testExecute_WaitForUserSelection_Skipped() {
        // Given: 配置为等待用户选择(faceSelectFirst = true)
        when(scenicConfigFacade.isFaceSelectFirst(10L))
                .thenReturn(true);

        // When
        StageResult<FaceMatchingContext> result = stage.execute(context);

        // Then
        assertTrue(result.isSkipped());
        assertTrue(result.getMessage().contains("等待用户手动选择"));
        verify(scenicConfigFacade, times(1)).isFaceSelectFirst(10L);
        verify(faceStatusManager, times(1)).setFaceCutStatus(1L, FaceCutStatus.WAITING_USER_SELECT);
        verify(taskService, never()).autoCreateTaskByFaceId(anyLong());
    }

    @Test
    void testExecute_CheckConfigFailed_Degraded() {
        // Given: 查询配置失败
        when(scenicConfigFacade.isFaceSelectFirst(10L))
                .thenThrow(new RuntimeException("Config service error"));

        // When
        StageResult<FaceMatchingContext> result = stage.execute(context);

        // Then
        assertTrue(result.isDegraded());
        assertTrue(result.getMessage().contains("任务创建失败"));
        verify(scenicConfigFacade, times(1)).isFaceSelectFirst(10L);
        verify(taskService, never()).autoCreateTaskByFaceId(anyLong());
        verify(faceStatusManager, never()).setFaceCutStatus(anyLong(), any(FaceCutStatus.class));
    }

    @Test
    void testExecute_AutoCreateTaskFailed_Degraded() {
        // Given: 自动创建任务失败
        when(scenicConfigFacade.isFaceSelectFirst(10L))
                .thenReturn(false);
        doThrow(new RuntimeException("Task creation error"))
                .when(taskService).autoCreateTaskByFaceId(1L);

        // When
        StageResult<FaceMatchingContext> result = stage.execute(context);

        // Then
        assertTrue(result.isDegraded());
        assertTrue(result.getMessage().contains("任务创建失败"));
        verify(taskService, times(1)).autoCreateTaskByFaceId(1L);
    }

    @Test
    void testExecute_SetStatusFailed_Degraded() {
        // Given: 设置状态失败
        when(scenicConfigFacade.isFaceSelectFirst(10L))
                .thenReturn(true);
        doThrow(new RuntimeException("Status set error"))
                .when(faceStatusManager).setFaceCutStatus(1L, FaceCutStatus.WAITING_USER_SELECT);

        // When
        StageResult<FaceMatchingContext> result = stage.execute(context);

        // Then
        assertTrue(result.isDegraded());
        assertTrue(result.getMessage().contains("任务创建失败"));
        verify(faceStatusManager, times(1)).setFaceCutStatus(1L, FaceCutStatus.WAITING_USER_SELECT);
    }

    @Test
    void testExecute_DifferentScenicId() {
        // Given: 不同的景区ID
        face.setScenicId(999L);

        when(scenicConfigFacade.isFaceSelectFirst(999L))
                .thenReturn(false);

        // When
        StageResult<FaceMatchingContext> result = stage.execute(context);

        // Then
        assertTrue(result.isSuccess());
        verify(scenicConfigFacade, times(1)).isFaceSelectFirst(999L);
        verify(taskService, times(1)).autoCreateTaskByFaceId(1L);
    }

    @Test
    void testExecute_DifferentFaceId() {
        // Given: 不同的faceId
        context = FaceMatchingContext.forAutoMatching(888L, true);
        face.setId(888L);
        context.setFace(face);

        when(scenicConfigFacade.isFaceSelectFirst(10L))
                .thenReturn(false);

        // When
        StageResult<FaceMatchingContext> result = stage.execute(context);

        // Then
        assertTrue(result.isSuccess());
        verify(taskService, times(1)).autoCreateTaskByFaceId(888L);
    }

    @Test
    void testExecute_NullPointerException_Degraded() {
        // Given: 空指针异常
        when(scenicConfigFacade.isFaceSelectFirst(10L))
                .thenThrow(new NullPointerException("Null scenic config"));

        // When
        StageResult<FaceMatchingContext> result = stage.execute(context);

        // Then
        assertTrue(result.isDegraded());
        assertTrue(result.getMessage().contains("任务创建失败"));
    }
}
