package com.mosquito.project.permission;

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.Collections;
import java.util.List;
import java.util.Optional;

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

/**
 * 审批流服务单元测试
 */
@ExtendWith(MockitoExtension.class)
class ApprovalFlowServiceTest {

    @Mock
    private ApprovalFlowRepository flowRepository;

    @Mock
    private ApprovalRecordRepository recordRepository;

    @Mock
    private ApprovalHistoryRepository historyRepository;

    @InjectMocks
    private ApprovalFlowService approvalFlowService;

    /**
     * 测试审批状态常量
     */
    @Test
    void testStatusConstants() {
        assertEquals("PENDING", ApprovalFlowService.STATUS_PENDING);
        assertEquals("APPROVED", ApprovalFlowService.STATUS_APPROVED);
        assertEquals("REJECTED", ApprovalFlowService.STATUS_REJECTED);
        assertEquals("PROCESSING", ApprovalFlowService.STATUS_PROCESSING);
        assertEquals("CANCELLED", ApprovalFlowService.STATUS_CANCELLED);
    }

    /**
     * 测试审批动作常量
     */
    @Test
    void testActionConstants() {
        assertEquals("SUBMIT", ApprovalFlowService.ACTION_SUBMIT);
        assertEquals("APPROVE", ApprovalFlowService.ACTION_APPROVE);
        assertEquals("REJECT", ApprovalFlowService.ACTION_REJECT);
        assertEquals("TRANSFER", ApprovalFlowService.ACTION_TRANSFER);
    }

    /**
     * 测试提交审批 - 流程不存在
     */
    @Test
    void testSubmitApproval_FlowNotFound() {
        when(flowRepository.findById(999L)).thenReturn(Optional.empty());

        assertThrows(IllegalArgumentException.class, () ->
            approvalFlowService.submitApproval(
                999L, "ACTIVITY", 100L, "测试活动", 1000L, "申请理由"
            )
        );
    }

    /**
     * 测试提交审批 - 流程已禁用
     */
    @Test
    void testSubmitApproval_FlowDisabled() {
        // 模拟禁用流程
        when(flowRepository.findById(1L)).thenReturn(Optional.empty());

        assertThrows(IllegalArgumentException.class, () ->
            approvalFlowService.submitApproval(
                1L, "ACTIVITY", 100L, "测试活动", 1000L, "申请理由"
            )
        );
    }

    /**
     * 测试提交审批 - 已有待处理审批
     */
    @Test
    void testSubmitApproval_ExistingPendingApproval() {
        // 模拟流程不存在的情况
        when(flowRepository.findById(1L)).thenReturn(Optional.empty());

        // 预期抛出异常
        assertThrows(IllegalArgumentException.class, () ->
            approvalFlowService.submitApproval(
                1L, "ACTIVITY", 100L, "测试活动", 1000L, "申请理由"
            )
        );
    }

    /**
     * 测试处理审批 - 记录不存在
     */
    @Test
    void testHandleApproval_RecordNotFound() {
        when(recordRepository.findById(999L)).thenReturn(Optional.empty());

        assertThrows(IllegalArgumentException.class, () ->
            approvalFlowService.handleApproval(999L, "APPROVE", Long.valueOf(1001L), "同意")
        );
    }

    /**
     * 测试处理审批 - 无效动作
     */
    @Test
    void testHandleApproval_InvalidAction() {
        // 模拟记录存在但查询流程配置失败
        when(recordRepository.findById(1L)).thenReturn(Optional.empty());

        assertThrows(IllegalArgumentException.class, () ->
            approvalFlowService.handleApproval(1L, "INVALID_ACTION", Long.valueOf(1001L), "测试")
        );
    }

    /**
     * 测试取消审批 - 记录不存在
     */
    @Test
    void testCancelApproval_RecordNotFound() {
        when(recordRepository.findById(999L)).thenReturn(Optional.empty());

        assertThrows(IllegalArgumentException.class, () ->
            approvalFlowService.cancelApproval(999L, Long.valueOf(1000L))
        );
    }

    /**
     * 测试获取待审批列表 - 正常返回
     */
    @Test
    void testGetPendingApprovals() {
        when(recordRepository.findPendingByApproverId(1001L))
            .thenReturn(Collections.emptyList());

        List<SysApprovalRecord> result = approvalFlowService.getPendingApprovals(1001L);

        assertNotNull(result);
        assertTrue(result.isEmpty());
        verify(recordRepository).findPendingByApproverId(1001L);
    }

    /**
     * 测试获取我发起的审批
     */
    @Test
    void testGetMyApplications() {
        when(recordRepository.findByApplicantId(1000L))
            .thenReturn(Collections.emptyList());

        List<SysApprovalRecord> result = approvalFlowService.getMyApplications(1000L);

        assertNotNull(result);
        assertTrue(result.isEmpty());
        verify(recordRepository).findByApplicantId(1000L);
    }

    /**
     * 测试获取审批记录 - 记录不存在
     */
    @Test
    void testGetRecordById_NotFound() {
        when(recordRepository.findById(999L)).thenReturn(Optional.empty());

        var result = approvalFlowService.getRecordById(999L);

        assertNull(result);
    }

    /**
     * 测试获取审批历史
     */
    @Test
    void testGetApprovalHistory() {
        when(historyRepository.findByRecordIdOrderByNodeIndexDesc(1L))
            .thenReturn(Collections.emptyList());

        List<SysApprovalHistory> result = approvalFlowService.getApprovalHistory(1L);

        assertNotNull(result);
        assertTrue(result.isEmpty());
        verify(historyRepository).findByRecordIdOrderByNodeIndexDesc(1L);
    }

    /**
     * 测试获取所有审批流程
     */
    @Test
    void testGetAllFlows() {
        when(flowRepository.findAll()).thenReturn(Collections.emptyList());

        List<SysApprovalFlow> result = approvalFlowService.getAllFlows();

        assertNotNull(result);
        assertTrue(result.isEmpty());
        verify(flowRepository).findAll();
    }

    /**
     * 测试获取启用的审批流程
     */
    @Test
    void testGetEnabledFlows() {
        when(flowRepository.findByStatus("ENABLED")).thenReturn(Collections.emptyList());

        List<SysApprovalFlow> result = approvalFlowService.getEnabledFlows();

        assertNotNull(result);
        assertTrue(result.isEmpty());
        verify(flowRepository).findByStatus("ENABLED");
    }
}
