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

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.model.pc.source.entity.MemberSourceEntity;
import com.ycwl.basic.service.pc.processor.VideoRecreationHandler;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.*;

/**
 * HandleVideoRecreationStage 单元测试
 */
@ExtendWith(MockitoExtension.class)
class HandleVideoRecreationStageTest {

    @Mock
    private VideoRecreationHandler videoRecreationHandler;

    @InjectMocks
    private HandleVideoRecreationStage 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_MemberSourceListNull_Skipped() {
        // Given: memberSourceList为null
        context.setMemberSourceList(null);

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

        // Then
        assertTrue(result.isSkipped());
        verify(videoRecreationHandler, never()).handleVideoRecreation(
                anyLong(), anyList(), anyLong(), anyLong(), anyList(), anyBoolean());
    }

    @Test
    void testExecute_MemberSourceListEmpty_Skipped() {
        // Given: memberSourceList为空
        context.setMemberSourceList(new ArrayList<>());

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

        // Then
        assertTrue(result.isSkipped());
        verify(videoRecreationHandler, never()).handleVideoRecreation(
                anyLong(), anyList(), anyLong(), anyLong(), anyList(), anyBoolean());
    }

    @Test
    void testExecute_Success_WithSampleListIds() {
        // Given: 有memberSourceList和sampleListIds
        List<MemberSourceEntity> memberSourceList = createMemberSourceList(3);
        context.setMemberSourceList(memberSourceList);

        List<Long> sampleListIds = Arrays.asList(101L, 102L, 103L);
        context.setSampleListIds(sampleListIds);

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

        // Then
        assertTrue(result.isSuccess());
        assertTrue(result.getMessage().contains("视频重切处理完成"));
        verify(videoRecreationHandler, times(1)).handleVideoRecreation(
                10L, memberSourceList, 1L, 100L, sampleListIds, true);
    }

    @Test
    void testExecute_Success_NullSampleListIds() {
        // Given: sampleListIds为null
        List<MemberSourceEntity> memberSourceList = createMemberSourceList(3);
        context.setMemberSourceList(memberSourceList);

        context.setSampleListIds(null);

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

        // Then
        assertTrue(result.isSuccess());
        verify(videoRecreationHandler, times(1)).handleVideoRecreation(
                10L, memberSourceList, 1L, 100L, null, true);
    }

    @Test
    void testExecute_Success_EmptySampleListIds() {
        // Given: sampleListIds为空
        List<MemberSourceEntity> memberSourceList = createMemberSourceList(3);
        context.setMemberSourceList(memberSourceList);

        context.setSampleListIds(new ArrayList<>());

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

        // Then
        assertTrue(result.isSuccess());
        verify(videoRecreationHandler, times(1)).handleVideoRecreation(
                10L, memberSourceList, 1L, 100L, new ArrayList<>(), true);
    }

    @Test
    void testExecute_OldUser() {
        // Given: 老用户
        context = FaceMatchingContext.forAutoMatching(1L, false);
        context.setFace(face);

        List<MemberSourceEntity> memberSourceList = createMemberSourceList(3);
        context.setMemberSourceList(memberSourceList);

        List<Long> sampleListIds = Arrays.asList(101L);
        context.setSampleListIds(sampleListIds);

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

        // Then
        assertTrue(result.isSuccess());
        verify(videoRecreationHandler, times(1)).handleVideoRecreation(
                10L, memberSourceList, 1L, 100L, sampleListIds, false);
    }

    @Test
    void testExecute_HandlerFailed_Degraded() {
        // Given: 处理器执行失败
        List<MemberSourceEntity> memberSourceList = createMemberSourceList(3);
        context.setMemberSourceList(memberSourceList);

        List<Long> sampleListIds = Arrays.asList(101L);
        context.setSampleListIds(sampleListIds);

        doThrow(new RuntimeException("Handler error"))
                .when(videoRecreationHandler).handleVideoRecreation(
                        10L, memberSourceList, 1L, 100L, sampleListIds, true);

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

        // Then
        assertTrue(result.isDegraded());
        assertTrue(result.getMessage().contains("视频重切处理失败"));
        verify(videoRecreationHandler, times(1)).handleVideoRecreation(
                10L, memberSourceList, 1L, 100L, sampleListIds, true);
    }

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

        List<MemberSourceEntity> memberSourceList = createMemberSourceList(3);
        context.setMemberSourceList(memberSourceList);

        List<Long> sampleListIds = Arrays.asList(101L);
        context.setSampleListIds(sampleListIds);

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

        // Then
        assertTrue(result.isSuccess());
        verify(videoRecreationHandler, times(1)).handleVideoRecreation(
                888L, memberSourceList, 1L, 100L, sampleListIds, true);
    }

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

        List<MemberSourceEntity> memberSourceList = createMemberSourceList(3);
        context.setMemberSourceList(memberSourceList);

        List<Long> sampleListIds = Arrays.asList(101L);
        context.setSampleListIds(sampleListIds);

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

        // Then
        assertTrue(result.isSuccess());
        verify(videoRecreationHandler, times(1)).handleVideoRecreation(
                10L, memberSourceList, 777L, 100L, sampleListIds, true);
    }

    @Test
    void testExecute_DifferentMemberId() {
        // Given: 不同的memberId
        face.setMemberId(999L);

        List<MemberSourceEntity> memberSourceList = createMemberSourceList(3);
        context.setMemberSourceList(memberSourceList);

        List<Long> sampleListIds = Arrays.asList(101L);
        context.setSampleListIds(sampleListIds);

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

        // Then
        assertTrue(result.isSuccess());
        verify(videoRecreationHandler, times(1)).handleVideoRecreation(
                10L, memberSourceList, 1L, 999L, sampleListIds, true);
    }

    @Test
    void testExecute_ManySources() {
        // Given: 大量源文件
        List<MemberSourceEntity> memberSourceList = createMemberSourceList(20);
        context.setMemberSourceList(memberSourceList);

        List<Long> sampleListIds = Arrays.asList(101L, 102L, 103L, 104L, 105L);
        context.setSampleListIds(sampleListIds);

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

        // Then
        assertTrue(result.isSuccess());
        verify(videoRecreationHandler, times(1)).handleVideoRecreation(
                10L, memberSourceList, 1L, 100L, sampleListIds, true);
    }

    @Test
    void testExecute_NullPointerException_Degraded() {
        // Given: 空指针异常
        List<MemberSourceEntity> memberSourceList = createMemberSourceList(3);
        context.setMemberSourceList(memberSourceList);

        doThrow(new NullPointerException("Null handler"))
                .when(videoRecreationHandler).handleVideoRecreation(
                        anyLong(), anyList(), anyLong(), anyLong(), anyList(), anyBoolean());

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

        // Then
        assertTrue(result.isDegraded());
        assertTrue(result.getMessage().contains("视频重切处理失败"));
    }

    private List<MemberSourceEntity> createMemberSourceList(int count) {
        List<MemberSourceEntity> list = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            MemberSourceEntity entity = new MemberSourceEntity();
            entity.setMemberId(100L);
            entity.setSourceId((long) (i + 1));
            list.add(entity);
        }
        return list;
    }
}
