package com.chinaweal.aiccs.schedule;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.core.io.FileSystemResource;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * 第三方文件上传服务
 *
 * @author Claude
 * @since 2025-11-06
 */
@Service
@Slf4j
public class FileUploadService {

    @Value("${forest.variables.fileUpload.testUrl}")
    private String testUrl;

    @Value("${forest.variables.fileUpload.prodUrl}")
    private String prodUrl;

    @Value("${forest.variables.fileUpload.testRecordUrl}")
    private String testRecordUrl;

    @Value("${forest.variables.fileUpload.prodRecordUrl}")
    private String prodRecordUrl;

    @Value("${forest.variables.fileUpload.appform}")
    private String appform;

    @Value("${forest.variables.fileUpload.fileType}")
    private String fileType;

    @Value("${forest.variables.fileUpload.env}")
    private String env;

    @Value("${forest.variables.fileUpload.testRegisterInfoUrl}")
    private String testRegisterInfoUrl;

    @Value("${forest.variables.fileUpload.prodRegisterInfoUrl}")
    private String prodRegisterInfoUrl;



    private final RestTemplate restTemplate;

    public FileUploadService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    /**
     * 上传文件到第三方
     * @param file 要上传的文件
     * @param uniscid 企业统一社会信用代码（用于日志记录）
     * @return 上传结果
     */
    public FileUploadResult uploadFile(File file, String uniscid,String minareregorg) {
        try {
            // 根据环境选择上传地址
            String uploadUrl = "prod".equals(env) ? prodUrl : testUrl;

            log.info("开始上传文件到第三方：企业={}, 文件={}, 上传地址={}", uniscid, file.getName(), uploadUrl);

            // 创建MultiValueMap来存放表单数据
            MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
            formData.add("appform", appform);
            formData.add("fileType", fileType);

            if (!file.exists()) {
                log.error("文件不存在：{}", file.getAbsolutePath());
                return null;
            }
            if (file.length() == 0) {
                log.error("文件为空：{}", file.getAbsolutePath());
                return null;
            }

            // 输出文件大小（单位：字节，同时转换为KB/MB方便阅读）
            long fileSize = file.length();
            String sizeInfo;
            if (fileSize < 1024) {
                sizeInfo = fileSize + " 字节";
            } else if (fileSize < 1024 * 1024) {
                sizeInfo = String.format("%.2f KB", fileSize / 1024.0);
            } else {
                sizeInfo = String.format("%.2f MB", fileSize / (1024.0 * 1024));
            }
            log.info("文件校验通过，准备上传：{}，大小：{}", file.getAbsolutePath(), sizeInfo);
            String minOrg = "";           // 关键修正：添加文件字段，字段名必须为 "file"
            formData.add("file", new FileSystemResource(file));
            if (minareregorg != null && minareregorg.length() >= 2) {
                String moveInProvince = minareregorg.substring(0, 2) + "0000";
                minOrg = moveInProvince;
            }
            String pinyin = getPinyin(minOrg); // 获取拼音
            formData.add("province", pinyin);

            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);

            // 创建HttpEntity
            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(formData, headers);

            // 使用RestTemplate上传文件
            String response = restTemplate.postForObject(uploadUrl, requestEntity, String.class);

            log.info("第三方响应：企业={}, 响应内容={}", uniscid, response);

            // 解析JSON响应
            FileUploadResult uploadResult = parseResponse(response, uniscid, file.getName());

            return uploadResult;

        } catch (Exception e) {
            log.error("文件上传过程中发生异常：企业={}, 文件={}", uniscid, file.getName(), e);
            return null;
        }
    }

    /**
     * 调用对账接口，通知第三方数据记录信息
     * @param uniscid 企业统一社会信用代码
     * @param entname 企业名称
     * @param enterpriseRecordCountMap 各表数据统计Map
     * @return 对账接口返回结果，包含resultCode和resultMsg
     */
    public RecordInfoResult callRecordInfoApi(String uniscid, String entname, Map<String, Integer> enterpriseRecordCountMap,String minareregorg) {
        try {
            // 根据环境选择对账接口地址
            String recordUrl = "prod".equals(env) ? prodRecordUrl : testRecordUrl;

            log.info("开始调用对账接口：企业={}, 企业名={}, 对账地址={}", uniscid, entname, recordUrl);

            // 构建对账接口参数 - 对账接口使用JSON格式，不是multipart/form-data
            Map<String, Object> recordData = new HashMap<>();
            recordData.put("appform", appform);
            recordData.put("uniscid", uniscid);
            if (minareregorg != null && minareregorg.length() >= 2) {
                String moveInProvince = minareregorg.substring(0, 2) + "0000";
                recordData.put("moveInProvince", moveInProvince);
            } else {
                // 处理长度不足的情况
                recordData.put("moveInProvince", "000000"); // 或者其他默认值
            }
            recordData.put("moveOutProvince", "440000"); // 迁出省份固定值
            recordData.put("entname", entname);

            // 设置各表数量，如果表中没有数据则设置为0（使用接口文档中的字段名格式）
            recordData.put("eBaseinfo", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_BASEINFO", 0)));
            recordData.put("eAlterRecoder", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_ALTER_RECODER", 0)));
            recordData.put("ePubSpotcheck", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_PUB_SPOTCHECK", 0)));
            recordData.put("drRaninsres", String.valueOf(enterpriseRecordCountMap.getOrDefault("DR_RANINSRES", 0)));
            recordData.put("aoOpanomaly", String.valueOf(enterpriseRecordCountMap.getOrDefault("AO_OPANOMALY", 0)));
            recordData.put("aoOpaDetail", String.valueOf(enterpriseRecordCountMap.getOrDefault("AO_OPA_DETAIL", 0)));
            recordData.put("aoOpanomalyInv", String.valueOf(enterpriseRecordCountMap.getOrDefault("AO_OPANOMALY_INV", 0)));
            recordData.put("anBaseinfo", String.valueOf(enterpriseRecordCountMap.getOrDefault("AN_BASEINFO", 0)));
            recordData.put("anSubcapital", String.valueOf(enterpriseRecordCountMap.getOrDefault("AN_SUBCAPITAL", 0)));
            recordData.put("anForinvestment", String.valueOf(enterpriseRecordCountMap.getOrDefault("AN_FORINVESTMENT", 0)));
            recordData.put("anWebsiteinfo", String.valueOf(enterpriseRecordCountMap.getOrDefault("AN_WEBSITEINFO", 0)));
            recordData.put("anAlterstockinfo", String.valueOf(enterpriseRecordCountMap.getOrDefault("AN_ALTERSTOCKINFO", 0)));
            recordData.put("anForguaranteeinfo", String.valueOf(enterpriseRecordCountMap.getOrDefault("AN_FORGUARANTEEINFO", 0)));
            recordData.put("anUpdateinfo", String.valueOf(enterpriseRecordCountMap.getOrDefault("AN_UPDATEINFO", 0)));
            recordData.put("anSupBaseinfo", String.valueOf(enterpriseRecordCountMap.getOrDefault("AN_SUP_BASEINFO", 0)));
            recordData.put("anSocsecinfo", String.valueOf(enterpriseRecordCountMap.getOrDefault("AN_SOCSECINFO", 0)));
            recordData.put("eImPermit", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_IM_PERMIT", 0)));
            recordData.put("eImPrmtalt", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_IM_PRMTALT", 0)));
            recordData.put("eImInvestment", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_IM_INVESTMENT", 0)));
            recordData.put("eImInvprodetail", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_IM_INVPRODETAIL", 0)));
            recordData.put("eImInvactdetail", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_IM_INVACTDETAIL", 0)));
            recordData.put("eImInvupdate", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_IM_INVUPDATE", 0)));
            recordData.put("eImIppldg", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_IM_IPPLDG", 0)));
            recordData.put("eImIppldgalt", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_IM_IPPLDGALT", 0)));
            recordData.put("eImCase", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_IM_CASE", 0)));
            recordData.put("eImCasalt", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_IM_CASALT", 0)));
            recordData.put("eImInvsralt", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_IM_INVSRALT", 0)));
            recordData.put("eLiIlldishonesty", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_LI_ILLDISHONESTY", 0)));
            recordData.put("eLiIlldisdetail", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_LI_ILLDISDETAIL", 0)));
            recordData.put("casePubNbaseinfo", String.valueOf(enterpriseRecordCountMap.getOrDefault("CASE_PUB_NBASEINFO", 0)));
            recordData.put("casePubNdoc", String.valueOf(enterpriseRecordCountMap.getOrDefault("CASE_PUB_NDOC", 0)));
            recordData.put("casePubNalter", String.valueOf(enterpriseRecordCountMap.getOrDefault("CASE_PUB_NALTER", 0)));
            recordData.put("eOtNpermit", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_OT_NPERMIT", 0)));
            recordData.put("eOtNprmtalt", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_OT_NPRMTALT", 0)));
            recordData.put("eOtNcase", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_OT_NCASE", 0)));
            recordData.put("eOtNcasalt", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_OT_NCASALT", 0)));
            recordData.put("eOtSpotcheck", String.valueOf(enterpriseRecordCountMap.getOrDefault("E_OT_SPOTCHECK", 0)));
            recordData.put("caseCreInformation", String.valueOf(enterpriseRecordCountMap.getOrDefault("CASE_CRE_INFORMATION", 0)));

            // 设置请求头 - 对账接口使用JSON格式
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            // 创建HttpEntity - 使用Map转换为JSON
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(recordData, headers);

            // 使用RestTemplate调用对账接口
            String response = restTemplate.postForObject(recordUrl, requestEntity, String.class);

            log.info("对账接口响应：企业={}, 企业名={}, 响应内容={}", uniscid, entname, response);

            // 解析对账接口响应
            RecordInfoResult recordResult = parseRecordInfoResponse(response, uniscid, entname);

            // 根据接口文档，成功响应码为 "2000"
            if (recordResult != null && "2000".equals(recordResult.getResultCode())) {
                log.info("对账接口调用成功：企业={}, 企业名={}, 结果={}", uniscid, entname, recordResult.getData());
            } else {
                log.error("对账接口调用失败：企业={}, 企业名={}, 返回码：{}, 返回消息：{}",
                        uniscid, entname,
                        recordResult != null ? recordResult.getResultCode() : "null",
                        recordResult != null ? recordResult.getResultMsg() : "null");
            }

            return recordResult;

        } catch (Exception e) {
            log.error("调用对账接口时发生异常：企业={}, 企业名={}", uniscid, entname, e);
            // 返回失败结果
            RecordInfoResult errorResult = new RecordInfoResult();
            errorResult.setResultCode("500");
            errorResult.setResultMsg("系统异常：" + (e.getMessage() != null && e.getMessage().length() <= 2000 ? e.getMessage() : "调用对账接口时发生异常"));
            errorResult.setData(null);
            return errorResult;
        }
    }

    /**
     * 解析第三方返回的JSON响应
     * @param response 响应字符串
     * @param uniscid 企业统一社会信用代码
     * @param fileName 文件名
     * @return 解析后的结果
     */
    private FileUploadResult parseResponse(String response, String uniscid, String fileName) {
        try {
            // 简单的JSON解析，实际项目中可以使用Jackson或Gson
            // 这里假设返回的格式是：{"resultMsg": "成功","resultCode": "2000","data": "上传成功"}

            String resultMsg = extractJsonValue(response, "resultMsg");
            String resultCode = extractJsonValue(response, "resultCode");
            String data = extractJsonValue(response, "data");

            FileUploadResult result = new FileUploadResult();
            result.setResultMsg(resultMsg);
            result.setResultCode(resultCode);
            result.setData(data);

            return result;

        } catch (Exception e) {
            log.error("解析第三方响应失败：企业={}, 文件={}, 响应={}", uniscid, fileName, response, e);
            return null;
        }
    }

    /**
     * 从JSON字符串中提取指定字段的值
     * @param json JSON字符串
     * @param fieldName 字段名
     * @return 字段值
     */
    private String extractJsonValue(String json, String fieldName) {
        try {
            // 简单的字符串匹配，实际项目中建议使用JSON库
            String pattern = "\"" + fieldName + "\"\\s*:\\s*\"([^\"]+)\"";
            java.util.regex.Pattern r = java.util.regex.Pattern.compile(pattern);
            java.util.regex.Matcher m = r.matcher(json);
            if (m.find()) {
                return m.group(1);
            }
            return "";
        } catch (Exception e) {
            log.debug("提取JSON字段失败：字段={}, JSON={}", fieldName, json, e);
            return "";
        }
    }

    /**
     * 解析对账接口返回的JSON响应
     * @param response 响应字符串
     * @param uniscid 企业统一社会信用代码
     * @param fileName 文件名
     * @return 解析后的结果
     */
    private RecordInfoResult parseRecordInfoResponse(String response, String uniscid, String fileName) {
        try {
            // 简单的JSON解析，假设返回格式与文件上传相同
            String resultMsg = extractJsonValue(response, "resultMsg");
            String resultCode = extractJsonValue(response, "resultCode");
            String data = extractJsonValue(response, "data");

            RecordInfoResult result = new RecordInfoResult();
            result.setResultMsg(resultMsg);
            result.setResultCode(resultCode);
            result.setData(data);

            return result;

        } catch (Exception e) {
            log.error("解析对账接口响应失败：企业={}, 文件={}, 响应={}", uniscid, fileName, response, e);
            return null;
        }
    }

    /**
     * 调用企业上传路径接口（2.1阶段）
     * @param uniscid 企业统一社会信用代码
     * @param entname 企业名称
     * @param minareregorg 迁入省份
     * @param zipFileName ZIP文件名
     * @return 企业上传路径接口结果
     */
    public RegisterInfoResult callRegisterInfoApi(String uniscid, String entname, String minareregorg, String zipFileName) {
        try {
            // 根据环境选择企业上传路径接口地址
            String registerInfoUrl = "prod".equals(env) ? prodRegisterInfoUrl : testRegisterInfoUrl;

            log.info("开始调用企业上传路径接口：企业={}, 企业名={}, 接口地址={}", uniscid, entname, registerInfoUrl);

            String minOrg = "";

            // 构建企业上传路径接口参数
            Map<String, Object> registerData = new HashMap<>();
            registerData.put("appform", appform);
            registerData.put("uniscid", uniscid);
            registerData.put("entname", entname);
            if (minareregorg != null && minareregorg.length() >= 2) {
                String moveInProvince = minareregorg.substring(0, 2) + "0000";
                registerData.put("moveInProvince", moveInProvince);
                minOrg = moveInProvince;
            } else {
                // 处理长度不足的情况
                registerData.put("moveInProvince", "000000"); // 或者其他默认值
            }
//            registerData.put("moveInProvince", "440000");//要注销掉
            registerData.put("moveOutProvince", "440000"); // 迁出省份固定值

            // 构建registerInfoFilePath，格式：/xxxxxx/{UNISCID}-QYXYXX-{当前日期}.zip
            String currentDate = cn.hutool.core.date.DateUtil.format(new java.util.Date(), "yyyyMMdd");
            String pinyin = getPinyin(minOrg); // 获取拼音
            String registerInfoFilePath = "/" + pinyin + "/" + zipFileName;
//            String registerInfoFilePath = "/guangdong/" + zipFileName;//要注销掉

            registerData.put("registerInfoFilePath", registerInfoFilePath);
            registerData.put("registerInfoFileType", "1"); // 固定为1

            log.info("企业上传路径接口参数：企业={}, 文件路径={}", uniscid, registerInfoFilePath);

            // 设置请求头 - 企业上传路径接口使用JSON格式
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            // 创建HttpEntity - 使用Map转换为JSON
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(registerData, headers);

            // 使用RestTemplate调用企业上传路径接口
            String response = restTemplate.postForObject(registerInfoUrl, requestEntity, String.class);

            log.info("企业上传路径接口响应：企业={}, 企业名={}, 响应内容={}", uniscid, entname, response);

            // 解析企业上传路径接口响应
            RegisterInfoResult registerResult = parseRegisterInfoResponse(response, uniscid, entname);

            return registerResult;
        } catch (Exception e) {
            log.error("调用企业上传路径接口失败：企业={}, 企业名={}, 错误={}", uniscid, entname, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 解析企业上传路径接口响应
     */
    private RegisterInfoResult parseRegisterInfoResponse(String response, String uniscid, String entname) {
        try {
            if (cn.hutool.core.util.StrUtil.isNotBlank(response)) {
                // 使用hutool的JSONObject解析响应
                cn.hutool.json.JSONObject jsonObject = new cn.hutool.json.JSONObject(response);

                String resultMsg = jsonObject.getStr("resultMsg");
                String resultCode = jsonObject.getStr("resultCode");
                String data = jsonObject.getStr("data");

                log.info("企业上传路径接口响应解析：企业={}, 结果消息={}, 结果码={}, 数据={}",
                        uniscid, resultMsg, resultCode, data);

                RegisterInfoResult result = new RegisterInfoResult();
                result.setResultMsg(resultMsg);
                result.setResultCode(resultCode);
                result.setData(data);

                return result;
            } else {
                log.warn("企业上传路径接口响应为空：企业={}, 企业名={}", uniscid, entname);
                return null;
            }
        } catch (Exception e) {
            log.error("解析企业上传路径接口响应失败：企业={}, 企业名={}, 响应={}, 错误={}",
                    uniscid, entname, response, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 上传结果响应类
     */
    @Data
    public static class FileUploadResult {
        private String resultMsg;  // 返回消息，如"成功"
        private String resultCode; // 返回码，如"200"
        private String data;        // 返回数据，如"上传成功"
    }

    /**
     * 企业上传路径接口结果响应类
     */
    @Data
    public static class RegisterInfoResult {
        private String resultMsg;  // 返回消息，如"成功"
        private String resultCode; // 返回码，如"200"
        private String data;        // 返回数据，如"上传成功"
    }

    /**
     * 对账接口结果响应类
     */
    @Data
    public static class RecordInfoResult {
        private String resultMsg;  // 返回消息，如"成功"
        private String resultCode; // 返回码，如"2000"
        private String data;        // 返回数据，如"记录成功"
    }

    /**
     * 通过行政区划代码获取拼音
     */
    public  String getPinyin(String areaCode) {
        switch(areaCode) {
            case "110000": return "beijing";
            case "120000": return "tianjin";
            case "130000": return "hebei";
            case "140000": return "shanxi";
            case "150000": return "neimenggu";
            case "210000": return "liaoning";
            case "220000": return "jilin";
            case "230000": return "heilongjiang";
            case "310000": return "shanghai";
            case "320000": return "jiangsu";
            case "330000": return "zhejiang";
            case "340000": return "anhui";
            case "350000": return "fujian";
            case "360000": return "jiangxi";
            case "370000": return "shandong";
            case "410000": return "henan";
            case "420000": return "hubei";
            case "430000": return "hunan";
            case "440000": return "guangdong";
            case "450000": return "guangxi";
            case "460000": return "hainan";
            case "500000": return "chongqing";
            case "510000": return "sichuan";
            case "520000": return "guizhou";
            case "530000": return "yunnan";
            case "540000": return "xizang";
            case "610000": return "shaxi";
            case "620000": return "gansu";
            case "630000": return "qinghai";
            case "640000": return "ningxia";
            case "650000": return "xinjiang";
            case "710000": return "taiwan";
            case "810000": return "xianggang";
            case "820000": return "aomen";
            default: return null;
        }
    }
}
