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

import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.bsf.service.app.IHRMsfService;
import com.kingdee.bos.metadata.entity.EntityViewInfo;
import com.kingdee.bos.metadata.entity.FilterInfo;
import com.kingdee.bos.metadata.entity.FilterItemInfo;
import com.kingdee.bos.metadata.entity.SelectorItemCollection;
import com.kingdee.bos.metadata.query.util.CompareType;
import com.kingdee.bos.sql.ParserException;
import com.kingdee.bos.util.BOSUuid;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.dataconfig.utils.SqlUtils;
import com.kingdee.eas.custom.entryconfig.DataConfigInfo;
import com.kingdee.eas.custom.entryconfig.DataConfigSelectFieldEntryCollection;
import com.kingdee.eas.custom.entryconfig.DataConfigSelectFieldEntryInfo;
import com.kingdee.eas.custom.esign.*;
import com.kingdee.eas.custom.esign.bizEnum.ComponentTypeEnum;
import com.kingdee.eas.custom.esign.utils.ESignFieldMappingUtils;
import com.kingdee.eas.fi.arap.util.DBUtil;
import com.kingdee.jdbc.rowset.IRowSet;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Map;

import org.apache.log4j.Logger;

public class OtherESignConfigDataService implements IHRMsfService {
	
	private static Logger logger = Logger.getLogger(OtherESignConfigDataService.class);
	
    @Override
    public Object process(Context context, Map map) throws EASBizException, BOSException {
        // 从参数映射中获取"number"参数值，用于定位配置信息
        Object o = map.get("number");
        // 从参数映射中获取"filter"参数值，用于构建查询过滤条件
        Object id = map.get("id");
        // 若"number"参数为null，返回空字符串（无效请求）
        if (o == null) {
            return "";
        }
        // 将"number"参数转换为字符串类型
        String number = o.toString();
        // 将"filter"参数转换为字符串类型（若为null则转换为"null"字符串）
        String filter = id.toString();
        // 声明实体视图信息对象，用于查询时的字段映射配置
        EntityViewInfo entityViewInfo = null;
        try {
            // 调用方法获取实体视图信息，该视图包含查询所需的字段映射配置
            entityViewInfo = this.getEntityViewInfo(number);
        } catch (ParserException e) {
            // 解析异常时，封装为运行时异常抛出
            throw new RuntimeException(e);
        }
        // 通过字段映射工厂，根据实体视图信息查询对应的字段映射集合
        FieldMappingCollection fieldMappingCollection = FieldMappingFactory.
                getLocalInstance(context).getFieldMappingCollection(entityViewInfo);
        // 创建SQL工具类实例，用于SQL语句的构建辅助
        //SqlUtils sqlUtils = new SqlUtils();
        // 创建电子签字段映射工具类实例，用于字段映射的核心处理
        ESignFieldMappingUtils utils = new ESignFieldMappingUtils();
        // 获取字段映射集合中的第一个映射信息（默认取第一个配置项）
        FieldMappingInfo fieldMappingInfo = fieldMappingCollection.get(0);
        // 获取当前字段映射信息中的明细项集合（包含具体的字段映射关系）
        FieldMappingEntryCollection entrys = fieldMappingInfo.getEntrys();
        // 获取当前字段映射信息对应的数据源配置
        //DataConfigInfo dataSource = fieldMappingInfo.getDataSource();

        // 验证数据源配置是否有效（非空且编号存在）
        //if (dataSource != null && dataSource.getNumber() != null && !dataSource.getNumber().equals("")) {
        // 通过工具类从字段映射明细中获取电子签SQL所需的字段集合
        //DataConfigSelectFieldEntryCollection eSignSqlField = utils.getESignSqlField(entrys);
        // 创建字符串构建器，用于拼接SQL查询的字段部分
        //StringBuilder sqlField = new StringBuilder();
        // 调用SQL工具类，将电子签字段集合拼接为SQL的SELECT子句
        //sqlUtils.getSelectField(eSignSqlField, sqlField);

        // 获取数据源配置的编号
        //String number1 = dataSource.getNumber();
        // 获取当前字段映射信息对应的电子签模板信息
        ESignTemplateInfo eSignFile = fieldMappingInfo.getESignFile();
//        if (sqlField.toString().equals("")) {
//            JSONObject jsonObject = this.reassembleData(eSignFile, context);
//            return jsonObject;
//        }
        // 通过工具类根据数据源编号和上下文获取电子签基础查询SQL
        //String eSignSql = utils.getESignSql(number1, context);
        // 替换SQL中的{{filed}}占位符为实际拼接的查询字段
        //eSignSql = eSignSql.replace("{{filed}}",sqlField.toString());
        // 在SQL末尾添加过滤条件（换行分隔，便于阅读）
        //eSignSql += "\n"+filter;
        // 执行SQL查询并将结果封装为JSON对象（包含字段映射关系）
        JSONObject data = this.getData(getSql(filter), context, entrys);
        // 重新组装电子签模板数据为JSON对象
        JSONObject jsonObject = this.reassembleData(eSignFile, context);
        // 合并查询数据与模板数据，返回合并后的JSON对象
        JSONObject newJSONObject = utils.mergeAgreements(data, jsonObject);
        return newJSONObject;

        // }
//        else {
//            // 若数据源无效，直接获取电子签模板信息
//            ESignTemplateInfo eSignFile = fieldMappingInfo.getESignFile();
//            // 重新组装模板数据并返回
//            JSONObject jsonObject = this.reassembleData(eSignFile, context);
//            return jsonObject;
//        }

    }

    public String getSql(String id) {
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT").append("\n");
        sql.append("person.FNAME_L2 AS person_name ,  -- 人员姓名").append("\n");
        sql.append("elation.FEnterDate  eDate ,  --入职日期").append("\n");
        sql.append("-- 1. 固定工资（税前）= 标准基本工资+综合工资+其他工资+加班工资").append("\n");
        sql.append("ISNULL(SUM(CASE WHEN sitem.FNUMBER IN ('TD01', 'T012', 'T013', 'TD02') THEN fas.FMoney ELSE 0 END), 0) AS fixed_salary ,").append("\n");
        sql.append("-- 2. 试用期固定工资（税前）= 标准基本工资+综合工资+其他工资+加班工资").append("\n");
        sql.append(" ISNULL(SUM(CASE WHEN sitem.FNUMBER IN ('TD01', 'T012', 'T013', 'TD02') THEN fas.FMoney ELSE 0 END), 0) AS prob_fixed_salary ,").append("\n");
        sql.append("  -- 3. 绩效奖金（税前）= 标准绩效奖金").append("\n");
        sql.append("ISNULL(SUM(CASE WHEN sitem.FNUMBER = 'TD04' THEN fas.FMoney ELSE 0 END), 0) AS perf_bonus ,").append("\n");
        sql.append("-- 4. 试用期绩效奖金（税前）= 试用期标准绩效奖金").append("\n");
        sql.append(" ISNULL(SUM(CASE WHEN sitem.FNUMBER = 'TD74' THEN fas.FMoney ELSE 0 END), 0) AS prob_perf_bonus ,").append("\n");
        sql.append("-- 5. 国内餐补 = 餐补补贴").append("\n");
        sql.append("ISNULL(SUM(CASE WHEN sitem.FNUMBER = 'T025' THEN fas.FMoney ELSE 0 END), 0) AS domestic_meal_subsidy ,").append("\n");
        sql.append(" -- 6. 艰苦补贴 = 艰苦补贴").append("\n");
        sql.append("ISNULL(SUM(CASE WHEN sitem.FNUMBER = 'T038' THEN fas.FMoney ELSE 0 END), 0) AS hardship_subsidy ,").append("\n");
        sql.append("-- 7. 社保公积金补贴 = 社保公积金补贴").append("\n");
        sql.append("ISNULL(SUM(CASE WHEN sitem.FNUMBER = 'TD101' THEN fas.FMoney ELSE 0 END), 0) AS social_fund").append("\n");
        sql.append("FROM").append("\n");
        sql.append("T_bd_Person person").append("\n");
        sql.append(" LEFT JOIN T_HR_EmpLaborRelation   elation 	on person.fid =  elation.FPersonID").append("\n");
        sql.append("LEFT JOIN").append("\n");
        sql.append("T_HR_SFixAdjustSalary fas ON person.FID = fas.FPersonID").append("\n");
        sql.append(" LEFT JOIN").append("\n");
        sql.append("T_HR_SCmpItem sitem ON fas.FCmpItemID = sitem.FID").append("\n");
        sql.append("WHERE").append("\n");
        sql.append("sitem.FNUMBER IN ('TD01', 'T012', 'T013', 'TD02', 'TD04', 'TD74', 'T025', 'T038', 'TD101')").append("\n");
        sql.append("and  person.fid  in (select FEmployeeID from T_HR_EmployeeContract where fid = '"+id+"')").append("\n");
        sql.append(" GROUP BY").append("\n");
        sql.append("person.FID, person.FNAME_L2  , elation.FEnterDate").append("\n");
        sql.append("ORDER BY").append("\n");
        sql.append("person.FNAME_L2").append("\n");
        return sql.toString();
    }

    /**
     * 执行SQL查询并将结果封装为JSON对象
     *
     * @param sql     要执行的查询SQL
     * @param context 上下文对象
     * @param entrys  字段映射明细集合
     * @return 封装后的JSON对象，包含电子签模板各字段信息
     */
    public JSONObject getData(String sql, Context context, FieldMappingEntryCollection entrys) {
        // 创建JSON对象用于存储最终封装的数据
        JSONObject jsonObject = new JSONObject();
        try {
            // 执行SQL查询，获取结果集
            IRowSet iRowSet1 = DBUtil.executeQuery(context, sql);
            // 遍历结果集中的每一行数据
				while (iRowSet1.next()) {
				    // 遍历每个字段映射明细项
				    for (int i = 0; i < entrys.size(); i++) {
				        // 获取当前索引对应的字段映射明细信息
				        FieldMappingEntryInfo fieldMappingEntryInfo = entrys.get(i);
				        // 获取明细项中关联的电子签模板字段信息
				        ESignTemplateFileEntryFieldInfo eField = fieldMappingEntryInfo.getEField();
				        // 判断该字段是否无效（已废弃）
				        boolean invalid = eField.isInvalid();
				        // 若字段无效，跳过当前循环（不处理）
				        if (invalid) {
				            continue;
				        }
				        // 获取明细项中关联的电子签模板明细信息
				        ESignTemplateFileEntryInfo template = fieldMappingEntryInfo.getTemplate();
				        // 获取电子签模板的ID
				        String eSignTemplateId = template.getESignTemplateId();
				        // 从JSON对象中获取该模板ID对应的子JSON对象
				        JSONObject templateJSON = jsonObject.getJSONObject(eSignTemplateId);
				        // 若模板对应的子JSON对象不存在，则创建并初始化（设置ID和名称）
				        if (templateJSON == null) {
				            templateJSON = new JSONObject();
				            templateJSON.put("id", eSignTemplateId); // 设置模板ID
				            templateJSON.put("name", template.getName()); // 设置模板名称
				            jsonObject.put(eSignTemplateId, templateJSON); // 将模板信息存入主JSON对象
				        }
				        // 从模板子JSON对象中获取字段信息对应的子JSON对象
				        JSONObject fields = templateJSON.getJSONObject("fields");
				        // 若字段信息子JSON对象不存在，则创建并添加到模板子JSON中
				        if (fields == null) {
				            fields = new JSONObject();
				            templateJSON.put("fields", fields);
				        }
				        // 获取电子签模板字段的ID
				        String templateFieldId = eField.getTemplateFieldId();
				        // 创建用于存储字段值信息的JSON对象
				        JSONObject value = new JSONObject();
				        value.put("name", eField.getTemplateFieldName()); // 设置字段名称
				        // 获取明细项中关联的数据源字段信息
				        //DataConfigSelectFieldEntryInfo dataSourceField = fieldMappingEntryInfo.getDataSourceField();
//                    if (dataSourceField==null){
//                        value.put("value","");
//                        value.put("dataFormat", eField.getDataFormat());
//                    }else {
				        // 获取数据源字段的映射键（对应数据库列名）
				        String name = fieldMappingEntryInfo.getEFieldMark();
				        // 去除映射键中的双引号（处理可能的格式问题）
				        //name = name.replace("\"", "");
				        // 从结果集中获取该字段对应的值，并存入字段值JSON对象
				        if (name != null && !name.equals("")) {
				            try {
								value.put("value", iRowSet1.getObject(name));
							} catch (SQLException e) {
								e.printStackTrace();
							}
				        }
				        // 设置字段的数据类型（取自数据源字段的类型别名）
				        //value.put("dataType", dataSourceField.getDataType().getAlias());
//                    if (dataSourceField.getDataType().getAlias().equals("Date")) {
//                        Object object = iRowSet1.getObject(name);
//                        if (object != null) {
//                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
//                            value.put("value", simpleDateFormat.format(iRowSet1.getDate(name)));
//                        }
//                        value.put("dataFormat", eField.getDataFormat());
//                    }
				        //}
				        if (eField.getComponentType().getValue() == 6 || eField.getComponentType().getValue() == 106) {
				            value.put("positionX", eField.getPositionX());
				            value.put("positionY", eField.getPositionY());
				            value.put("pageNum", eField.getPageNum());
				        }
				        // 将字段值信息存入字段信息子JSON对象（以模板字段ID为键）
				        fields.put(templateFieldId, value);
				    }
				}
		 

        } catch (BOSException e) {
            // BOS异常时，封装为运行时异常抛出
            throw new RuntimeException(e);
        } catch (SQLException e) {
            // SQL异常时，封装为运行时异常抛出
            throw new RuntimeException(e);
        }  
        // 返回封装好的JSON对象
        return jsonObject;
    }

    /**
     * 构建查询字段映射信息的实体视图
     *
     * @param number 字段映射的编号，用于过滤
     * @return 构建好的实体视图信息
     * @throws ParserException 解析异常
     */
    public EntityViewInfo getEntityViewInfo(String number) throws ParserException {
        // 创建实体视图信息对象
        EntityViewInfo entityViewInfo = new EntityViewInfo();
        // 创建选择项集合，用于指定查询返回的字段
        SelectorItemCollection selectorItemCollection = new SelectorItemCollection();
        selectorItemCollection.add("*"); // 选择所有基础字段
        selectorItemCollection.add("eSignFile.*"); // 选择关联的电子签文件的所有字段
        selectorItemCollection.add("dataSource.*"); // 选择关联的数据源的所有字段
        selectorItemCollection.add("entrys.*"); // 选择关联的明细项的所有字段
        selectorItemCollection.add("entrys.eField.*"); // 选择明细项中电子签字段的所有字段
        selectorItemCollection.add("entrys.dataSourceField.*"); // 选择明细项中数据源字段的所有字段
        selectorItemCollection.add("entrys.template.*"); // 选择明细项中模板的所有字段
        // 为实体视图设置选择项（指定查询返回的字段集）
        entityViewInfo.setSelector(selectorItemCollection);
        // 创建过滤信息对象，用于设置查询条件
        FilterInfo filterInfo = new FilterInfo();
        // 添加过滤条件：字段映射的编号等于传入的number
        filterInfo.getFilterItems().add(new FilterItemInfo("number", number));
        // 为实体视图设置过滤条件
        entityViewInfo.setFilter(filterInfo);
        // 返回构建好的实体视图信息
        return entityViewInfo;
    }

    /**
     * 重新组装数据（当前未实现完整逻辑，仅基础框架）
     *
     * @param eSignFile 电子签模板信息
     * @param context   上下文对象
     * @return 重新组装后的JSON对象（数据可能为null）
     */
    public JSONObject reassembleData(ESignTemplateInfo eSignFile, Context context) {
        // 获取电子签模板的ID
        BOSUuid id = eSignFile.getId();
        // 声明用于存储组装后数据的JSON对象
        JSONObject dataJSON;
        try {
            // 初始化数据JSON对象
            dataJSON = new JSONObject();
            // 创建实体视图信息对象
            EntityViewInfo entityViewInfo = new EntityViewInfo();
            // 创建选择项集合，指定查询返回的字段
            SelectorItemCollection selectorItemCollection = new SelectorItemCollection();
            selectorItemCollection.add("*"); // 选择所有基础字段
            selectorItemCollection.add("Parent1.*"); // 选择父级对象的所有字段
            // 为实体视图设置选择项
            entityViewInfo.setSelector(selectorItemCollection);
            // 创建过滤信息对象
            FilterInfo filterInfo = new FilterInfo();
            // 添加过滤条件：字段未失效（Invalid为false）
            filterInfo.getFilterItems().add(new FilterItemInfo("Invalid", 1, CompareType.NOTEQUALS));
            // 添加过滤条件：父级的父级ID等于电子签模板ID
            filterInfo.getFilterItems().add(new FilterItemInfo("Parent1.Parent.id", id));
            // 为实体视图设置过滤条件
            entityViewInfo.setFilter(filterInfo);
            // 根据实体视图查询电子签模板字段明细集合
            ESignTemplateFileEntryFieldCollection eFields = ESignTemplateFileEntryFieldFactory.
                    getLocalInstance(context).getESignTemplateFileEntryFieldCollection(entityViewInfo);
            // 遍历字段明细集合
            for (int i = 0; i < eFields.size(); i++) {

                // 获取当前索引对应的电子签模板字段明细
                ESignTemplateFileEntryFieldInfo eFile = eFields.get(i);
                // 获取该字段明细的父级对象（模板明细）
                ESignTemplateFileEntryInfo parent1 = eFile.getParent1();
                // 获取电子签模板ID
                String eSignTemplateId = parent1.getESignTemplateId();
                // 获取电子签模板名称
                String name = parent1.getName();
                // 从数据JSON中获取模板ID对应的子JSON对象
                JSONObject signTemplate = dataJSON.getJSONObject(eSignTemplateId);
                // 若模板子JSON对象不存在，则创建并初始化
                if (signTemplate == null) {
                    signTemplate = new JSONObject();
                    signTemplate.put("name", name); // 设置模板名称
                    signTemplate.put("id", eSignTemplateId); // 设置模板ID
                    JSONObject fields = new JSONObject(); // 创建字段信息JSON对象
                    signTemplate.put("fields", fields); // 将字段信息存入模板JSON
                    dataJSON.put(eSignTemplateId, signTemplate);
                }
                // 从模板子JSON中获取字段信息JSON对象
                JSONObject fields = signTemplate.getJSONObject("fields");
                // 获取模板字段ID
                String templateFieldId = eFile.getTemplateFieldId();
                // 从字段信息JSON中获取该字段ID对应的子JSON对象
                JSONObject field = fields.getJSONObject(templateFieldId);
                // 若字段子JSON对象不存在，则创建并添加到字段信息JSON
                if (field == null) {
                    field = new JSONObject();
                    fields.put(templateFieldId, field);
                }
                // 获取模板字段名称
                String templateFieldName = eFile.getTemplateFieldName();
                // 设置字段名称到字段子JSON
                field.put("name", templateFieldName);
                // 获取字段组件类型
                ComponentTypeEnum componentType = eFile.getComponentType();
                // 设置字段数据类型（取自组件类型的别名）
                field.put("dataType", componentType.getAlias());
                field.put("dataFormat", eFile.getDataFormat());
                field.put("isRequired", eFile.isRequired());
                field.put("seq", eFile.getSeq());
                // 字段值暂设为null
                field.put("value", null);
            }

        } catch (BOSException e) {
            // BOS异常时，封装为运行时异常抛出
            throw new RuntimeException(e);
        }
        // 返回重新组装后的JSON对象
        return dataJSON;
    }
}
