package com.zfire.jiasm.syncdata.upload.order;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zfire.jiasm.syncdata.constant.TaskConfigEnum;
import com.zfire.jiasm.syncdata.data.Token;
import com.zfire.jiasm.syncdata.plus.entity.OutJiasmToGreeSynRule;
import com.zfire.jiasm.syncdata.service.CommonService;
import com.zfire.jiasm.syncdata.service.PublicService;
import com.zfire.jiasm.syncdata.service.UploadService;
import com.zfire.jiasm.syncdata.utils.DataUtil;
import com.zfire.jiasm.syncdata.utils.HttpUtil;
import com.zfire.jiasm.syncdata.utils.JSONResult;
import com.zfire.jiasm.syncdata.utils.TokenCenter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 工单数据同步到格力总部
 * 1:需要生成上传任务清单列表   ProduceUploadList处理
 * 2:生成需要上传的数据   ProduceDataUploadList处理
 *
 * out_jiasm_to_gree_syn_rule 数据同步记录表提取数据
 * 根据源数据表名提取对应的数据
 * 组装参数进行数据同步
 * 修改同步表的同步状态
 */
@Slf4j
@Component
public class DataUpload {
    @Value("${baseurl}")
    private String baseurl;
    @Value("${datauploadc}")
    private String datauploadc = "";

    @Autowired
    private TokenCenter tokenCenter;
    @Resource
    private UploadService uploadService;
    @Autowired
    private CommonService commonService;
    @Resource
    private PublicService publicService;
    private Map<Integer, Boolean> map = new ConcurrentHashMap<Integer, Boolean>();




    @Scheduled(fixedDelayString = "${dataupload}")
    public void uploadProcess() throws Exception {
        if (datauploadc.equals(TaskConfigEnum.FALSE.getCode())){
            return;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<OutJiasmToGreeSynRule> synRules = new ArrayList<>();

        // 数据同步规则记录表中提取数据 out_jiasm_to_gree_syn_rule
        List<Map<String, Object>> result = uploadService.getTaskData();
        Token token = tokenCenter.getCurrentToken();

        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();

                            // 查看该网点数据是否需要回传，不需要回传时直接修改同步状态将不再回传
                            // 工单号，名表，记录ID
                            if (publicService.checkWebsitSyncFlag((String) sourceData.get("worker_order_no"),srcTabName,synReqId)){
                                continue;
                            }

                            log.info("开始上传[src_tab_name=" + srcTabName + ",syn_req_id=" + synReqId + "]");
                            // 接口方式与数据表方式
                            if ("interface".equalsIgnoreCase(synMode)) {
                                uploadInterfaceMode(token, taskId, srcTabName, row, sourceData);
                            } else {
                                // token,记录表id,数据源表，记录表中记录，需同步的数据
                                uploadTableMode(token, taskId, srcTabName, row, sourceData);
                            }
                            log.info("结束上传[src_tab_name=" + srcTabName + ",syn_req_id=" + synReqId + ",用时="
                                    + (System.currentTimeMillis() - startTime) + "毫秒]");
                        }
                    } catch (Exception ex) {
                        log.info("执行上传任务[" + 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(Token token, 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.httpRequestGetPgid(interfaceUrl, "POST", token, 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(Token token, 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.httpRequestWithToken(isNewDataUrl, "POST",
                    JSON.toJSONStringWithDateFormat(genDataMap(keyList, sourceData), "yyyy-MM-dd HH:mm:ss"), token);
            if (jsonResult.isOK()) {
                // 总部有数据进行修改
                if (!jsonResult.getData().equals("")) {
                    // 未设置更新的列时表示不更新
                    if (updColList == null || updColList.trim().length() == 0) {
                        uploadService.updateSuccess(srcTabName, synReqId);
                    } else {
                        // 组装列参数，进行修改
                        JSONResult updateResult = HttpUtil.httpRequestWithToken(updateUrl, "POST", JSON
                                        .toJSONStringWithDateFormat(genDataMap(updColList, sourceData), "yyyy-MM-dd HH:mm:ss"),
                                token);
                        if (updateResult.isOK()) {
                            uploadService.updateSuccess(srcTabName, synReqId);
                        } else {
                            uploadService.updateError(srcTabName, synReqId, updateResult.getMsg());
                            throw new Exception("更新数据失败[" + synReqId + "],[" + updateResult.getMsg() + "]");
                        }
                    }
                } else {
                    // 总部无数据进行新增
                    JSONResult addResult = HttpUtil.httpRequestWithToken(addDataUrl, "POST",
                            JSON.toJSONStringWithDateFormat(genDataMap(insCoList, sourceData), "yyyy-MM-dd HH:mm:ss"),
                            token);
                    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;
            }
        }
    }
}
