package com.ruoyi.ccdi.project.controller;

import com.ruoyi.ccdi.project.domain.dto.CcdiProjectExtendedPurchaseDetailQueryDTO;
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectExtendedPurchaseQueryDTO;
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectExtendedRecruitmentDetailQueryDTO;
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectExtendedRecruitmentQueryDTO;
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectExtendedTransferDetailQueryDTO;
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectExtendedTransferQueryDTO;
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectFamilyAssetLiabilityDetailQueryDTO;
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectFamilyAssetLiabilityListQueryDTO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectExtendedPurchaseDetailVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectExtendedPurchaseListVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectExtendedRecruitmentDetailVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectExtendedRecruitmentListVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectExtendedTransferDetailVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectExtendedTransferListVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectFamilyAssetLiabilityDetailVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectFamilyAssetLiabilityListVO;
import com.ruoyi.ccdi.project.service.ICcdiProjectSpecialCheckService;
import com.ruoyi.common.core.domain.AjaxResult;
import io.swagger.v3.oas.annotations.Operation;
import java.lang.reflect.Method;
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 org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class CcdiProjectSpecialCheckControllerTest {

    @InjectMocks
    private CcdiProjectSpecialCheckController controller;

    @Mock
    private ICcdiProjectSpecialCheckService specialCheckService;

    @Test
    void shouldExposeFamilyAssetLiabilityListEndpoint() throws Exception {
        CcdiProjectFamilyAssetLiabilityListQueryDTO queryDTO = new CcdiProjectFamilyAssetLiabilityListQueryDTO();
        queryDTO.setProjectId(40L);
        when(specialCheckService.getFamilyAssetLiabilityList(queryDTO)).thenReturn(new CcdiProjectFamilyAssetLiabilityListVO());

        AjaxResult result = controller.getFamilyAssetLiabilityList(queryDTO);

        assertEquals(200, result.get("code"));
        verify(specialCheckService).getFamilyAssetLiabilityList(queryDTO);

        RequestMapping mapping = CcdiProjectSpecialCheckController.class.getAnnotation(RequestMapping.class);
        Method method = CcdiProjectSpecialCheckController.class.getMethod(
            "getFamilyAssetLiabilityList",
            CcdiProjectFamilyAssetLiabilityListQueryDTO.class
        );
        GetMapping getMapping = method.getAnnotation(GetMapping.class);
        PreAuthorize preAuthorize = method.getAnnotation(PreAuthorize.class);
        Operation operation = method.getAnnotation(Operation.class);

        assertNotNull(mapping);
        assertEquals("/ccdi/project/special-check", mapping.value()[0]);
        assertNotNull(getMapping);
        assertEquals("/family-asset-liability/list", getMapping.value()[0]);
        assertNotNull(preAuthorize);
        assertEquals("@ss.hasPermi('ccdi:project:query')", preAuthorize.value());
        assertNotNull(operation);
    }

    @Test
    void shouldExposeFamilyAssetLiabilityDetailEndpoint() throws Exception {
        CcdiProjectFamilyAssetLiabilityDetailQueryDTO queryDTO = new CcdiProjectFamilyAssetLiabilityDetailQueryDTO();
        queryDTO.setProjectId(40L);
        queryDTO.setStaffIdCard("330102199001011234");
        when(specialCheckService.getFamilyAssetLiabilityDetail(queryDTO))
            .thenReturn(new CcdiProjectFamilyAssetLiabilityDetailVO());

        AjaxResult result = controller.getFamilyAssetLiabilityDetail(queryDTO);

        assertEquals(200, result.get("code"));
        verify(specialCheckService).getFamilyAssetLiabilityDetail(queryDTO);

        Method method = CcdiProjectSpecialCheckController.class.getMethod(
            "getFamilyAssetLiabilityDetail",
            CcdiProjectFamilyAssetLiabilityDetailQueryDTO.class
        );
        GetMapping getMapping = method.getAnnotation(GetMapping.class);
        PreAuthorize preAuthorize = method.getAnnotation(PreAuthorize.class);
        Operation operation = method.getAnnotation(Operation.class);

        assertNotNull(getMapping);
        assertEquals("/family-asset-liability/detail", getMapping.value()[0]);
        assertNotNull(preAuthorize);
        assertEquals("@ss.hasPermi('ccdi:project:query')", preAuthorize.value());
        assertNotNull(operation);
    }

    @Test
    void shouldReturnAjaxResultSuccessForExtendedPurchaseEndpoints() {
        CcdiProjectExtendedPurchaseQueryDTO listQuery = new CcdiProjectExtendedPurchaseQueryDTO();
        listQuery.setProjectId(40L);
        CcdiProjectExtendedPurchaseListVO listVO = new CcdiProjectExtendedPurchaseListVO();
        when(specialCheckService.getExtendedPurchaseList(listQuery)).thenReturn(listVO);

        AjaxResult listResult = controller.getExtendedPurchaseList(listQuery);

        assertEquals(200, listResult.get("code"));
        assertEquals(listVO, listResult.get("data"));

        CcdiProjectExtendedPurchaseDetailQueryDTO detailQuery = new CcdiProjectExtendedPurchaseDetailQueryDTO();
        detailQuery.setProjectId(40L);
        detailQuery.setPurchaseId("CG-001");
        CcdiProjectExtendedPurchaseDetailVO detailVO = new CcdiProjectExtendedPurchaseDetailVO();
        when(specialCheckService.getExtendedPurchaseDetail(detailQuery)).thenReturn(detailVO);

        AjaxResult detailResult = controller.getExtendedPurchaseDetail(detailQuery);

        assertEquals(200, detailResult.get("code"));
        assertEquals(detailVO, detailResult.get("data"));
    }

    @Test
    void shouldReturnAjaxResultSuccessForExtendedRecruitmentEndpoints() {
        CcdiProjectExtendedRecruitmentQueryDTO listQuery = new CcdiProjectExtendedRecruitmentQueryDTO();
        listQuery.setProjectId(40L);
        CcdiProjectExtendedRecruitmentListVO listVO = new CcdiProjectExtendedRecruitmentListVO();
        when(specialCheckService.getExtendedRecruitmentList(listQuery)).thenReturn(listVO);

        AjaxResult listResult = controller.getExtendedRecruitmentList(listQuery);

        assertEquals(200, listResult.get("code"));
        assertEquals(listVO, listResult.get("data"));

        CcdiProjectExtendedRecruitmentDetailQueryDTO detailQuery = new CcdiProjectExtendedRecruitmentDetailQueryDTO();
        detailQuery.setProjectId(40L);
        detailQuery.setRecruitId("ZP-001");
        CcdiProjectExtendedRecruitmentDetailVO detailVO = new CcdiProjectExtendedRecruitmentDetailVO();
        when(specialCheckService.getExtendedRecruitmentDetail(detailQuery)).thenReturn(detailVO);

        AjaxResult detailResult = controller.getExtendedRecruitmentDetail(detailQuery);

        assertEquals(200, detailResult.get("code"));
        assertEquals(detailVO, detailResult.get("data"));
    }

    @Test
    void shouldReturnAjaxResultSuccessForExtendedTransferEndpoints() {
        CcdiProjectExtendedTransferQueryDTO listQuery = new CcdiProjectExtendedTransferQueryDTO();
        listQuery.setProjectId(40L);
        CcdiProjectExtendedTransferListVO listVO = new CcdiProjectExtendedTransferListVO();
        when(specialCheckService.getExtendedTransferList(listQuery)).thenReturn(listVO);

        AjaxResult listResult = controller.getExtendedTransferList(listQuery);

        assertEquals(200, listResult.get("code"));
        assertEquals(listVO, listResult.get("data"));

        CcdiProjectExtendedTransferDetailQueryDTO detailQuery = new CcdiProjectExtendedTransferDetailQueryDTO();
        detailQuery.setProjectId(40L);
        detailQuery.setId(1L);
        CcdiProjectExtendedTransferDetailVO detailVO = new CcdiProjectExtendedTransferDetailVO();
        when(specialCheckService.getExtendedTransferDetail(detailQuery)).thenReturn(detailVO);

        AjaxResult detailResult = controller.getExtendedTransferDetail(detailQuery);

        assertEquals(200, detailResult.get("code"));
        assertEquals(detailVO, detailResult.get("data"));
    }
}
