//package com.njcn.gather.aireport.testreport.service.impl;
//
//import com.njcn.common.pojo.exception.BusinessException;
//import com.njcn.gather.aireport.reportmodel.component.ReportModelFileStorageService;
//import com.njcn.gather.aireport.reportmodel.service.ReportModelService;
//import com.njcn.gather.aireport.testreport.component.TestReportLedgerImportService;
//import com.njcn.gather.aireport.testreport.component.TestReportLedgerTemplateService;
//import com.njcn.gather.aireport.testreport.component.TestReportPointExcelParser;
//import com.njcn.gather.aireport.testreport.component.TestReportStorageService;
//import com.njcn.gather.aireport.testreport.mapper.TestReportGroupReportMapper;
//import com.njcn.gather.aireport.testreport.mapper.TestReportMapper;
//import com.njcn.gather.aireport.testreport.mapper.TestReportPointMapper;
//import com.njcn.gather.aireport.testreport.pojo.constant.TestReportConst;
//import com.njcn.gather.aireport.testreport.pojo.param.TestReportParam;
//import com.njcn.gather.aireport.testreport.pojo.po.TestReportGroupReportPO;
//import com.njcn.gather.aireport.testreport.pojo.po.TestReportPO;
//import com.njcn.gather.aireport.testreport.pojo.po.TestReportPointPO;
//import com.njcn.gather.aireport.testreport.pojo.vo.TestReportLedgerValidateResultVO;
//import com.njcn.gather.aireport.testreport.pojo.vo.TestReportPointVO;
//import com.njcn.gather.aireport.testreport.pojo.vo.TestReportVO;
//import com.njcn.gather.comservice.filepreview.FilePreviewService;
//import com.njcn.gather.system.dictionary.pojo.po.DictData;
//import com.njcn.gather.system.dictionary.pojo.po.DictType;
//import com.njcn.gather.system.dictionary.service.IDictDataService;
//import com.njcn.gather.system.dictionary.service.IDictTypeService;
//import com.njcn.gather.system.pojo.constant.DictConst;
//import org.junit.jupiter.api.Assertions;
//import org.junit.jupiter.api.Test;
//import org.springframework.mock.web.MockMultipartFile;
//import org.springframework.web.multipart.MultipartFile;
//
//import java.io.InputStream;
//import java.lang.reflect.Method;
//import java.nio.file.Files;
//import java.nio.file.Paths;
//import java.util.Arrays;
//import java.util.Collections;
//import java.util.HashMap;
//import java.util.Map;
//import java.util.UUID;
//
//import static org.mockito.Mockito.mock;
//import static org.mockito.Mockito.verify;
//import static org.mockito.Mockito.when;
//
//class TestReportServiceImplTest {
//
//    private static final Integer DICT_STATE_NORMAL = 1;
//    private static final Integer DICT_STATE_DELETED = 0;
//
//    @Test
//    void constantsShouldExposeGenerateStates() {
//        Assertions.assertEquals(Integer.valueOf(0), TestReportConst.REPORT_GENERATE_STATE_PENDING);
//        Assertions.assertEquals(Integer.valueOf(1), TestReportConst.REPORT_GENERATE_STATE_GENERATING);
//        Assertions.assertEquals(Integer.valueOf(2), TestReportConst.REPORT_GENERATE_STATE_FINISHED);
//        Assertions.assertEquals(Integer.valueOf(3), TestReportConst.GROUP_REPORT_GENERATE_STATE_FAILED);
//    }
//
//    @Test
//    void pointPoShouldStoreParsedFields() {
//        TestReportPointPO point = new TestReportPointPO();
//        point.setSubstationName("220kV城南站");
//        point.setPointName("1号监测点");
//        point.setVoltageLevel("10kV");
//
//        Assertions.assertEquals("220kV城南站", point.getSubstationName());
//        Assertions.assertEquals("1号监测点", point.getPointName());
//        Assertions.assertEquals("10kV", point.getVoltageLevel());
//    }
//
//    @Test
//    void groupReportPoShouldStoreResultFields() {
//        TestReportGroupReportPO groupReport = new TestReportGroupReportPO();
//        groupReport.setGroupNo(1);
//        groupReport.setReportName("第1组检测报告");
//        groupReport.setGenerateState(TestReportConst.GROUP_REPORT_GENERATE_STATE_PENDING);
//
//        Assertions.assertEquals(Integer.valueOf(1), groupReport.getGroupNo());
//        Assertions.assertEquals("第1组检测报告", groupReport.getReportName());
//        Assertions.assertEquals(TestReportConst.GROUP_REPORT_GENERATE_STATE_PENDING, groupReport.getGenerateState());
//    }
//
//    @Test
//    void serviceShouldExposeGroupedApis() throws Exception {
//        Assertions.assertNotNull(TestReportServiceImpl.class.getMethod("listTestReports", TestReportParam.QueryParam.class));
//        Assertions.assertNotNull(TestReportServiceImpl.class.getMethod("validateLedger", String.class, MultipartFile[].class));
//        Assertions.assertNotNull(TestReportServiceImpl.class.getMethod("importLedger", String.class,
//                TestReportParam.LedgerImportParam.class));
//        Assertions.assertNotNull(TestReportServiceImpl.class.getMethod("listPoints", String.class));
//        Assertions.assertNotNull(TestReportServiceImpl.class.getMethod("listGroupReports", String.class));
//    }
//
//    @Test
//    void parserShouldReadNodeInfoSheetFromSampleXls() throws Exception {
//        TestReportPointExcelParser parser = new TestReportPointExcelParser();
//        try (InputStream inputStream = Files.newInputStream(
//                Paths.get("ai-report/test-report/src/恒谊_20260610110840_202606101108_202606110957.xls"))) {
//            TestReportPointExcelParser.ParsedPoint point = parser.parse(
//                    "恒谊_20260610110840_202606101108_202606110957.xls", inputStream);
//            Assertions.assertNotNull(point.getPointName());
//            Assertions.assertNotNull(point.getSubstationName());
//        }
//    }
//
//    @Test
//    void importLedgerShouldRejectGeneratingTask() {
//        TestReportPO report = new TestReportPO();
//        report.setId("report-001");
//        report.setStatus(TestReportConst.STATUS_NORMAL);
//        report.setReportGenerateState(TestReportConst.REPORT_GENERATE_STATE_GENERATING);
//        TestableTestReportServiceImpl service = new TestableTestReportServiceImpl(mock(IDictTypeService.class),
//                mock(IDictDataService.class), report);
//        MockMultipartFile file = new MockMultipartFile("files", "sample.xls", "application/vnd.ms-excel", new byte[]{1});
//
//        BusinessException exception = Assertions.assertThrows(BusinessException.class,
//                () -> service.validateLedger("report-001", new MultipartFile[]{file}));
//
//        Assertions.assertTrue(exception.getMessage().contains("未生成"));
//    }
//
//    @Test
//    void importLedgerShouldRejectMissingBatchId() {
//        TestReportServiceImpl service = createService(mock(IDictTypeService.class), mock(IDictDataService.class));
//        TestReportParam.LedgerImportParam param = new TestReportParam.LedgerImportParam();
//
//        BusinessException exception = Assertions.assertThrows(BusinessException.class,
//                () -> service.importLedger("report-001", param));
//
//        Assertions.assertNotNull(exception.getMessage());
//    }
//
//    @Test
//    void addTestReportShouldRejectMissingNo() {
//        TestReportServiceImpl service = createService(mock(IDictTypeService.class), mock(IDictDataService.class));
//        TestReportParam.AddParam param = new TestReportParam.AddParam();
//        param.setClientUnitId("client-1");
//        param.setReportModelId("model-1");
//        param.setCreateUnit("unit-1");
//        param.setContractNumber("HT-001");
//        param.setStandard("[\"std-1\"]");
//        param.setData("{}");
//
//        BusinessException exception = Assertions.assertThrows(BusinessException.class,
//                () -> service.addTestReport(param));
//
//        Assertions.assertNotNull(exception.getMessage());
//    }
//
//    @Test
//    void submitAuditShouldRejectMissingId() {
//        TestReportServiceImpl service = createService(mock(IDictTypeService.class), mock(IDictDataService.class));
//        TestReportParam.SubmitAuditParam param = new TestReportParam.SubmitAuditParam();
//        param.setCheckResult("approved");
//
//        BusinessException exception = Assertions.assertThrows(BusinessException.class,
//                () -> service.submitAudit(param));
//
//        Assertions.assertNotNull(exception.getMessage());
//    }
//
//    @Test
//    void addTestReportShouldRejectInvalidStandardJsonArray() {
//        TestReportServiceImpl service = createService(mock(IDictTypeService.class), mock(IDictDataService.class));
//        TestReportParam.AddParam param = new TestReportParam.AddParam();
//        param.setNo("PT-001");
//        param.setClientUnitId("client-1");
//        param.setReportModelId("model-1");
//        param.setCreateUnit("company-1");
//        param.setContractNumber("HT-001");
//        param.setStandard("not-json-array");
//        param.setData("{}");
//
//        BusinessException exception = Assertions.assertThrows(BusinessException.class,
//                () -> service.addTestReport(param));
//
//        Assertions.assertTrue(exception.getMessage().contains("测试依据"));
//    }
//
//    @Test
//    void addTestReportShouldPreferFrontendIdWhenProvided() {
//        TestableAddTestReportServiceImpl service = createAddService();
//        TestReportParam.AddParam param = buildValidNormalizeParam();
//        param.setId("report-frontend-001");
//
//        boolean result = service.addTestReport(param);
//
//        Assertions.assertTrue(result);
//        Assertions.assertNotNull(service.savedReport);
//        Assertions.assertEquals("report-frontend-001", service.savedReport.getId());
//    }
//
//    @Test
//    void addTestReportShouldGenerateUuidWhenFrontendIdMissing() {
//        TestableAddTestReportServiceImpl service = createAddService();
//        TestReportParam.AddParam param = buildValidNormalizeParam();
//
//        boolean result = service.addTestReport(param);
//
//        Assertions.assertTrue(result);
//        Assertions.assertNotNull(service.savedReport);
//        Assertions.assertNotNull(service.savedReport.getId());
//        Assertions.assertDoesNotThrow(() -> UUID.fromString(service.savedReport.getId()));
//    }
//
//    @Test
//    void addTestReportShouldRejectInvalidDataJson() {
//        TestReportServiceImpl service = createService(mock(IDictTypeService.class), mock(IDictDataService.class));
//        TestReportParam.AddParam param = buildValidNormalizeParam();
//        param.setData("not-json");
//
//        BusinessException exception = Assertions.assertThrows(BusinessException.class,
//                () -> invokeNormalizeParam(service, param));
//
//        Assertions.assertTrue(exception.getMessage().contains("受资数据"));
//    }
//
//    @Test
//    void addTestReportShouldRejectScalarDataJson() {
//        TestReportServiceImpl service = createService(mock(IDictTypeService.class), mock(IDictDataService.class));
//        TestReportParam.AddParam param = buildValidNormalizeParam();
//        param.setData("\"plain-text\"");
//
//        BusinessException exception = Assertions.assertThrows(BusinessException.class,
//                () -> invokeNormalizeParam(service, param));
//
//        Assertions.assertTrue(exception.getMessage().contains("受资数据"));
//    }
//
//    @Test
//    void normalizeParamShouldAcceptJsonObjectAndJsonArrayData() {
//        TestReportServiceImpl service = createService(mock(IDictTypeService.class), mock(IDictDataService.class));
//        TestReportParam.AddParam objectParam = buildValidNormalizeParam();
//        objectParam.setData("{\"fileName\":\"report.json\"}");
//        TestReportParam.AddParam arrayParam = buildValidNormalizeParam();
//        arrayParam.setData("[{\"fileName\":\"report-a.json\"}]");
//
//        Assertions.assertDoesNotThrow(() -> invokeNormalizeParam(service, objectParam));
//        Assertions.assertDoesNotThrow(() -> invokeNormalizeParam(service, arrayParam));
//    }
//
//    @Test
//    void addTestReportShouldRejectDeletedStandardDictData() {
//        IDictTypeService dictTypeService = mock(IDictTypeService.class);
//        IDictDataService dictDataService = mock(IDictDataService.class);
//        TestReportServiceImpl service = createService(dictTypeService, dictDataService);
//        mockNormalDictType(dictTypeService, DictConst.TEST_REPORT_COMPANY_DICT_CODE, "type-company");
//        mockNormalDictType(dictTypeService, DictConst.TEST_REPORT_STANDARD_DICT_CODE, "type-standard");
//        when(dictDataService.listDictDataByTypeId("type-company")).thenReturn(Collections.singletonList(
//                buildDictData("company-1", "company-A", DICT_STATE_NORMAL)));
//        when(dictDataService.listDictDataByTypeId("type-standard")).thenReturn(Collections.singletonList(
//                buildDictData("std-1", "standard-A", DICT_STATE_DELETED)));
//        TestReportParam.AddParam param = new TestReportParam.AddParam();
//        param.setNo("PT-001");
//        param.setClientUnitId("client-1");
//        param.setReportModelId("model-1");
//        param.setCreateUnit("company-1");
//        param.setContractNumber("HT-001");
//        param.setStandard("[\"std-1\"]");
//        param.setData("{}");
//
//        BusinessException exception = Assertions.assertThrows(BusinessException.class,
//                () -> service.addTestReport(param));
//
//        Assertions.assertTrue(exception.getMessage().contains("测试依据"));
//    }
//
//    @Test
//    void fillDisplayUserNamesShouldPreferUserNameFallbackToUserIdAndDash() {
//        TestReportServiceImpl service = createService(mock(IDictTypeService.class), mock(IDictDataService.class));
//        TestReportVO first = new TestReportVO();
//        first.setCreateBy("creator-001");
//        first.setUpdateBy("updater-001");
//        first.setCreateByName("creator-A");
//        first.setUpdateByName("updater-A");
//        TestReportVO second = new TestReportVO();
//        second.setCreateBy("creator-002");
//        second.setUpdateBy(null);
//
//        Map<String, String> userNameMap = new HashMap<String, String>();
//        userNameMap.put("creator-001", "creator-A");
//        userNameMap.put("updater-001", "updater-A");
//
//        service.fillDisplayUserNames(first, userNameMap);
//        service.fillDisplayUserNames(second, userNameMap);
//
//        Assertions.assertEquals("creator-A", first.getCreateBy());
//        Assertions.assertEquals("updater-A", first.getUpdateBy());
//        Assertions.assertEquals("creator-002", second.getCreateBy());
//        Assertions.assertEquals("-", second.getUpdateBy());
//    }
//
//    @Test
//    void fillDisplayFieldsShouldResolveDictNamesAndFallbackToRawValue() {
//        IDictTypeService dictTypeService = mock(IDictTypeService.class);
//        IDictDataService dictDataService = mock(IDictDataService.class);
//        TestReportServiceImpl service = createService(dictTypeService, dictDataService);
//        mockNormalDictType(dictTypeService, DictConst.TEST_REPORT_COMPANY_DICT_CODE, "type-company");
//        mockNormalDictType(dictTypeService, DictConst.TEST_REPORT_STANDARD_DICT_CODE, "type-standard");
//        when(dictDataService.listDictDataByTypeId("type-company")).thenReturn(Collections.singletonList(
//                buildDictData("company-1", "Nanjing Zhiyou", DICT_STATE_NORMAL)));
//        when(dictDataService.listDictDataByTypeId("type-standard")).thenReturn(Arrays.asList(
//                buildDictData("std-1", "GB 50150-2016", DICT_STATE_NORMAL),
//                buildDictData("std-2", "DL/T 596-2021", DICT_STATE_NORMAL)));
//        TestReportVO first = new TestReportVO();
//        first.setCreateUnit("company-1");
//        first.setStandard("[\"std-1\",\"std-2\"]");
//        TestReportVO second = new TestReportVO();
//        second.setCreateUnit("company-unknown");
//        second.setStandard("[\"std-unknown\"]");
//
//        service.fillDisplayFields(Arrays.asList(first, second));
//
//        Assertions.assertEquals("Nanjing Zhiyou", first.getCreateUnit());
//        Assertions.assertEquals("GB 50150-2016, DL/T 596-2021", first.getStandard());
//        Assertions.assertEquals("company-unknown", second.getCreateUnit());
//        Assertions.assertEquals("std-unknown", second.getStandard());
//    }
//
//    @Test
//    void fillDisplayFieldsShouldIgnoreDeletedDictData() {
//        IDictTypeService dictTypeService = mock(IDictTypeService.class);
//        IDictDataService dictDataService = mock(IDictDataService.class);
//        TestReportServiceImpl service = createService(dictTypeService, dictDataService);
//        mockNormalDictType(dictTypeService, DictConst.TEST_REPORT_COMPANY_DICT_CODE, "type-company");
//        mockNormalDictType(dictTypeService, DictConst.TEST_REPORT_STANDARD_DICT_CODE, "type-standard");
//        when(dictDataService.listDictDataByTypeId("type-company")).thenReturn(Collections.singletonList(
//                buildDictData("company-1", "company-A", DICT_STATE_DELETED)));
//        when(dictDataService.listDictDataByTypeId("type-standard")).thenReturn(Collections.singletonList(
//                buildDictData("std-1", "standard-A", DICT_STATE_DELETED)));
//        TestReportVO report = new TestReportVO();
//        report.setCreateUnit("company-1");
//        report.setStandard("[\"std-1\"]");
//
//        service.fillDisplayFields(Collections.singletonList(report));
//
//        Assertions.assertEquals("company-1", report.getCreateUnit());
//        Assertions.assertEquals("std-1", report.getStandard());
//    }
//
//    @Test
//    void submitAuditShouldMoveEditingStateToAuditingAndClearAuditFields() {
//        TestReportPO report = new TestReportPO();
//        report.setId("report-001");
//        report.setState(TestReportConst.STATE_EDITING);
//        report.setStatus(TestReportConst.STATUS_NORMAL);
//        report.setCheckId("checker-001");
//        report.setCheckTime(java.time.LocalDate.of(2026, 6, 26));
//        report.setCheckResult("done");
//        TestableTestReportServiceImpl service = new TestableTestReportServiceImpl(mock(IDictTypeService.class),
//                mock(IDictDataService.class), report);
//        TestReportParam.SubmitAuditParam param = new TestReportParam.SubmitAuditParam();
//        param.setId("report-001");
//
//        boolean result = service.submitAudit(param);
//
//        Assertions.assertTrue(result);
//        Assertions.assertEquals(TestReportConst.STATE_AUDITING, report.getState());
//        Assertions.assertNull(report.getCheckId());
//        Assertions.assertNull(report.getCheckTime());
//        Assertions.assertNull(report.getCheckResult());
//        Assertions.assertSame(report, service.updatedReport);
//    }
//
//    private TestReportServiceImpl createService(IDictTypeService dictTypeService, IDictDataService dictDataService) {
//        return new TestReportServiceImpl(
//                mock(ReportModelService.class),
//                mock(ReportModelFileStorageService.class),
//                mock(FilePreviewService.class),
//                dictTypeService,
//                dictDataService,
//                mock(TestReportPointMapper.class),
//                mock(TestReportGroupReportMapper.class),
//                mock(TestReportPointExcelParser.class),
//                mock(TestReportStorageService.class),
//                mock(TestReportLedgerImportService.class),
//                mock(TestReportLedgerTemplateService.class));
//    }
//
//    private TestableAddTestReportServiceImpl createAddService() {
//        IDictTypeService dictTypeService = mock(IDictTypeService.class);
//        IDictDataService dictDataService = mock(IDictDataService.class);
//        TestReportMapper testReportMapper = mock(TestReportMapper.class);
//        mockNormalDictType(dictTypeService, DictConst.TEST_REPORT_COMPANY_DICT_CODE, "type-company");
//        mockNormalDictType(dictTypeService, DictConst.TEST_REPORT_STANDARD_DICT_CODE, "type-standard");
//        when(dictDataService.listDictDataByTypeId("type-company")).thenReturn(Collections.singletonList(
//                buildDictData("company-1", "company-A", DICT_STATE_NORMAL)));
//        when(dictDataService.listDictDataByTypeId("type-standard")).thenReturn(Collections.singletonList(
//                buildDictData("std-1", "standard-A", DICT_STATE_NORMAL)));
//        when(testReportMapper.countNormalClientUnit("client-1")).thenReturn(1);
//        when(testReportMapper.countNormalReportModel("model-1")).thenReturn(1);
//        return new TestableAddTestReportServiceImpl(dictTypeService, dictDataService, testReportMapper);
//    }
//
//    private TestReportParam.AddParam buildValidNormalizeParam() {
//        TestReportParam.AddParam param = new TestReportParam.AddParam();
//        param.setNo("PT-001");
//        param.setClientUnitId("client-1");
//        param.setReportModelId("model-1");
//        param.setCreateUnit("company-1");
//        param.setContractNumber("HT-001");
//        param.setStandard("[\"std-1\"]");
//        param.setData("{}");
//        return param;
//    }
//
//    private Object invokeNormalizeParam(TestReportServiceImpl service, TestReportParam.AddParam param) {
//        try {
//            Method method = TestReportServiceImpl.class.getDeclaredMethod("normalizeParam", TestReportParam.AddParam.class);
//            method.setAccessible(true);
//            return method.invoke(service, param);
//        } catch (java.lang.reflect.InvocationTargetException exception) {
//            Throwable targetException = exception.getTargetException();
//            if (targetException instanceof RuntimeException) {
//                throw (RuntimeException) targetException;
//            }
//            throw new RuntimeException(targetException);
//        } catch (Exception exception) {
//            throw new RuntimeException(exception);
//        }
//    }
//
//    private static class TestableTestReportServiceImpl extends TestReportServiceImpl {
//        private final TestReportPO report;
//        private TestReportPO updatedReport;
//
//        private TestableTestReportServiceImpl(IDictTypeService dictTypeService, IDictDataService dictDataService,
//                                              TestReportPO report) {
//            super(mock(ReportModelService.class), mock(ReportModelFileStorageService.class),
//                    mock(FilePreviewService.class), dictTypeService, dictDataService,
//                    mock(TestReportPointMapper.class), mock(TestReportGroupReportMapper.class),
//                    mock(TestReportPointExcelParser.class), mock(TestReportStorageService.class),
//                    mock(TestReportLedgerImportService.class), mock(TestReportLedgerTemplateService.class));
//            this.report = report;
//        }
//
//        @Override
//        public TestReportPO requireNormal(String id) {
//            return report;
//        }
//
//        @Override
//        public boolean updateById(TestReportPO entity) {
//            this.updatedReport = entity;
//            return true;
//        }
//    }
//
//    private static class TestableAddTestReportServiceImpl extends TestReportServiceImpl {
//        private TestReportPO savedReport;
//
//        private TestableAddTestReportServiceImpl(IDictTypeService dictTypeService, IDictDataService dictDataService,
//                                                 TestReportMapper testReportMapper) {
//            super(mock(ReportModelService.class), mock(ReportModelFileStorageService.class),
//                    mock(FilePreviewService.class), dictTypeService, dictDataService,
//                    mock(TestReportPointMapper.class), mock(TestReportGroupReportMapper.class),
//                    mock(TestReportPointExcelParser.class), mock(TestReportStorageService.class),
//                    mock(TestReportLedgerImportService.class), mock(TestReportLedgerTemplateService.class));
//            this.baseMapper = testReportMapper;
//        }
//
//        @Override
//        public long count(com.baomidou.mybatisplus.core.conditions.Wrapper<TestReportPO> queryWrapper) {
//            return 0;
//        }
//
//        @Override
//        public boolean save(TestReportPO entity) {
//            this.savedReport = entity;
//            return true;
//        }
//    }
//
//    private void mockNormalDictType(IDictTypeService dictTypeService, String code, String typeId) {
//        when(dictTypeService.getByCode(code)).thenReturn(buildDictType(typeId, code));
//    }
//
//    private DictType buildDictType(String id, String code) {
//        DictType dictType = new DictType();
//        dictType.setId(id);
//        dictType.setCode(code);
//        dictType.setState(DICT_STATE_NORMAL);
//        return dictType;
//    }
//
//    private DictData buildDictData(String id, String name, Integer state) {
//        DictData dictData = new DictData();
//        dictData.setId(id);
//        dictData.setName(name);
//        dictData.setState(state);
//        return dictData;
//    }
//}
