package com.chinaweal.aiccs.schedule;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chinaweal.aiccs.aicbizqy.entity.datamove.EBaseInfo;
import com.chinaweal.aiccs.aicbizqy.mapper.datamove.EBaseInfoDataMoveMapper;
import com.chinaweal.aiccs.crgs.entity.EMoveIn;
import com.chinaweal.aiccs.crgs.mapper.EMoveInMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import java.io.File;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 迁入省局数据定时任务测试类
 *
 * @author Claude
 * @since 2025-11-10
 */
@SpringBootTest
@ActiveProfiles("dev")
@Slf4j
public class MoveInDataScheduleTest {

    @Autowired
    private MoveInDataSchedule moveInDataSchedule;

    @Autowired
    private EMoveInMapper eMoveInMapper;

    @Autowired
    private EBaseInfoDataMoveMapper eBaseInfoMapper;

    /**
     * 测试查询迁入企业功能
     */
    @Test
    public void testQueryMoveInEnterprises() {
        try {
            log.info("开始测试查询迁入企业功能...");

            List<EMoveIn> moveInList = eMoveInMapper.selectList(new QueryWrapper<>());
            log.info("查询到{}条迁入企业记录", moveInList.size());

            for (EMoveIn moveIn : moveInList) {
                log.info("企业信息：PRIPID={}, MIN_ID={}, S_EXT_DATATIME={}",
                    moveIn.getPripid(), moveIn.getMinId(), moveIn.getSExtDatatime());
            }

            log.info("测试查询迁入企业功能完成");
        } catch (Exception e) {
            log.error("测试查询迁入企业功能失败", e);
        }
    }

    /**
     * 测试查询企业基本信息功能
     */
    @Test
    public void testQueryEnterpriseBaseInfo() {
        try {
            log.info("开始测试查询企业基本信息功能...");

            // 先查询一个企业
            List<EMoveIn> moveInList = eMoveInMapper.selectList(new QueryWrapper<>());
            if (moveInList.isEmpty()) {
                log.warn("没有找到迁入企业记录，无法测试");
                return;
            }

            String pripid = moveInList.get(0).getPripid();
            log.info("测试企业PRIPID：{}", pripid);

            QueryWrapper<EBaseInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("PRIPID", pripid);
            List<EBaseInfo> eBaseInfoList = eBaseInfoMapper.selectList(queryWrapper);

            if (!eBaseInfoList.isEmpty()) {
                EBaseInfo eBaseInfo = eBaseInfoList.get(0);
                log.info("企业基本信息：UNISCID={}, ENTNAME={}, REGNO={}",
                    eBaseInfo.getUniscid(), eBaseInfo.getEntname(), eBaseInfo.getRegno());
            } else {
                log.warn("未找到企业基本信息，PRIPID={}", pripid);
            }

            log.info("测试查询企业基本信息功能完成");
        } catch (Exception e) {
            log.error("测试查询企业基本信息功能失败", e);
        }
    }

    /**
     * 测试创建测试数据
     */
    @Test
    public void testCreateTestData() {
        try {
            log.info("开始创建测试数据...");

            // 创建测试用的EMoveIn记录
            EMoveIn testMoveIn = new EMoveIn();
            testMoveIn.setMinId(UUID.randomUUID().toString().replace("-", ""));
            testMoveIn.setPripid("TESTPRIPID123456");
            testMoveIn.setMinletnum("TESTMINLETNUM");
            testMoveIn.setMoutarea("TESTMOUTAREA");
            testMoveIn.setMinrea("TESTMINREA");
            testMoveIn.setMoutareregorg("TESTMOUTAREREGORG");
            testMoveIn.setMindate(new Timestamp(System.currentTimeMillis()));
            testMoveIn.setSExtDatatime(new Timestamp(System.currentTimeMillis()));
            testMoveIn.setMoveType("TESTMOVETYPE");
            testMoveIn.setMoveTypeDetail("TESTMOVETYPEDETAIL");

            // 这里注意：实际插入需要根据表结构调整
            // eMoveInMapper.insert(testMoveIn);

            log.info("创建测试数据完成：MIN_ID={}, PRIPID={}", testMoveIn.getMinId(), testMoveIn.getPripid());
        } catch (Exception e) {
            log.error("创建测试数据失败", e);
        }
    }

    /**
     * 测试ZIP文件解析功能
     */
    @Test
    public void testZipFileParsing() {
        try {
            log.info("开始测试ZIP文件解析功能...");

            // 创建测试用的XML文件
            String testXmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<rows>\n" +
                "  <row>\n" +
                "    <PRIPID>TESTPRIPID123456</PRIPID>\n" +
                "    <UNISCID>91110000000000000X</UNISCID>\n" +
                "    <ENTNAME>测试企业</ENTNAME>\n" +
                "    <REGNO>110000000000000</REGNO>\n" +
                "  </row>\n" +
                "</rows>";

            // 创建临时目录
            String tempDir = "D:\\data\\test\\temp";
            FileUtil.mkdir(new File(tempDir));

            // 写入XML文件
            File xmlFile = new File(tempDir, "E_BASEINFO.xml");
            FileUtil.writeString(testXmlContent, xmlFile, "UTF-8");

            // 创建ZIP文件
            String zipFileName = "91110000000000000X-QYXYXX-" + DateUtil.format(new Date(), "yyyyMMdd") + ".zip";
            File zipFile = new File(tempDir, zipFileName);
            ZipUtil.zip(zipFile, false, xmlFile);

            log.info("创建测试ZIP文件：{}", zipFile.getAbsolutePath());

            // 测试解析（需要实际调用MoveInDataSchedule的方法）
            // Map<String, List<?>> parsedDataMap = moveInDataSchedule.parseZipFile(zipFile, "91110000000000000X");
            // log.info("解析结果：{}", parsedDataMap);

            log.info("测试ZIP文件解析功能完成");
        } catch (Exception e) {
            log.error("测试ZIP文件解析功能失败", e);
        }
    }

    /**
     * 测试执行完整迁入流程
     */
    @Test
    public void testExecuteMoveInData() {
        try {
            log.info("开始测试执行完整迁入流程...");

            // 执行迁入定时任务
            moveInDataSchedule.executeMoveInData();

            log.info("测试执行完整迁入流程完成");
        } catch (Exception e) {
            log.error("测试执行完整迁入流程失败", e);
        }
    }

    /**
     * 测试构建对账参数功能
     */
    @Test
    public void testBuildReconciliationParams() {
        try {
            log.info("开始测试构建对账参数功能...");

            // 创建测试数据统计
            java.util.Map<String, Integer> recordCountMap = new java.util.HashMap<>();
            recordCountMap.put("E_BASEINFO", 1);
            recordCountMap.put("E_ALTER_RECODER", 2);
            recordCountMap.put("E_IM_PERMIT", 3);

            String uniscid = "91110000000000000X";
            String entname = "测试企业";

            // 这里需要通过反射或其他方式调用private方法
            // String result = moveInDataSchedule.buildReconciliationParams(uniscid, entname, recordCountMap);
            // log.info("对账参数：{}", result);

            log.info("测试构建对账参数功能完成");
        } catch (Exception e) {
            log.error("测试构建对账参数功能失败", e);
        }
    }

    /**
     * 测试调用对账接口功能
     */
    @Test
    public void testCallRecordInfoApi() {
        try {
            log.info("开始测试调用对账接口功能...");

            String uniscid = "91110000000000000X";
            String entname = "测试企业";

            java.util.Map<String, Integer> recordCountMap = new java.util.HashMap<>();
            recordCountMap.put("E_BASEINFO", 1);
            recordCountMap.put("E_ALTER_RECODER", 2);
            recordCountMap.put("E_IM_PERMIT", 3);

            // 这里需要通过反射或其他方式调用private方法
            // moveInDataSchedule.callRecordInfoApi(uniscid, entname, recordCountMap);

            log.info("测试调用对账接口功能完成");
        } catch (Exception e) {
            log.error("测试调用对账接口功能失败", e);
        }
    }

    /**
     * 测试获取迁移数据路径功能
     */
    @Test
    public void testGetMigrationDataPath() {
        try {
            log.info("开始测试获取迁移数据路径功能...");

            String testUniscid = "9151XX22337785640X";
            String testPripid = "TESTPRIPID123456";
            String testMinId = "TESTMINID123456";

            // 这里需要通过反射或其他方式调用private方法
            // 由于getMigrationDataPath是private方法，我们可以通过反射调用
            java.lang.reflect.Method method = MoveInDataSchedule.class.getDeclaredMethod("getMigrationDataPath", String.class, String.class, String.class);
            method.setAccessible(true);

            // String uploadFilePath = (String) method.invoke(moveInDataSchedule, testUniscid, testPripid, testMinId);
            // log.info("获取到迁移数据路径：{}", uploadFilePath);

            log.info("测试获取迁移数据路径功能完成（方法调用被注释，实际测试时取消注释）");
        } catch (Exception e) {
            log.error("测试获取迁移数据路径功能失败", e);
        }
    }

    /**
     * 测试下载ZIP文件功能（包含获取迁移数据路径和POST请求）
     */
    @Test
    public void testDownloadZipFileWithMigrationPath() {
        try {
            log.info("开始测试下载ZIP文件功能（包含获取迁移数据路径和POST请求）...");

            String testUniscid = "9151XX22337785640X";
            String testPripid = "TESTPRIPID123456";
            String testMinId = "TESTMINID123456";
            String currentDate = DateUtil.format(new Date(), "yyyyMMdd");
            String zipFileName = testUniscid + "-QYXYXX-" + currentDate + ".zip";

            // 调用下载ZIP文件方法（会先调用获取迁移数据路径，然后使用POST请求下载）
            // File zipFile = moveInDataSchedule.downloadZipFile(testUniscid, zipFileName, currentDate, testPripid, testMinId);

            // if (zipFile != null) {
            //     log.info("下载ZIP文件成功：{}", zipFile.getAbsolutePath());
            // } else {
            //     log.warn("下载ZIP文件失败");
            // }

            log.info("测试下载ZIP文件功能完成（方法调用被注释，实际测试时取消注释）");
        } catch (Exception e) {
            log.error("测试下载ZIP文件功能失败", e);
        }
    }

    /**
     * 测试POST请求下载接口参数构建
     */
    @Test
    public void testPostRequestParamsBuilding() {
        try {
            log.info("开始测试POST请求下载接口参数构建...");

            String testAppform = "markets";
            String testFilePath = "/guangdong/913700005887679143-QYDJXX-20250804.zip";

            // 模拟构建POST请求参数的过程
            java.util.Map<String, Object> downloadParams = new java.util.HashMap<>();
            downloadParams.put("appform", testAppform);
            downloadParams.put("filePath", testFilePath);

            log.info("构建的POST请求参数：{}", downloadParams);

            // 验证参数格式是否符合要求
            if (downloadParams.containsKey("appform") && downloadParams.containsKey("filePath")) {
                log.info("POST请求参数格式验证通过");
            } else {
                log.error("POST请求参数格式验证失败");
            }

            log.info("测试POST请求下载接口参数构建完成");
        } catch (Exception e) {
            log.error("测试POST请求下载接口参数构建失败", e);
        }
    }

    /**
     * 测试获取迁移数据路径记录功能
     */
    @Test
    public void testMigrationDataPathRecording() {
        try {
            log.info("开始测试获取迁移数据路径记录功能...");

            String testUniscid = "9151XX22337785640X";
            String testPripid = "TESTPRIPID123456";
            String testMinId = "TESTMINID123456";

            // 模拟各种场景的记录
            String[] testScenarios = {
                "获取迁移数据路径成功：路径=/test/path/file.zip, 上传时间=2024-11-27 15:26:00",
                "获取迁移数据路径失败：返回的data数组为空",
                "获取迁移数据路径失败：registerInfoFiles数组为空",
                "获取迁移数据路径失败：接口返回空响应",
                "获取迁移数据路径失败：异常=网络连接超时"
            };

            for (String scenario : testScenarios) {
                log.info("测试场景：{}", scenario);
                // 这里可以验证recordFileUploadResult方法会被正确调用
                // 由于方法是private的，实际测试时通过反射调用
            }

            log.info("测试获取迁移数据路径记录功能完成");
        } catch (Exception e) {
            log.error("测试获取迁移数据路径记录功能失败", e);
        }
    }

    /**
     * 测试下载对账接口功能
     */
    @Test
    public void testDownloadRecordInfoApi() {
        try {
            log.info("开始测试下载对账接口功能...");

            String testUniscid = "9151XX22337785640X";
            String testEntname = "南江玉 XX 酿造有限责任公司";
            String testMoveInProvince = "110000";
            String testMoveOutProvince = "100000";
            String testMoutareregorg = "440100";

            // 这里需要通过反射调用private方法
            java.lang.reflect.Method method = MoveInDataSchedule.class.getDeclaredMethod(
                "callDownloadRecordInfoApi", String.class, String.class, String.class, String.class, String.class);
            method.setAccessible(true);

            // JSONObject response = (JSONObject) method.invoke(
            //     moveInDataSchedule, testUniscid, testEntname, testMoveInProvince, testMoveOutProvince, testMoutareregorg);

            // if (response != null) {
            //     log.info("下载对账接口调用成功：{}", response);
            // } else {
            //     log.warn("下载对账接口调用失败");
            // }

            log.info("测试下载对账接口功能完成（方法调用被注释，实际测试时取消注释）");
        } catch (Exception e) {
            log.error("测试下载对账接口功能失败", e);
        }
    }

    /**
     * 测试JSON拼接和区分功能
     */
    @Test
    public void testJsonCombination() {
        try {
            log.info("开始测试JSON拼接和区分功能...");

            // 模拟下载对账接口返回的JSON
            String downloadRecordJson = "{\"resultCode\":\"2000\",\"resultMsg\":\"查询成功！\",\"data\":{\"recordId\":\"112345678321\",\"uniscid\":\"9151XX22337785640X\"}}";

            // 模拟上传对账参数
            String uploadRecordJson = "{\"uniscid\":\"9151XX22337785640X\",\"entname\":\"南江玉 XX 酿造有限责任公司\",\"recordCounts\":{\"E_BASEINFO\":1,\"E_ALTER_RECODER\":2}}";

            // 模拟拼接逻辑
            String combinedReconciliationPar = "DOWNLOAD_RECORD:" + downloadRecordJson +
                "|||UPLOAD_RECORD:" + uploadRecordJson;

            log.info("拼接后的对账参数：{}", combinedReconciliationPar);

            // 验证拼接格式
            if (combinedReconciliationPar.contains("DOWNLOAD_RECORD:") &&
                combinedReconciliationPar.contains("|||UPLOAD_RECORD:")) {
                log.info("JSON拼接格式验证通过");
            } else {
                log.error("JSON拼接格式验证失败");
            }

            // 模拟解析（验证可以正确分割）
            String[] parts = combinedReconciliationPar.split("\\|\\|\\|");
            if (parts.length == 2) {
                log.info("JSON分割验证通过，共{}部分", parts.length);
                log.info("第一部分：{}", parts[0]);
                log.info("第二部分：{}", parts[1]);
            } else {
                log.error("JSON分割验证失败，期望2部分，实际{}部分", parts.length);
            }

            log.info("测试JSON拼接和区分功能完成");
        } catch (Exception e) {
            log.error("测试JSON拼接和区分功能失败", e);
        }
    }

    /**
     * 测试insertXt方法记录功能
     */
    @Test
    public void testInsertXtRecording() {
        try {
            log.info("开始测试insertXt方法记录功能...");

            // 模拟企业数据
            String testPripid = "TESTPRIPID123456";
            String testUniscid = "9151XX22337785640X";
            String testZipPath = "D:\\data\\test\\file.zip";

            // 模拟各种场景的记录
            String[] testScenarios = {
                "第五阶段数据插入到系统成功",
                "第五阶段数据插入到系统失败"
            };

            for (String scenario : testScenarios) {
                log.info("测试场景：{}", scenario);
                // 这里可以验证recordFileUploadResult方法会被正确调用
                // 由于方法是private的，实际测试时通过反射调用
            }

            log.info("测试insertXt方法记录功能完成");
        } catch (Exception e) {
            log.error("测试insertXt方法记录功能失败", e);
        }
    }
}
