package com.kingdee.eas.custom.esign.utils;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.BOSException;
import com.kingdee.bos.metadata.entity.EntityViewInfo;
import com.kingdee.bos.metadata.entity.FilterInfo;
import com.kingdee.bos.metadata.entity.FilterItemInfo;
import com.kingdee.eas.custom.entryconfig.DataConfigSelectFieldEntryCollection;
import com.kingdee.eas.custom.entryconfig.DataConfigSelectFieldEntryInfo;
import com.kingdee.bos.Context;
import com.kingdee.eas.custom.esign.*;
import com.kingdee.shr.base.syssetting.MSFServiceFacadeFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 电子签名字段映射工具类
 * 提供电子签名相关的字段处理、SQL获取、模板信息获取、JSON合并等工具方法
 */
public class ESignFieldMappingUtils {
//    /**
//     * 生成电子签名SQL字段字符串（已注释，备用逻辑）
//     * @param fields 字段映射集合
//     * @return 拼接后的SQL字段字符串（格式：数据库字段 as 映射键, ...）
//     */
//    public String getESignSqlField(FieldMappingEntryCollection fields){
//        String sqlField = "";
//        // 遍历字段映射集合
//        for (int i = 0; i < fields.size(); i++) {
//            // 获取当前字段映射信息
//            FieldMappingEntryInfo field = fields.get(i);
//            // 获取数据源字段信息
//            DataConfigSelectFieldEntryInfo dataSourceField = field.getDataSourceField();
//            // 获取映射键
//            String mappingKey = dataSourceField.getMappingKey();
//            // 获取数据库字段名
//            String databaseName = dataSourceField.getDatabaseName();
//            // 拼接SQL字段字符串（数据库字段 as 映射键）
//            sqlField+=databaseName+" as "+mappingKey;
//            // 判断是否为最后一个字段，最后一个字段后加换行，否则加逗号
//            if (i==fields.size()-1){
//                sqlField+="\n";
//            }else {
//                sqlField+=",";
//            }
//        }
//        // 返回拼接好的SQL字段字符串
//        return sqlField;
//    }

    /**
     * 从字段映射集合中提取数据源字段集合
     * @param fields 字段映射集合（包含字段映射关系）
     * @return 数据源字段集合（仅包含数据源字段信息）
     */
    public DataConfigSelectFieldEntryCollection getESignSqlField(FieldMappingEntryCollection fields){
        // 初始化数据源字段集合
        DataConfigSelectFieldEntryCollection dataConfigSelectFieldEntryCollection = new DataConfigSelectFieldEntryCollection();
        // 遍历字段映射集合
        for (int i = 0; i < fields.size(); i++) {
            // 获取当前字段映射信息
            FieldMappingEntryInfo field = fields.get(i);
            // 从字段映射中提取数据源字段
            DataConfigSelectFieldEntryInfo dataSourceField = field.getDataSourceField();
            // 将数据源字段添加到结果集合中
            if (dataSourceField!=null){
                dataConfigSelectFieldEntryCollection.add(dataSourceField);
            }
        }
        // 返回提取后的数据源字段集合
        return dataConfigSelectFieldEntryCollection;
    }

    /**
     * 根据数据配置编号获取电子签名相关SQL
     * @param dataConfigNumber 数据配置编号（用于标识特定的数据配置）
     * @param context 上下文对象（金蝶BOS框架上下文，包含环境信息）
     * @return 获取到的SQL字符串
     */
    public String getESignSql(String dataConfigNumber,Context context){
        // 初始化服务调用参数映射
        Map<String,Object> getSqlServiceMap = new HashMap<String,Object>();
        // 设置参数：数据配置编号
        getSqlServiceMap.put("number",dataConfigNumber);
        // 声明SQL结果变量
        Object sql = null;
        try {
            // 调用本地服务获取SQL，服务名为"getSqlService"，传入参数映射
            sql = MSFServiceFacadeFactory.getLocalInstance(context).processService("getSqlService", getSqlServiceMap);
        } catch (Exception e) {
            // 捕获异常并包装为运行时异常抛出
            throw new RuntimeException(e);
        }
        // 将SQL结果转为字符串返回
        return sql.toString();
    }

    /**
     * 根据ID获取电子签名模板信息
     * @param id 模板ID（用于唯一标识模板）
     * @param context 上下文对象（金蝶BOS框架上下文）
     * @return 电子签名模板信息（当前逻辑未实现，返回null）
     * @throws BOSException 金蝶BOS框架异常
     */
    public ESignTemplateInfo getTemplateInfo(String id,Context context) throws BOSException {
        // 创建实体视图信息（用于查询时指定视图条件）
        EntityViewInfo entityViewInfo = new EntityViewInfo();
        // 创建过滤信息对象（用于设置查询过滤条件）
        FilterInfo filterInfo = new FilterInfo();
        // 向过滤信息中添加过滤项：根据ID过滤（字段名为"id"，值为传入的id）
        filterInfo.getFilterItems().add(new FilterItemInfo("id",id));
        // 将过滤信息设置到实体视图中
        entityViewInfo.setFilter(filterInfo);
        // 调用电子签名模板工厂获取符合条件的模板集合（当前未使用返回的集合）
        ESignTemplateFactory.getLocalInstance(context).getESignTemplateCollection(entityViewInfo);

        // 方法暂未实现，返回null
        return null;
    }

    /**
     * 合并两个协议JSONObject对象的方法
     * @param baseJson 基础JSON对象（被合并的原始数据，优先级较低）
     * @param newJson 新JSON对象（待合并的数据，优先级较高，用于覆盖/补充原始数据）
     * @return 合并后的JSONObject
     * @throws IllegalArgumentException 当基础JSON为null时抛出
     */
    public  JSONObject mergeAgreements(JSONObject baseJson, JSONObject newJson) {
        // 基础JSON非空校验
        if (baseJson == null) {
            throw new IllegalArgumentException("基础JSON数据不能为null");
        }
        // 若新JSON为null，直接返回基础JSON
        if (newJson == null) {
            return baseJson;
        }

        // 遍历新JSON中的所有协议Key
        for (String agreementKey : newJson.keySet()) {
            try {
                // 从新JSON中获取当前Key对应的协议对象
                JSONObject newAgreement = newJson.getJSONObject(agreementKey);
                // 若当前协议不是JSONObject类型，跳过处理
                if (newAgreement == null) {
                    continue;
                }

                // 若基础JSON中已包含当前协议Key
                if (baseJson.containsKey(agreementKey)) {
                    // 从基础JSON中获取对应协议对象
                    JSONObject baseAgreement = baseJson.getJSONObject(agreementKey);
                    // 合并两个协议对象的内部字段
                    mergeSingleAgreement(baseAgreement, newAgreement);
                } else {
                    // 若基础JSON中不包含当前协议Key，直接添加新协议到基础JSON
                    baseJson.put(agreementKey, newAgreement);
                }
            } catch (JSONException e) {
                // 捕获JSON解析异常，打印错误信息后继续处理其他协议
                System.err.println("处理协议[" + agreementKey + "]时出错：" + e.getMessage());
                continue;
            }
        }
        // 返回合并后的基础JSON
        return baseJson;
    }

//    /**
//     * 合并两个单个协议对象的内部字段
//     * @param baseAgreement 基础协议对象（被合并的原始协议）
//     * @param newAgreement 新协议对象（待合并的协议，用于覆盖/补充原始协议）
//     */
//    private  void mergeSingleAgreement(JSONObject baseAgreement, JSONObject newAgreement) {
//        // 合并协议的基础属性：name（若新协议有name则覆盖）
//        if (newAgreement.getString("name") != null) {
//            baseAgreement.put("name", newAgreement.getString("name"));
//        }
//        // 合并协议的基础属性：id（若新协议有id则覆盖）
//        if (newAgreement.getString("id") != null) {
//            baseAgreement.put("id", newAgreement.getString("id"));
//        }
//        // 合并协议的基础属性：dataType（dataType则覆盖）
//        if (newAgreement.getString("dataType") != null) {
//            baseAgreement.put("dataType", newAgreement.getString("dataType"));
//        }
//        // 合并协议的基础属性：dataFormat（dataFormat则覆盖）
//        if (newAgreement.getString("dataFormat") != null) {
//            baseAgreement.put("dataFormat", newAgreement.getString("dataFormat"));
//        }
//
//        // 从新协议中获取fields字段（字段集合）
//        JSONObject newFields = newAgreement.getJSONObject("fields");
//        // 若新协议的fields为空或不存在，无需合并字段，直接返回
//        if (newFields == null || newFields.isEmpty()) {
//            return;
//        }
//
//        // 从基础协议中获取fields字段（字段集合）
//        JSONObject baseFields = baseAgreement.getJSONObject("fields");
//        // 若基础协议中没有fields字段，直接将新协议的fields设置到基础协议
//        if (baseFields == null) {
//            baseAgreement.put("fields", newFields);
//            return;
//        }
//
//        // 遍历新协议fields中的所有字段Key
//        for (String fieldKey : newFields.keySet()) {
//            // 从新协议fields中获取当前字段对象
//            JSONObject newField = newFields.getJSONObject(fieldKey);
//            if (newField != null) {
//                // 获取新字段的value值
//                Object value = newField.get("value");
//                // 若新字段value为null且基础fields中已存在该字段，则跳过（不覆盖现有有效数据）
//                if (value == null && baseFields.containsKey(fieldKey)) {
//                    JSONObject jsonObject1 = baseFields.getJSONObject(fieldKey);
//                    String dataType = jsonObject1.getString("dataType");
//                    String dataFormat = jsonObject1.getString("dataFormat");
//                    newField.put("dataType",dataType);
//                    newField.put("dataFormat",dataFormat);
//                    //continue;
//                }
////                else {
////                    String dataType = baseFields.getString("dataType");
////                    String dataFormat = baseFields.getString("dataFormat");0
////                    newField.put("dataType",dataType);
////                    newField.put("dataFormat",dataFormat);
////                }
//                // 将新字段添加/覆盖到基础fields中
//                baseFields.put(fieldKey, newField);
//            }
//        }
//    }
    /**
     * 合并单个协议对象内部的字段
     * @param baseAgreement 基础协议对象（被合并的原始协议）
     * @param newAgreement 新协议对象（要合并的协议，用于覆盖/补充原始协议）
     */
    private void mergeSingleAgreement(JSONObject baseAgreement, JSONObject newAgreement) {
        // 协议级字段：优先使用newAgreement的name、id、dataType、dataFormat
        if (newAgreement.getString("name") != null) {
            baseAgreement.put("name", newAgreement.getString("name"));
        }
        if (newAgreement.getString("id") != null) {
            baseAgreement.put("id", newAgreement.getString("id"));
        }
        if (newAgreement.getString("dataType") != null) {
            baseAgreement.put("dataType", newAgreement.getString("dataType"));
        }
        if (newAgreement.getString("dataFormat") != null) {
            baseAgreement.put("dataFormat", newAgreement.getString("dataFormat"));
        }

        // 从新协议中获取fields
        JSONObject newFields = newAgreement.getJSONObject("fields");
        if (newFields == null || newFields.isEmpty()) {
            return; // 新协议无fields，无需处理
        }

        // 从基础协议中获取fields（若不存在则直接使用新协议的fields）
        JSONObject baseFields = baseAgreement.getJSONObject("fields");
        if (baseFields == null) {
            baseAgreement.put("fields", newFields); // base无fields，直接用new的fields
            return;
        }

        // 基础协议存在fields，遍历新协议的fields进行合并
        for (String fieldKey : newFields.keySet()) {
            JSONObject newField = newFields.getJSONObject(fieldKey);
            if (newField == null) {
                continue;
            }

            // 若基础协议的fields中没有当前字段，直接添加新字段（以new为主）
            if (!baseFields.containsKey(fieldKey)) {
                baseFields.put(fieldKey, newField);
                continue;
            }

            // 基础协议存在当前字段，进行字段级合并
            JSONObject baseField = baseFields.getJSONObject(fieldKey);
            // 1. new的dataType和dataFormat优先覆盖base
            String newDataType = newField.getString("dataType");
            if (newDataType != null) {
                baseField.put("dataType", newDataType);
            }
            String newDataFormat = newField.getString("dataFormat");
            if (newDataFormat != null) {
                baseField.put("dataFormat", newDataFormat);
            }

            // 2. 其他字段（如name、value等）：以base为主，new有非空值时覆盖
            for (String key : newField.keySet()) {
                if ("dataType".equals(key) || "dataFormat".equals(key)) {
                    continue; // 已处理过的字段跳过
                }
                Object newValue = newField.get(key);
                if (newValue != null) {
                    baseField.put(key, newValue); // 仅new有值时覆盖base
                }
            }

            // 将合并后的字段放回baseFields
            baseFields.put(fieldKey, baseField);
        }
    }
    // ---------- 以下为重载方法，支持JSON字符串的合并 ----------

    /**
     * 合并两个JSON字符串（重载方法）
     * @param baseJsonStr 基础JSON字符串
     * @param newJsonStr 新JSON字符串
     * @return 合并后的JSONObject
     * @throws IllegalArgumentException 当JSON字符串解析失败时抛出
     */
    public  JSONObject mergeAgreements(String baseJsonStr, String newJsonStr) {
        try {
            // 将基础JSON字符串解析为JSONObject
            JSONObject baseJson = JSONObject.parseObject(baseJsonStr);
            // 将新JSON字符串解析为JSONObject
            JSONObject newJson = JSONObject.parseObject(newJsonStr);
            // 调用JSON对象合并方法
            return mergeAgreements(baseJson, newJson);
        } catch (JSONException e) {
            // 解析失败时抛出异常，包含错误信息
            throw new IllegalArgumentException("JSON字符串解析失败：" + e.getMessage(), e);
        }
    }

    // ---------- 以下为重载方法，支持从文件读取JSON并合并 ----------

    /**
     * 从文件读取JSON字符串并合并（重载方法）
     * @param baseFilePath 基础JSON文件路径
     * @param newFilePath 新JSON文件路径
     * @return 合并后的JSONObject
     * @throws IOException 当文件读取失败时抛出
     */
    public  JSONObject mergeAgreementsFromFile(String baseFilePath, String newFilePath) throws IOException {
        // 读取基础JSON文件内容为字符串
        String baseJsonStr = readFileToString(baseFilePath);
        // 读取新JSON文件内容为字符串
        String newJsonStr = readFileToString(newFilePath);
        // 调用JSON字符串合并方法
        return mergeAgreements(baseJsonStr, newJsonStr);
    }

    /**
     * 将文件内容读取为字符串（使用UTF-8编码）
     * @param filePath 文件路径
     * @return 文件内容字符串
     * @throws IOException 当文件不存在或读取失败时抛出
     */
    private  String readFileToString(String filePath) throws IOException {
        // 根据文件路径创建File对象
        File file = new File(filePath);
        // 使用try-with-resources自动关闭流：创建文件输入流和Scanner
        try (FileInputStream fis = new FileInputStream(file);
             java.util.Scanner scanner = new java.util.Scanner(fis, StandardCharsets.UTF_8.name())) {
            // 设置Scanner的分隔符为文件开始（即读取整个文件）
            scanner.useDelimiter("\\A");
            // 若有内容则返回内容，否则返回空字符串
            return scanner.hasNext() ? scanner.next() : "";
        }
    }

    // ---------- 测试方法入口 ----------

    /**
     * 主方法：测试入口
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        // 测试场景1：基础合并 + 新增数据（被注释，可取消注释执行）
//        testBasicMerge();
//
//        // 测试场景2：新JSON为null（被注释，可取消注释执行）
//        testNewJsonNull();

        // 测试场景3：字段value为null的处理（被注释，可取消注释执行）
        //testNullValueField();
    }

    /**
     * 测试场景1：基础合并逻辑
     * 验证已有协议字段覆盖、新增协议及字段的合并效果
     */
//    private static void testBasicMerge() {
//        System.out.println("===== 测试场景1：基础合并 =====");
//        // 基础JSON字符串（原始数据）
//        String baseJsonStr = " {\n" +
//                "                    \"借款协议_id\": {\n" +
//                "                        \"name\": \"借款协议\",\n" +
//                "                        \"id\": \"借款协议_id\",\n" +
//                "                        \"fields\": {\n" +
//                "                            \"借款协议_Field_id\": {\"dataType\": \"String\", \"name\": \"借款协议Field1\", \"value\": \"001\"},\n" +
//                "                            \"借款协议_Field_id1\": {\"dataType\": \"String\", \"name\": \"借款协议Field2\", \"value\": null}\n" +
//                "                        }\n" +
//                "                    },\n" +
//                "                    \"投资合同_id\": {\n" +
//                "                        \"name\": \"投资合同\",\n" +
//                "                        \"id\": \"投资合同_id\",\n" +
//                "                        \"fields\": {\"投资合同_Field_id1\": {\"dataType\": \"String\", \"name\": \"投资合同Field2\", \"value\": \"小明\"}}\n" +
//                "                    }\n" +
//                "                }";
//
//        // 新JSON字符串（待合并数据）
//        String newJsonStr = "{\n" +
//                "                    \"借款协议_id\": {\n" +
//                "                        \"name\": \"借款协议(修改)\",\n" +
//                "                        \"id\": \"借款协议_id\",\n" +
//                "                        \"fields\": {\n" +
//                "                            \"借款协议_Field_id1\": {\"dataType\": \"String\", \"name\": \"借款协议Field2\", \"value\": \"002\"},\n" +
//                "                            \"借款协议_Field_id2\": {\"dataType\": \"String\", \"name\": \"借款协议Field3\", \"value\": \"新字段\"}\n" +
//                "                        }\n" +
//                "                    },\n" +
//                "                    \"业务协议_id\": {\n" +
//                "                        \"name\": \"业务协议\",\n" +
//                "                        \"id\": \"业务协议_id\",\n" +
//                "                        \"fields\": {\"业务协议_Field_id\": {\"dataType\": \"String\", \"name\": \"业务协议Field1\", \"value\": \"19892761659\"}}\n" +
//                "                    }\n" +
//                "                }";
//
//        try {
//            // 执行合并
//            JSONObject mergedJson = mergeAgreements(baseJsonStr, newJsonStr);
//            // 打印合并结果（格式化输出）
//            System.out.println("合并结果\n" + JSONObject.toJSONString(mergedJson, true));
//        } catch (Exception e) {
//            // 捕获并打印合并失败信息
//            System.err.println("合并失败：" + e.getMessage());
//        }
//        System.out.println("------------------------\n");
//    }
//
//    /**
//     * 测试场景2：新JSON为null的情况
//     * 验证当新数据为null时，是否返回基础数据
//     */
//    private static void testNewJsonNull() {
//        System.out.println("===== 测试场景2：新JSON为null =====");
//        // 基础JSON字符串
//        String baseJsonStr = "{\"投资合同_id\": {\"name\": \"投资合同\", \"id\": \"投资合同_id\"}}";
//        try {
//            // 传入新JSON为null，执行合并
//            JSONObject mergedJson = mergeAgreements(baseJsonStr, null);
//            // 打印合并结果
//            System.out.println("合并结果\n" + JSONObject.toJSONString(mergedJson, true));
//        } catch (Exception e) {
//            // 捕获并打印合并失败信息
//            System.err.println("合并失败：" + e.getMessage());
//        }
//        System.out.println("------------------------\n");
//    }

    /**
     * 测试场景3：字段value为null的处理
     * 验证当新字段value为null时，是否保留基础字段的有效数据
     */
//    private static void testNullValueField() {
//        System.out.println("===== 测试场景3：字段value为null =====");
//        // 基础JSON字符串（包含有效value的字段）
//        String baseJsonStr = """
//                {
//                    "借款协议_id": {
//                        "fields": {"借款协议_Field_id": {"value": "有效数据"}}
//                    }
//                }""";
//
//        // 新JSON字符串（包含value为null的字段和新增字段）
//        String newJsonStr = """
//                {
//                    "借款协议_id": {
//                        "fields": {"借款协议_Field_id": {"value": null}, "新字段": {"value": "新数据"}}
//                    }
//                }""";
//
//        try {
//            // 执行合并
//            JSONObject mergedJson = mergeAgreements(baseJsonStr, newJsonStr);
//            // 打印合并结果（验证value为null的字段是否被忽略）
//            System.out.println("合并结果（验证字段value为null时的处理）：\n" + JSONObject.toJSONString(mergedJson, true));
//        } catch (Exception e) {
//            // 捕获并打印合并失败信息
//            System.err.println("合并失败：" + e.getMessage());
//        }
//    }
}