package com.system.api;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.system.constants.KingDeeConstants;
import com.system.dao.InitConnectParamMapper;
import com.system.exception.KingDeeConnectException;
import com.system.model.DelayedElement;
import com.system.model.InitConnectParam;
import com.system.utils.HttpUtil;
import com.system.utils.JsonUtil;
import com.system.utils.KingDeeLogUtil;
import com.system.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author Inori
 */
@Slf4j
@Component
public class KingDeeApi {

    private final String serviceNameTable = "LQKJ.WebApi.Stub.CustomWebApiService.ExecutDataSet,LQKJ.WebApi.Stub";

    private final String serviceNameMap = "LQKJ.WebApi.Stub.CustomWebApiService.ExecuteDynamicObject,LQKJ.WebApi.Stub";

    private final String updateService = "LQKJ.WebApi.Stub.CustomWebApiService.ExecutBatch,LQKJ.WebApi.Stub";

    private ExecutorService threadPool = new ThreadPoolExecutor(10, 10,
            0L,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(1024),
            new ThreadFactoryBuilder().setNameFormat("env-pool-%d").build(),
            new ThreadPoolExecutor.AbortPolicy());

    private static final String LOGIN_MESSAGE = "金蝶服务器地址异常";

    public InitConnectParam initConnectParam;

    public String thirdPartyUrl;

    public boolean flag = false;

    public KingDeeK3CloudApi kingDeeK3CloudApi;

    @Autowired
    private InitConnectParamMapper initConnectParamMapper;

    @Autowired
    private KingDeeLogUtil kingDeeLogUtil;


    @PostConstruct
    public void init() {
        initConnectParam = initConnectParamMapper.selectOne(new QueryWrapper<InitConnectParam>().last("LIMIT 1"));
        if (StringUtil.isNotNull(initConnectParam)) {
            thirdPartyUrl = initConnectParam.getThirdPartyUrl();
            kingDeeK3CloudApi = new KingDeeK3CloudApi(initConnectParam.getK3CloudUrl());
        }
    }

    public InitConnectParam getInitConnectParam() {
        return initConnectParam;
    }

    public void setInitConnectParam(InitConnectParam initConnectParam) {
        this.initConnectParam = initConnectParam;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public KingDeeK3CloudApi getKingDeeK3CloudApi() {
        return kingDeeK3CloudApi;
    }

    public void setKingDeeK3CloudApi(KingDeeK3CloudApi kingDeeK3CloudApi) {
        this.kingDeeK3CloudApi = kingDeeK3CloudApi;
    }

    public String getThirdPartyUrl() {
        return thirdPartyUrl;
    }

    public void setThirdPartyUrl(String thirdPartyUrl) {
        this.thirdPartyUrl = thirdPartyUrl;
    }

    private String stringKey(Map<String, String> map) {
        StringBuilder keys = new StringBuilder();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (StringUtil.isNotBlank(keys)) {
                keys.append(", ").append(entry.getKey());
            } else {
                keys = new StringBuilder(entry.getKey());
            }
        }
        if (StringUtil.isNotBlank(keys.toString())) {
            return "\"FieldKeys\":\"" + keys.toString() + "\"";
        }
        return "";
    }

    private String stringWhere(Map<String, String> map) {
        StringBuilder where = new StringBuilder();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (StringUtil.isNotBlank(where)) {
                where.append(" AND ").append(entry.getKey()).append("='").append(entry.getValue()).append("'");
            } else {
                where = new StringBuilder(entry.getKey() + "='" + entry.getValue() + "'");
            }
        }
        if (StringUtil.isNotBlank(where.toString())) {
            return ",\"FilterString\":\"" + where.toString() + "\"";
        }
        return "";
    }

    /**
     * 查询单据体
     */
    public List<List<Object>> getKingDeeData(String sFormId, String queueId, Map<String, String> key, Map<String, String> where, String kingDeeLogName) {
        try {
            if (this.flag) {
                String content = "{\"FormId\":\"" + sFormId + "\"," + stringKey(key) + stringWhere(where) + "}";
                System.out.println("================content==============" + content + "=================content===================");
                List<List<Object>> result = kingDeeK3CloudApi.executeBillQuery(content);
                //记录查询金蝶云数据的请求及响应信息
                if (StringUtil.isNotBlank(kingDeeLogName)) {
                    kingDeeLogUtil.kingDeeSynLogCreate(queueId, kingDeeLogName, content, result);
                }
                return result;
            } else {
                throw new KingDeeConnectException(LOGIN_MESSAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (StringUtil.isNotBlank(kingDeeLogName)) {
                kingDeeLogUtil.kingDeeErrorLogCreate(kingDeeLogName, queueId, "", LOGIN_MESSAGE);
            }
            throw new KingDeeConnectException(LOGIN_MESSAGE);
        }
    }

    /**
     * 金蝶同步
     */
    public List<List<Object>> synchronization(String sFormId, Map<String, String> key, Map<String, String> where, String kingDeeLogName, String queueId) {
        try {
            if (this.flag) {
                String request = "{\"FormId\":\"" + sFormId + "\"," + stringKey(key) + stringWhere(where) + "}";
                System.out.println("================content==============" + request + "=================content===================");
                List<List<Object>> result = kingDeeK3CloudApi.executeBillQuery(request);
                //记录查询金蝶云数据的请求及响应信息
                kingDeeLogUtil.kingDeeSynLogCreate(queueId, kingDeeLogName, request, result);

                return result;
            } else {
                throw new KingDeeConnectException(LOGIN_MESSAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
            kingDeeLogUtil.kingDeeErrorLogCreate(kingDeeLogName, queueId, "", LOGIN_MESSAGE);
            throw new KingDeeConnectException(LOGIN_MESSAGE);
        }
    }

    /**
     * 金蝶数据删除
     */
    public String delete(String sFormId, String fid, String kingDeeLogName, String queueId) {
        try {
            if (this.flag) {
                String content = "{\"Ids\":" + fid + "}";
                String result = kingDeeK3CloudApi.delete(sFormId, content);
                //记录删除金蝶云数据的请求及响应信息
                kingDeeLogUtil.kingDeePushLogCreate(kingDeeLogName, queueId, content, result);

                return result;
            } else {
                throw new KingDeeConnectException(LOGIN_MESSAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
            kingDeeLogUtil.kingDeeErrorLogCreate(kingDeeLogName, queueId, "", LOGIN_MESSAGE);
            throw new KingDeeConnectException(LOGIN_MESSAGE);
        }
    }

    public String kingDeeDataPush(Map<String, Object> data, String kingDeeLogName, String queueId) {
        try {
            if (this.flag) {
                String result = kingDeeK3CloudApi.execute("LQKJ.WebApi.Stub.CustomWebApiService.PushAndSave,LQKJ.WebApi.Stub", new Object[]{data}, String.class);

                //记录下推金蝶云数据的请求及响应信息
                kingDeeLogUtil.kingDeeLogCreate(kingDeeLogName, queueId, JsonUtil.toString(data), result);

                return result;
            } else {
                throw new KingDeeConnectException(LOGIN_MESSAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
            kingDeeLogUtil.kingDeeErrorLogCreate(kingDeeLogName, queueId, "", LOGIN_MESSAGE);
            throw new KingDeeConnectException(LOGIN_MESSAGE);
        }
    }

    /**
     * SQL更新金蝶数据
     */
    public String kingDeeUpdateBySql(String sql, String kingDeeLogName, String queueId) {
        return kingDeeSql(sql, kingDeeLogName, queueId, updateService);
    }

    /**
     * SQL查询金蝶数据
     */
    public String kingDeeSelectBySql(String sql, String kingDeeLogName, String queueId) {
        return kingDeeSql(sql, kingDeeLogName, queueId, serviceNameMap);
    }

    private String kingDeeSql(String sql, String kingDeeLogName, String queueId, String serviceName) {
        try {
            if (this.flag) {
                Object[] data = new Object[]{sql};
                String result = kingDeeK3CloudApi.execute(serviceName, data, String.class);

                //记录SQL查询金蝶数据的请求及响应信息
                kingDeeLogUtil.kingDeeSqlLogCreate(kingDeeLogName, queueId, JsonUtil.toString(sql), result);

                return result;
            } else {
                throw new KingDeeConnectException(LOGIN_MESSAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
            kingDeeLogUtil.kingDeeErrorLogCreate(kingDeeLogName, queueId, "", LOGIN_MESSAGE);
            throw new KingDeeConnectException(LOGIN_MESSAGE);
        }
    }

    /**
     * 批量保存
     */
    public void batchAdd(String sFormId, String json) {
        try {
            if (this.flag) {
                String content = "{\"Model\":" + json + "}";
                kingDeeK3CloudApi.batchSave(sFormId, content);
            } else {
                throw new KingDeeConnectException(LOGIN_MESSAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new KingDeeConnectException(LOGIN_MESSAGE);
        }
    }

    public String sendThirdParty(String json, int index) {
        try {
            return HttpUtil.httpPost(this.thirdPartyUrl, json).getBody();
        } catch (Exception e) {
            if (index != 0) {
                this.sendThirdParty(json, index - 1);
            } else {
                HttpUtil.httpGet("http://127.0.0.1:8090/integrate/api/turn/off/synchronization");

                DelayQueue<DelayedElement> delayQueue = new DelayQueue<>();
                threadPool.execute(() -> {
                    //take方法将阻塞线程
                    delayQueue.add(new DelayedElement(60));

                    try {
                        delayQueue.take();
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }

                    HttpUtil.httpGet("http://127.0.0.1:8090/integrate/api/start/synchronization");
                });
            }

            Map<String, Object> map = new HashMap<>(2);
            map.put("resultCode", KingDeeConstants.OVERTIME_CODE);
            map.put("resultMsg", "第三方请求超时");
            return JsonUtil.toString(map);
        }
    }

    public String sendPlugInUnit(String plugInUrl, String json, Integer index) {
        try {
            return HttpUtil.httpPost(plugInUrl, json).getBody();
        } catch (Exception e) {
            if (index != 0) {
                this.sendPlugInUnit(plugInUrl, json, index - 1);
            }

            Map<String, Object> map = new HashMap<>(2);
            map.put("resultCode", KingDeeConstants.ERROR_CODE);
            map.put("resultMsg", "插件请求超时");
            return JsonUtil.toString(map);
        }
    }


}

