package com.ruoyi.info.collection.controller;

import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.info.collection.domain.excel.CcdiIntermediaryEnterpriseRelationExcel;
import com.ruoyi.info.collection.domain.excel.CcdiIntermediaryPersonExcel;
import com.ruoyi.info.collection.domain.vo.ImportResultVO;
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
import com.ruoyi.info.collection.domain.vo.IntermediaryEnterpriseRelationImportFailureVO;
import com.ruoyi.info.collection.domain.vo.IntermediaryPersonImportFailureVO;
import com.ruoyi.info.collection.service.ICcdiIntermediaryEnterpriseRelationImportService;
import com.ruoyi.info.collection.service.ICcdiIntermediaryPersonImportService;
import com.ruoyi.info.collection.service.ICcdiIntermediaryService;
import com.ruoyi.info.collection.utils.EasyExcelUtil;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.mock.web.MockMultipartFile;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class CcdiIntermediaryControllerTest {

    @InjectMocks
    private CcdiIntermediaryController controller;

    @Mock
    private ICcdiIntermediaryService intermediaryService;

    @Mock
    private ICcdiIntermediaryPersonImportService personImportService;

    @Mock
    private ICcdiIntermediaryEnterpriseRelationImportService enterpriseRelationImportService;

    @Test
    void importPersonData_shouldReturnWarnWhenExcelHasNoRows() throws Exception {
        MockMultipartFile file = new MockMultipartFile(
            "file",
            "intermediary-empty.xlsx",
            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            "empty".getBytes(StandardCharsets.UTF_8)
        );

        try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
            mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiIntermediaryPersonExcel.class)))
                .thenReturn(List.of());

            AjaxResult result = controller.importPersonData(file);

            assertEquals(HttpStatus.ERROR, result.get(AjaxResult.CODE_TAG));
            assertEquals("至少需要一条数据", result.get(AjaxResult.MSG_TAG));
        }
    }

    @Test
    void importPersonData_shouldReturnSuccessWhenTaskCreated() throws Exception {
        MockMultipartFile file = new MockMultipartFile(
            "file",
            "intermediary-person.xlsx",
            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            "person".getBytes(StandardCharsets.UTF_8)
        );
        CcdiIntermediaryPersonExcel excel = new CcdiIntermediaryPersonExcel();
        excel.setPersonId("320101199001010011");
        when(intermediaryService.importIntermediaryPerson(List.of(excel))).thenReturn("task-person");

        try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
            mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiIntermediaryPersonExcel.class)))
                .thenReturn(List.of(excel));

            AjaxResult result = controller.importPersonData(file);

            assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
            ImportResultVO data = (ImportResultVO) result.get(AjaxResult.DATA_TAG);
            assertEquals("task-person", data.getTaskId());
        }
    }

    @Test
    void importEnterpriseRelationData_shouldReturnSuccessWhenTaskCreated() throws Exception {
        MockMultipartFile file = new MockMultipartFile(
            "file",
            "intermediary-relation.xlsx",
            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            "relation".getBytes(StandardCharsets.UTF_8)
        );
        CcdiIntermediaryEnterpriseRelationExcel excel = new CcdiIntermediaryEnterpriseRelationExcel();
        excel.setOwnerPersonId("320101199001010011");
        excel.setSocialCreditCode("91330100MA27X12345");
        when(intermediaryService.importIntermediaryEnterpriseRelation(List.of(excel))).thenReturn("task-relation");

        try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
            mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiIntermediaryEnterpriseRelationExcel.class)))
                .thenReturn(List.of(excel));

            AjaxResult result = controller.importEnterpriseRelationData(file);

            assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
            ImportResultVO data = (ImportResultVO) result.get(AjaxResult.DATA_TAG);
            assertEquals("task-relation", data.getTaskId());
        }
    }

    @Test
    void getEnterpriseRelationImportStatus_shouldDelegateToRelationImportService() {
        ImportStatusVO statusVO = new ImportStatusVO();
        statusVO.setTaskId("task-status");
        when(enterpriseRelationImportService.getImportStatus("task-status")).thenReturn(statusVO);

        AjaxResult result = controller.getEnterpriseRelationImportStatus("task-status");

        assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
        assertEquals(statusVO, result.get(AjaxResult.DATA_TAG));
    }

    @Test
    void getEnterpriseRelationImportFailures_shouldReturnPagedRows() {
        IntermediaryEnterpriseRelationImportFailureVO failure1 = new IntermediaryEnterpriseRelationImportFailureVO();
        failure1.setOwnerPersonId("A1");
        IntermediaryEnterpriseRelationImportFailureVO failure2 = new IntermediaryEnterpriseRelationImportFailureVO();
        failure2.setOwnerPersonId("A2");
        when(enterpriseRelationImportService.getImportFailures("task-failures")).thenReturn(List.of(failure1, failure2));

        TableDataInfo result = controller.getEnterpriseRelationImportFailures("task-failures", 2, 1);

        assertEquals(2, result.getTotal());
        assertEquals(1, result.getRows().size());
        assertEquals("A2", ((IntermediaryEnterpriseRelationImportFailureVO) result.getRows().get(0)).getOwnerPersonId());
    }

    @Test
    void getPersonImportFailures_shouldReturnPagedRows() {
        IntermediaryPersonImportFailureVO failure1 = new IntermediaryPersonImportFailureVO();
        failure1.setPersonId("A1");
        IntermediaryPersonImportFailureVO failure2 = new IntermediaryPersonImportFailureVO();
        failure2.setPersonId("A2");
        when(personImportService.getImportFailures("task-person-failures")).thenReturn(List.of(failure1, failure2));

        TableDataInfo result = controller.getPersonImportFailures("task-person-failures", 2, 1);

        assertEquals(2, result.getTotal());
        assertEquals(1, result.getRows().size());
        assertEquals("A2", ((IntermediaryPersonImportFailureVO) result.getRows().get(0)).getPersonId());
    }

    @Test
    void importEnterpriseRelationTemplate_shouldUseRelationTemplateName() {
        try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
            controller.importEnterpriseRelationTemplate(null);

            mocked.verify(() -> EasyExcelUtil.importTemplateWithDictDropdown(
                null,
                CcdiIntermediaryEnterpriseRelationExcel.class,
                "中介实体关联关系信息"
            ));
        }
    }
}
