package com.system.serivce.impl;

import com.system.constants.KingDeeCommonPushConstants;
import com.system.constants.KingDeeConstants;
import com.system.kingdee.KingDeeCommonPushKingDeeApi;
import com.system.scheduler.KingDeeLoginScheduler;
import com.system.scheduler.LicScheduler;
import com.system.serivce.IKingDeeCommonPushService;
import com.system.transfer.kingdee.KingDeeUpdateThirdDataInVo;
import com.system.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Inori
 */
@Service
public class KingDeeCommonPushServiceImpl implements IKingDeeCommonPushService {

    @Autowired
    private KingDeeCommonPushKingDeeApi kingDeeCommonpushKingDeeApi;

    @Autowired
    private KingDeeCommonPushConstants kingDeeCommonPushConstants;

    @Autowired
    private KingDeeLoginScheduler kingDeeLoginScheduler;

    @Autowired
    private ThirdPartyLogUtil thirdPartyLogUtil;

    @Autowired
    private LicScheduler licScheduler;


    @Override
    public Object kingDeeUpdateThirdData(KingDeeUpdateThirdDataInVo inVo) {
        if (!licScheduler.isFlag()) {
            return PushResultUtil.purchaseTo(KingDeeConstants.ERROR_CODE, "操作失败！权限限制", new ArrayList<>());
        }
        //读取配置
        Map<String, String> map = kingDeeCommonPushConstants.get(inVo.getDocType());
        if (CollectionUtils.isEmpty(map)) {
            return PushResultUtil.purchaseTo(KingDeeConstants.ERROR_CODE, "操作失败! 第三方标识为: " + inVo.getDocType() + " 的MES-ERP标识不存在", new ArrayList<>());
        }
        String sFormId = map.get("sFormId");
        String entryName = map.get("entryName");
        String fathersFormId = map.get("fathersFormId");
        String fatherEntryName = map.get("fatherEntryName");
        String pushRule = map.get("pushRule");
        String isInTransaction = map.get("isInTransaction");
        String isAutoPerform = map.get("isAutoPerform");
        String kingDeeLogName = StringUtil.isNotBlank(map.get("kingDeeLogName")) ? map.get("kingDeeLogName") : "自定义下推金蝶日志";
        String kingDeeFiledDetail = map.get("kingDeeFiledDetail");
        String plugInUrl = map.get("plugInUrl");
        String customSql = map.get("customSql");

        //记录IMS日志
        String queueId = String.valueOf(inVo.getData().get(0).get("QUEUE_ID"));
        if (thirdPartyLogUtil.isExist(queueId) != 0) {
            return PushResultUtil.purchaseTo(KingDeeConstants.ERROR_CODE, "操作失败! QUEUE_ID为: " + queueId + "的唯一标识已存在", new ArrayList<>());
        }
        Integer id = thirdPartyLogUtil.thirdPartyLogCreate(kingDeeLogName, inVo.getDocType(), queueId, JsonUtil.toString(inVo.getData()), null, 0);

        //是否执行插件
        if (StringUtil.isNotBlank(plugInUrl)) {
            String plugInUrlResult = kingDeeCommonpushKingDeeApi.sendPlugInUnit(plugInUrl, JsonUtil.toString(inVo));
            thirdPartyLogUtil.thirdPartyLogCreate(kingDeeLogName + "执行插件", inVo.getDocType(), queueId, JsonUtil.toString(inVo), plugInUrlResult, 1);

            Map<String, Object> temp = JsonUtil.toMap(plugInUrlResult, String.class, Object.class);
            if (temp.containsKey(KingDeeConstants.CODE_NAME) && !KingDeeConstants.ERROR_CODE.equals(temp.get(KingDeeConstants.CODE_NAME))) {
                if (temp.containsKey(KingDeeConstants.DATA_NAME)) {
                    List<Object> objectList = JsonUtil.toList(JsonUtil.toString(temp.get("data")), Object.class);
                    List<Map<String, Object>> dataList = objectList.stream().map(m -> JsonUtil.toMap(JsonUtil.toString(m), String.class, Object.class)).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(dataList)) {
                        inVo.setData(dataList);
                    }
                }
            } else {
                Object result = PushResultUtil.purchaseTo(KingDeeConstants.ERROR_CODE, "操作失败! docType为: " + inVo.getDocType() + " 的标识执行插件请求错误 " + temp.get("resultMsg"), new ArrayList<>());
                thirdPartyLogUtil.thirdPartyLogUpdate(id, JsonUtil.toString(result));
                return result;
            }
        }

        //是否执行SQL
        if (StringUtil.isNotBlank(customSql)) {
            return this.implementSql(inVo, kingDeeLogName, queueId, customSql, id);
        }

        //保存
        List<String> fatherEntryIdList = new ArrayList<>();
        if (StringUtil.isNotBlank(fathersFormId)) {
            fatherEntryIdList = inVo.getData().stream().filter(m -> m.containsKey("ERP_SIC")).map(m -> String.valueOf(m.get("ERP_SIC"))).collect(Collectors.toList());
        }
        Map<String, Object> data = new LinkedHashMap<>();
        this.purchase(data, "FormId", sFormId);
        this.purchase(data, "ConvertRule", pushRule);
        this.purchase(data, "SrcFormId", fathersFormId);
        this.purchase(data, "SrcEntryKey", fatherEntryName);
        this.purchase(data, "SrcIds", fatherEntryIdList);
        this.purchase(data, "IsInTransaction", "1".equals(isInTransaction));
        this.purchase(data, "isAutoSubmit", this.getIsAutoSubmit(isAutoPerform));

        return this.purchaseRequest(inVo, id, entryName, kingDeeLogName, queueId, kingDeeFiledDetail, data);
    }

    /**
     * 封装请求及返回值
     */
    private Object purchaseRequest(KingDeeUpdateThirdDataInVo inVo, Integer id, String entryName, String kingDeeLogName, String queueId, String kingDeeFiledDetail, Map<String, Object> data) {
        List<Object> objectList = JsonUtil.toList(kingDeeFiledDetail, Object.class);
        List<Map<String, String>> fieldList = objectList.stream().map(m -> JsonUtil.toMap(JsonUtil.toString(m), String.class, String.class)).collect(Collectors.toList());
        String addTwo = kingDeeCommonpushKingDeeApi.kingDeeUpdateThirdData(inVo.getData(), fieldList, data, entryName, kingDeeLogName, queueId);

        Map<String, Object> temp = JsonUtil.toMap(addTwo, String.class, Object.class);
        if (!CollectionUtils.isEmpty(temp) && KingDeeConstants.NOT_LOGGED_IN_CODE.equals(temp.get(KingDeeConstants.CODE_NAME))) {
            kingDeeLoginScheduler.configureTasks();
            addTwo = kingDeeCommonpushKingDeeApi.kingDeeUpdateThirdData(inVo.getData(), fieldList, data, entryName, kingDeeLogName + "重新登陆请求", queueId);
            temp = JsonUtil.toMap(addTwo, String.class, Object.class);
        }

        Object result;
        if (!CollectionUtils.isEmpty(temp) && !KingDeeConstants.SUCCESS_CODE.equals(temp.get(KingDeeConstants.CODE_NAME))) {
            result = PushResultUtil.purchaseTo(KingDeeConstants.ERROR_CODE, "操作失败! " + StringUtil.replaceBlank((String) temp.get("resultMsg")), KingDeeUtil.getPushResultMap(temp));
        } else if (CollectionUtils.isEmpty(temp)) {
            result = PushResultUtil.purchaseTo(KingDeeConstants.ERROR_CODE, "操作失败! " + StringUtil.replaceBlank(addTwo), KingDeeUtil.getPushResultMap(temp));
        } else {
            result = PushResultUtil.purchaseTo(KingDeeConstants.SUCCESS_CODE, "", KingDeeUtil.getPushResultMap(temp));
        }
        thirdPartyLogUtil.thirdPartyLogUpdate(id, JsonUtil.toString(result));

        return result;
    }

    private Object implementSql(KingDeeUpdateThirdDataInVo inVo, String kingDeeLogName, String queueId, String customSql, Integer id) {
        String kingDeeSql = "";
        for (Map<String, Object> temp : inVo.getData()) {
            for (Map.Entry<String, Object> entry : temp.entrySet()) {
                if (customSql.contains("@" + entry.getKey())) {
                    kingDeeSql = customSql.replaceAll("@" + entry.getKey(), String.valueOf(entry.getValue()));
                }
            }
        }

        if (StringUtil.isBlank(kingDeeSql)) {
            kingDeeSql = customSql;
        }
        //DES加密
        kingDeeSql = DesHelperUtil.encrypt(kingDeeSql, StandardCharsets.UTF_8, "MES&&DES");
        String result = kingDeeCommonpushKingDeeApi.kingDeeUpdateBySql(kingDeeSql, kingDeeLogName + "执行SQL", queueId);

        Map<String, Object> map = JsonUtil.toMap(result, String.class, Object.class);
        if (map.containsKey(KingDeeConstants.CODE_NAME) && !KingDeeConstants.ERROR_CODE.equals(map.get(KingDeeConstants.CODE_NAME))) {
            Object object = PushResultUtil.purchaseTo(KingDeeConstants.SUCCESS_CODE, "SQL执行成功", new ArrayList<>());
            thirdPartyLogUtil.thirdPartyLogUpdate(id, JsonUtil.toString(object));
            return object;
        } else {
            String message = "";
            if (map.containsKey(KingDeeConstants.MSG_NAME)) {
                message = StringUtil.replaceBlank(String.valueOf(map.get(KingDeeConstants.MSG_NAME)));
            }
            Object object = PushResultUtil.purchaseTo(KingDeeConstants.ERROR_CODE, "SQL执行失败 " + message, new ArrayList<>());
            thirdPartyLogUtil.thirdPartyLogUpdate(id, JsonUtil.toString(object));
            return object;
        }
    }

    private void purchase(Map<String, Object> data, String key, Object value) {
        if (value instanceof ArrayList) {
            if (!CollectionUtils.isEmpty(JsonUtil.toList(JsonUtil.toString(value), Object.class))) {
                data.put(key, value);
            }
        } else {
            if (StringUtil.isNotBlank(String.valueOf(value))) {
                data.put(key, value);
            }
        }
    }

    private String getIsAutoSubmit(String isAutoPerform) {
        String isAutoSubmit = "";
        if ("0".equals(isAutoPerform)) {
            isAutoSubmit = "draft";
        } else if ("1".equals(isAutoPerform)) {
            isAutoSubmit = "save";
        } else if ("2".equals(isAutoPerform)) {
            isAutoSubmit = "submit";
        } else if ("3".equals(isAutoPerform)) {
            isAutoSubmit = "auto";
        }
        return isAutoSubmit;
    }


}
