package com.zfire.jiasm.syncdata.common;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 工单数据同步到格力总部
 * 1:需要生成上传任务清单列表   ProduceUploadList处理
 * 2:生成需要上传的数据   ProduceDataUploadList处理
 * <p>
 * out_jiasm_to_gree_syn_rule 数据同步记录表提取数据
 * 根据源数据表名提取对应的数据
 * 组装参数进行数据同步
 * 修改同步表的同步状态
 */

@Slf4j
@Service
public class DataUploadLogic {/*
    @Value("${baseurl}")
    private String baseurl;
    @Autowired
    private TokenCenter tokenCenter;
    @Resource
    private UploadService uploadService;
    @Autowired
    private CommonService commonService;
    @Autowired
    RedisUtil redis;

    private Map<Integer, Boolean> map = new ConcurrentHashMap<Integer, Boolean>();


    public void uploaditftblazassignappointment() throws Exception {
        // 数据同步记录表中提取数据 out_jiasm_to_gree_syn_rule
        // 用户预约改约
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_ASSIGN_APPOINTMENT_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazwgmxjyktfj() throws Exception {
        // 家用空调数据采集附件
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_WGMX_JYKT_FJ_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazwgmxsyktfj() throws Exception {
        // 商用空调数据采集附件
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_WGMX_SYKT_FJ_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazwgmxqitafj() throws Exception {
        // 其他数据采集附件
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_WGMX_QITA_FJ_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazwgmxjykttmmx() throws Exception {
        // 家用空调条码明细
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_WGMX_JYKT_TMMX_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazwgmxsykttmmxls() throws Exception {
        // 商用完工明细数据采集条码明细
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_WGMX_SYKT_TMMX_LS_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazwgmxqitatmmx() throws Exception {
        // 其他完工明细数据采集条码明细
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_WGMX_QITA_TMMX_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazassignfkmx() throws Exception {
        // 安装反馈明细
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_ASSIGN_FKMX_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazassignfee() throws Exception {
        // 空调安装费用清单
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_ASSIGN_FEE_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazassignlcls() throws Exception {
        // 安装主表
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_ASSIGN_LC_LS_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazwgmxqita() throws Exception {
        // 完工明细(其他)
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_WGMX_QITA_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazwgmxjykt() throws Exception {
        // 完工明细(家用空调)
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_WGMX_JYKT_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazwgmxsykt() throws Exception {
        // 完工明细(商用空调)
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_WGMX_SYKT_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazassignmx() throws Exception {
        // 安装工单明细
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_ASSIGN_MX_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblwxjspjmxjykt() throws Exception {
        // 配件表
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.WXJS_PJMX_JYKT_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblwxjswxxmjykt() throws Exception {
        // 维修项目
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.WXJS_WXXM_JYKT_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblwxjsxxyyjykt() throws Exception {
        // 维修现象
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.WXJS_XXYY_JYKT_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblwxjsfjjykt() throws Exception {
        // 维修附件表
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.WXJS_FJ_JYKT_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblassignfee() throws Exception {
        // 维修费用表
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.ASSIGN_FEE_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblassignxzyd() throws Exception {
        // 新增阅读记录维护表
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.ASSIGN_XZYD_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblwxjsjykt() throws Exception {
        // 维修结算表
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.WXJS_JYKT_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblassign() throws Exception {
        // 维修单表
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.ASSIGN_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblassignmx() throws Exception {
        // 维修单明细
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.ASSIGN_MX_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblassignappointment() throws Exception {
        // 维修单预约改约信息
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.ASSIGN_APPOINTMENT_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblassignfkmx() throws Exception {
        // 维修工单反馈信息
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.ASSIGN_FKMX_UPLOAD.getCode());
        uploadData(result);
    }

    public void uploaditftblazassignxzyd() throws Exception {
        // 新增安装阅读记录维护表
        getAccessToken();
        List<Map<String, Object>> result = uploadService.getTaskData(UploadTableEnum.AZ_ASSIGN_XZYD_UPLOAD.getCode());
        uploadData(result);
    }


    private void uploadData(List<Map<String, Object>> result) {
        for (Map<String, Object> row : result) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    int taskId = (Integer) row.get("id");
                    synchronized (map) {
                        if (map.get(taskId) != null && map.get(taskId) == Boolean.TRUE) {
                            return;
                        }
                        map.put(taskId, Boolean.TRUE);
                    }

                    try {
                        String synMode = (String) row.get("syn_mode");
                        String srcTabName = (String) row.get("src_tab_name");

                        // 从需要上传的具体表中提取数据
                        List<Map<String, Object>> sourceDatas = uploadService.getSourceData(srcTabName);
                        log.info("准备上传[src_tab_name=" + srcTabName + ",总记录数=" + sourceDatas.size() + "]");
                        for (Map<String, Object> sourceData : sourceDatas) {
                            long synReqId = (Long) sourceData.get("syn_req_id");
                            long startTime = System.currentTimeMillis();
                            log.info("开始上传[src_tab_name=" + srcTabName + ",syn_req_id=" + synReqId + "]");

                            // 接口方式与数据表方式
                            if ("interface".equalsIgnoreCase(synMode)) {
                                uploadInterfaceMode(DataUploadNew.accessToken, taskId, srcTabName, row, sourceData);
                            } else {
                                // token,记录表id,数据源表，记录表中记录，需同步的数据
                                uploadTableMode(DataUploadNew.accessToken, taskId, srcTabName, row, sourceData);
                            }
                            log.info("结束上传[src_tab_name=" + srcTabName + ",syn_req_id=" + synReqId + ",用时="
                                    + (System.currentTimeMillis() - startTime) + "毫秒]");
                        }
                    } catch (Exception ex) {
                        log.info("执行上传任务[ " + (String) row.get("src_tab_name") + " " + taskId + "]发生错误", ex);
                    } finally {
                        synchronized (map) {
                            map.put(taskId, Boolean.FALSE);
                        }
                    }
                }
            };
            (new Thread(runnable)).start();
        }
    }

    private Map<String, Object> genDataMap(String keyList, Map<String, Object> sourceData) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        String[] keys = keyList.split("\\Q,\\E");
        for (String key : keys) {
            Object value = sourceData.get(key.trim());
            paramMap.put(DataUtil.fromDbName2ServiceName(key.trim()), value);
        }

        return paramMap;
    }


    private void uploadInterfaceMode(String accessToken, int taskId, String srcTabName, Map<String, Object> row,
                                     Map<String, Object> sourceData) throws Exception {

        long synReqId = (Long) sourceData.get("syn_req_id");
        Integer synTimes = (Integer) sourceData.get("syn_times");
        Integer segFlag = (Integer) row.get("seq_flag");
        String interfaceUrl = (String) row.get("dest_tab_name");
        String insCoList = (String) row.get("ins_col_list");

        try {
            JSONObject jsonResult = HttpUtil.httpRequestGetPgidt(interfaceUrl, "POST", accessToken, Long.toString(synReqId),
                    JSON.toJSONStringWithDateFormat(genDataMap(insCoList, sourceData), "yyyy-MM-dd HH:mm:ss"));

            String statusCode = jsonResult.getString("status");
            if ("200".equals(statusCode)) {
                uploadService.updateSuccess(srcTabName, synReqId);
            } else {
                String errorMessage = jsonResult.getString("message");
                if (errorMessage == null || errorMessage.trim().length() == 0) {
                    errorMessage = "失败";
                }
                throw new Exception(errorMessage);
            }
        } catch (Exception ex) {
            log.error("执行上传任务[ "+srcTabName+" taskId=" + taskId + ",syn_req_id=" + synReqId + ",seqFlag=" + segFlag + "]发生错误:"
                    + ex.getMessage());
            try {
                String errMessage = ex.getMessage();
                if (errMessage == null || errMessage.trim().length() == 0) {
                    errMessage = ex.getClass().getName();
                }
                commonService.updateError(srcTabName, synReqId, synTimes, errMessage);
            } catch (Exception e) {
                log.error("发生错误", e);
            }
            if (segFlag == 1) {
                throw ex;
            }
        }
    }

    // token,记录表id,数据源表，记录表中记录，需同步的数据
    private void uploadTableMode(String accessToken, int taskId, String srcTabName, Map<String, Object> row,
                                 Map<String, Object> sourceData) throws Exception {

        long synReqId = (Long) sourceData.get("syn_req_id");
        Integer synTimes = (Integer) sourceData.get("syn_times");

        String desTabName = (String) row.get("dest_tab_name");
        String insCoList = (String) row.get("ins_col_list");
        String updColList = (String) row.get("upd_col_list");
        String keyList = (String) row.get("key_list");
        Integer segFlag = (Integer) row.get("seq_flag");

        String serviceName = DataUtil.fromDbName2ServiceName(desTabName);
        String isNewDataUrl = baseurl + serviceName + "/isNewData";
        String addDataUrl = baseurl + serviceName + "/add";
        String updateUrl = baseurl + serviceName + "/update";
        String queryUrl = baseurl + serviceName + "/querylist";

        try {
            JSONResult jsonResult = HttpUtil.httpRequestWithTokenT(isNewDataUrl, "POST",
                    JSON.toJSONStringWithDateFormat(genDataMap(keyList, sourceData), "yyyy-MM-dd HH:mm:ss"), accessToken);
            if (jsonResult.isOK()) {
                // 总部有数据进行修改
                if (!jsonResult.getData().equals("")) {
                    // 未设置更新的列时表示不更新
                    if (updColList == null || updColList.trim().length() == 0) {
                        uploadService.updateSuccess(srcTabName, synReqId);
                    } else {
                        // 组装列参数，进行修改
                        JSONResult updateResult = HttpUtil.httpRequestWithTokenT(updateUrl, "POST", JSON
                                        .toJSONStringWithDateFormat(genDataMap(updColList, sourceData), "yyyy-MM-dd HH:mm:ss"),
                                accessToken);
                        if (updateResult.isOK()) {
                            uploadService.updateSuccess(srcTabName, synReqId);
                        } else {
                            uploadService.updateError(srcTabName, synReqId, updateResult.getMsg());
                            throw new Exception("更新数据失败[" + synReqId + "],[" + updateResult.getMsg() + "]");
                        }
                    }
                } else {
                    // 总部无数据进行新增
                    JSONResult addResult = HttpUtil.httpRequestWithTokenT(addDataUrl, "POST",
                            JSON.toJSONStringWithDateFormat(genDataMap(insCoList, sourceData), "yyyy-MM-dd HH:mm:ss"),
                            accessToken);
                    if (addResult.isOK()) {
                        uploadService.updateSuccess(srcTabName, synReqId);
                    } else {
                        throw new Exception("新增数据失败[" + synReqId + "],[" + addResult.getMsg() + "]");
                    }
                }
            } else {
                throw new Exception("检查是否新增失败[" + synReqId + "],[" + jsonResult.getMsg() + "]");
            }
        } catch (Exception ex) {
            log.error("执行上传任务[ "+srcTabName+" taskId=" + taskId + ",syn_req_id=" + synReqId + ",seqFlag=" + segFlag + "]发生错误:"
                    + ex.getMessage());
            try {
                String errMessage = ex.getMessage();
                if (errMessage == null || errMessage.trim().length() == 0) {
                    errMessage = ex.getClass().getName();
                }
                commonService.updateError(srcTabName, synReqId, synTimes, errMessage);
            } catch (Exception e) {
                log.error("发生错误", e);
            }
            if (segFlag == 1) {
                throw ex;
            }
        }
    }

    private String getAccessToken() throws Exception {
        String redisKey = Constant.RedisPrefix.TOKEN_GREE_UPLOAD;
        DataUploadNew.accessToken = (String)redis.get(redisKey);
        if(StringUtil.isEmpty(DataUploadNew.accessToken)){
            DataUploadNew.accessToken = tokenCenter.getCurrentToken().getAccessToken();
            //写入缓存
            redis.set(Constant.RedisPrefix.TOKEN_GREE_UPLOAD, DataUploadNew.accessToken,5 * 60);
        }
        return DataUploadNew.accessToken;
    }*/
}
