package com.zfire.jiasm.syncdata.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.zfire.jiasm.syncdata.constant.GDAppointStatusEnum;
import com.zfire.jiasm.syncdata.constant.GDOrderStatusEnum;
import com.zfire.jiasm.syncdata.constant.OrderTypeEnum;
import com.zfire.jiasm.syncdata.dao.mapper.OrderInformationNewMapper;
import com.zfire.jiasm.syncdata.data.Token;
import com.zfire.jiasm.syncdata.parameter.OrderPar;
import com.zfire.jiasm.syncdata.plus.entity.*;
import com.zfire.jiasm.syncdata.plus.service.*;
import com.zfire.jiasm.syncdata.response.WebsitFWS;
import com.zfire.jiasm.syncdata.service.PrepareService;
import com.zfire.jiasm.syncdata.service.PublicService;
import com.zfire.jiasm.syncdata.service.RepairProduceUploadListService;
import com.zfire.jiasm.syncdata.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
public class RepairProduceUploadListServiceImpl implements RepairProduceUploadListService {
    @Value("${baseurl}")
    private String baseurl = "";

    @Autowired
    private TokenCenter tokenCenter;
    @Resource
    PrepareService prepareService;
    @Resource
    OutJiasmToGreeUploadTaskListService outJiasmToGreeUploadTaskListService;
    @Resource
    OrderBaseService orderBaseService;
    @Resource
    OutJiasmToGreeUploadnotifylistService outJiasmToGreeUploadnotifylistService;
    @Resource
    PublicService publicService;
    @Resource
    OrderProductService orderProductService;
    @Resource
    OrderRepairOperatingLogService orderRepairOperatingLogService;
    @Resource
    OrderInformationService orderInformationService;
    @Resource
    OrderInformationNewMapper orderInformationNewMapper;
    @Resource
    ItfTblAssignXzydUploadService itfTblAssignXzydUploadService;
    @Resource
    OrderReAppointmentService orderReAppointmentService;
    @Resource
    TestService testService;




    @Override
    public void processproduceList() throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<OutJiasmToGreeUploadTaskList> ojtgutls = new ArrayList<>();

        log.info("开始预处理需要上传的维修工单数据: \uF0B7{}",sdf.format(new Date()));

        //测试使用
        List<String> orderNos = new ArrayList<>();
        List<Test> orderno = testService.lambdaQuery()
                .eq(Test::getFlag,1).list();
        if (CollectionUtils.isEmpty(orderno)){
            return;
        }
        orderno.stream().forEach(event->{
            orderNos.add(event.getId());
        });
        orderno.clear();


        // 从需要上传的订单数据表中提取数据
        List<OutJiasmToGreeUploadnotifylist> taskResults = outJiasmToGreeUploadnotifylistService.lambdaQuery()
                .eq(OutJiasmToGreeUploadnotifylist::getSynStatus,0)
                // .eq(OutJiasmToGreeUploadnotifylist::getSynReqId,416094L)// 测试用
                .in(OutJiasmToGreeUploadnotifylist::getOrderNo, orderNos)// 测试用
                .orderByAsc(OutJiasmToGreeUploadnotifylist::getSynReqId).list();
        try{
            Token token = tokenCenter.getCurrentToken();

            for (OutJiasmToGreeUploadnotifylist item : taskResults) {
                Long itemSynReqId = item.getSynReqId();
                // 同步的表名
                String itemTableName = item.getTableName();
                // 同步表中的工单号
                String itemOrderNo = item.getOrderNo();
                // 同步表中的主键id
                String itemTableNameId = item.getId();
                // 工单类型
                String itemOrderType = item.getOrderType();

                // 数据同步预处理规则表中提取对应表名的规则
                Map<String, Object> row = prepareService.getTaskInfo(itemTableName);
                int taskId = (Integer) row.get("id");
                String srcTabName = (String) row.get("src_tab_name");

                String errorMessage = null;
                try{
                    // 维修工单主表处理 66、661
                    if (itemTableName.equals("order_base") &&
                            itemOrderType.equals(OrderTypeEnum.ORDER_TYPE_REPAIR.getCode())){
                        // 过程名，源表中的ID，源表中的数据最后修改时间，源表中的工单号，源表中的id,空值，false
                        // TL_PrePare_task_by_fa_order_repair
                        orderBaseProess(itemTableName, itemOrderNo, itemTableNameId, ojtgutls, item.getSynReqId());
                    }
                    // 维修工单产品信息 68
                    if (itemTableName.equals("order_product") &&
                            itemOrderType.equals(OrderTypeEnum.ORDER_TYPE_REPAIR.getCode())){
                        // 过程名，源表中的ID，源表中的数据最后修改时间，源表中的工单号，源表中的id,空值，false
                        // TL_PrePare_task_by_fa_order_repair_product
                        orderProductProess(item, itemTableName, itemOrderNo, itemTableNameId);
                    }
                    // 维修工单操作明细 67
                    if (itemTableName.equals("order_repair_operating_log")){
                        // TL_PrePare_task_by_fa_order_repair_operating_log
                        logProess(item, itemTableName, itemOrderNo, itemTableNameId, itemOrderType);
                    }
                    // 维修单用户预约、改约明细 230 同时向发短信表插入一条数据
                    if (itemTableName.equals("order_re_appointment") &&
                            itemOrderType.equals(OrderTypeEnum.ORDER_TYPE_REPAIR.getCode())){
                        OrderReAppointment(item, itemTableName, itemOrderType);
                    }
                    // 子信息 TL_PrePareSynDataby_fa_order_repair_information
                    if (itemTableName.equals("order_information") &&
                            itemOrderType.equals(OrderTypeEnum.ORDER_TYPE_REPAIR.getCode())){
                        // 执行 TL_get_fa_order_repair_information_pgid 取pgid 从工单主表中看
                        orderInformationProess(token, item, itemOrderNo, itemTableNameId, srcTabName);
                    }
                } catch (Exception ex) {
                    errorMessage = ex.getMessage();
                    updateError(errorMessage, item);
                } finally {
                    PrepareTaskLog.writeMessage(genInfoData(taskId, srcTabName, false, errorMessage));
                }
            }
            log.info("预处理需要上传的维修工单数据完成: \uF0B7{}",sdf.format(new Date()));

        } catch (Exception ex) {
            ex.printStackTrace();
            log.info("开始预处理需要上传的维修工单数据出错");
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public void orderInformationProess(Token token, OutJiasmToGreeUploadnotifylist item, String itemOrderNo,
                                       String itemTableNameId, String srcTabName) throws Exception {
        String newDykh = "";
        // 提取工单数据
        OrderBase orderBase = orderBaseService.lambdaQuery()
                .eq(OrderBase::getId, itemOrderNo)
                .last("limit 1")
                .one();
        // 提取对应的子信息
        OrderInformation oi = orderInformationService.lambdaQuery()
                .eq(OrderInformation::getId, itemTableNameId)
                .last("limit 1")
                .one();
        // 为空不做处理
        if (StringUtils.isNotEmpty(orderBase.getPgid())){
            // 看 xzid 值 不为空取该值 为空时网络获取
            if (oi != null){
                // 获取YDID 表中不存在时从接口中获取
                newDykh = getYdId(token, itemOrderNo, itemTableNameId, srcTabName, orderBase, oi);
                // 修改 xzid 来自接口
                upYdid(itemTableNameId, newDykh);
                // 生成待同步表数据
                getInformation(itemTableNameId);

                // 需要上传的订单数据表中处理状态同步为已处理
                OutJiasmToGreeUploadnotifylist upn = getOutJiasmToGreeUploadnotifylist(item.getSynReqId());
                outJiasmToGreeUploadnotifylistService.updateById(upn);
            }
        }
    }

    private void getInformation(String itemTableNameId) {
        OrderPar orderPar = new OrderPar();
        WebsitFWS websitFWS = new WebsitFWS();
        orderPar.setId(itemTableNameId);
        ItfTblAssignXzydUpload rec = orderInformationNewMapper.getOrderInformationrepair(orderPar);
        if (rec.getYdren().length()>20){
            rec.setYdren(rec.getYdren().substring(0,20));
        }
        if (rec.getYdrmc().length()>120){
            rec.setYdrmc(rec.getYdrmc().substring(0,120));
        }

        OrderBase orderBase = orderBaseService.lambdaQuery()
                .eq(OrderBase::getId,rec.getWorkerOrderNo())
                .last("limit 1")
                .one();
        rec.setPgid(Long.valueOf(orderBase.getPgid()));
        websitFWS = publicService.shshwdToptshwd(rec.getWdno(),orderBase);
        if (StringUtils.isEmpty(websitFWS.getWebsitId())){
            websitFWS = publicService.shxswdToptxswd(rec.getWdno(),orderBase);
        }

        rec.setWdno(websitFWS.getWebsitId());
        itfTblAssignXzydUploadService.save(rec);
    }

    private void upYdid(String itemTableNameId, String newDykh) {
        OrderPar orderPar = new OrderPar();
        orderPar.setId(itemTableNameId);
        orderPar.setXzid(newDykh);
        orderInformationNewMapper.upYdid(orderPar);
    }

    private String getYdId(Token token, String itemOrderNo, String itemTableNameId, String srcTabName,
                           OrderBase orderBase, OrderInformation oi) throws Exception {
        String newDykh;
        if (oi.getXzid()>0){
            // 表中获取
            newDykh = String.valueOf(oi.getXzid());
        } else {
            // 网络获取
            newDykh = getWebAcquire(token, itemOrderNo, itemTableNameId, srcTabName, orderBase);
        }
        return newDykh;
    }

    private String getWebAcquire(Token token, String itemOrderNo, String itemTableNameId, String srcTabName, OrderBase orderBase) throws Exception {
        String newDykh;
        Map<String, Object> sourceData = prepareService.getTaskDataDetail(srcTabName, itemOrderNo,
                itemTableNameId);
        sourceData.put("pgid", orderBase.getPgid());

        String serviceName = DataUtil.fromDbName2ServiceName("tbl_assign_xzyd");
        String addDataUrl = baseurl + serviceName + "/add";

        JSONResult addResult = HttpUtil.httpRequestWithToken(addDataUrl, "POST",
                JSON.toJSONStringWithDateFormat(
                        genDataMapFromSource("pgid", "pgid", sourceData),
                        "yyyy-MM-dd HH:mm:ss"),
                token);
        if (!addResult.isOK()) {
            throw new Exception("新增数据获取主键失败[" + serviceName + "],[" + addResult.getMsg() + "]");
        } else {
            if (addResult.getData() == null || addResult.getData().equals("")) {
                throw new Exception("新增数据获取主键返回空[" + serviceName + "]");
            } else {
                newDykh = addResult.getData().toString();
            }
        }
        return newDykh;
    }

    private Map<String, Object> genDataMapFromSource(String localKeyList, String serverKeyList,
                                                     Map<String, Object> sourceData) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        String[] localKeys = localKeyList.split("\\Q,\\E");
        String[] serverKeys = serverKeyList.split("\\Q,\\E");
        for (int i = 0; i < localKeys.length; i++) {
            String localKey = localKeys[i];
            String serverKey = serverKeys[i];
            Object value = sourceData.get(localKey.trim());
            paramMap.put(DataUtil.fromDbName2ServiceName(serverKey.trim()), value);
        }

        return paramMap;
    }

    @Transactional(rollbackFor = Exception.class)
    public void logProess(OutJiasmToGreeUploadnotifylist item, String itemTableName, String itemOrderNo, String itemTableNameId,String itemOrderType) {
        // 提取日志数据
        OrderRepairOperatingLog org = orderRepairOperatingLogService.lambdaQuery()
                .eq(OrderRepairOperatingLog::getId, itemTableNameId)
                .last("limit 1")
                .one();
        if (org !=null){
            // 生成67类型上传任务数据
            // 单号，主键，同步任务生成时间，同步的表名，工单类型，任务类型
            OutJiasmToGreeUploadTaskList add = publicService.getUploadTaskListLog(itemOrderNo, itemTableNameId,org.getUpdateTime(), itemTableName,
                    itemOrderType,67);
            outJiasmToGreeUploadTaskListService.save(add);

            // 需要上传的订单数据表中处理状态同步为已处理
            OutJiasmToGreeUploadnotifylist upn = getOutJiasmToGreeUploadnotifylist(item.getSynReqId());
            outJiasmToGreeUploadnotifylistService.updateById(upn);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public  void OrderReAppointment(OutJiasmToGreeUploadnotifylist item, String itemTableName, String itemOrderType) {
        OrderReAppointment rea = orderReAppointmentService.lambdaQuery()
                .eq(OrderReAppointment::getId, item.getId())
                .last("limit 1")
                .one();
        // 同步任务增加一条数据
        if (rea !=null){
            OutJiasmToGreeUploadTaskList add = publicService.getUploadTaskList(item.getOrderNo(), item.getId(),
                    rea.getCreateTime(), itemTableName, itemOrderType, 230);
            outJiasmToGreeUploadTaskListService.save(add);

            // 向发短信表插入一条数据，短信表ID同预约改约表ID相同 .addFaOrderSms(
            // publicService.addFaOrderSms(rea);
        }

        // 需要上传的订单数据表中处理状态同步为已处理
        OutJiasmToGreeUploadnotifylist up = getOutJiasmToGreeUploadnotifylist(item.getSynReqId());
        outJiasmToGreeUploadnotifylistService.updateById(up);
    }

    @Transactional(rollbackFor = Exception.class)
    public void orderProductProess(OutJiasmToGreeUploadnotifylist item, String itemTableName, String itemOrderNo, String itemTableNameId) {
        // 提取工单机型
        OrderProduct op = orderProductService.lambdaQuery()
                .eq(OrderProduct::getId, itemTableNameId)
                .last("limit 1")
                .one();
        if (op!=null){
            // 生成68类型上传任务数据
            // 单号，主键，同步任务生成时间，同步的表名，工单类型，任务类型
            OutJiasmToGreeUploadTaskList add = publicService.getUploadTaskList(itemOrderNo, itemTableNameId,op.getUpdateTime(), itemTableName,
                    OrderTypeEnum.ORDER_TYPE_REPAIR.getCode(),68);
            outJiasmToGreeUploadTaskListService.save(add);

            // 需要上传的订单数据表中处理状态同步为已处理
            OutJiasmToGreeUploadnotifylist upn = getOutJiasmToGreeUploadnotifylist(item.getSynReqId());
            outJiasmToGreeUploadnotifylistService.updateById(upn);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void orderBaseProess(String itemTableName, String itemOrderNo, String itemTableNameId,
                                List<OutJiasmToGreeUploadTaskList> ojtgutls, Long synReqId) {
        // 提取工单数据
        OrderBase orderBase = orderBaseService.lambdaQuery()
                .eq(OrderBase::getId, itemOrderNo)
                .last("limit 1")
                .one();
        // 生成任务清单数据
        if (orderBase != null){
            // 删除工单更新被忽略

            // 生成66类型上传任务数据
            // 单号，主键，同步任务生成时间，同步的表名，工单类型，任务类型
            OutJiasmToGreeUploadTaskList add = publicService.getUploadTaskList(itemOrderNo, itemTableNameId,
                    orderBase.getUpdateTime(), itemTableName,orderBase.getOrderType(),66);
            ojtgutls.add(add);

            // 生成661类型上传任务数据
            OrderBase up = generateTaskList(itemTableName, itemOrderNo, itemTableNameId, orderBase, ojtgutls);

            if (ojtgutls.size()>0){
                outJiasmToGreeUploadTaskListService.saveBatch(ojtgutls);
                ojtgutls.clear();
            }
            if (up !=null ){
                orderBaseService.updateById(up);
                orderBase.setOutCjDownloadFlag(1);
            }

            // 需要上传的订单数据表中处理状态同步为已处理
            OutJiasmToGreeUploadnotifylist upn = getOutJiasmToGreeUploadnotifylist(synReqId);
            outJiasmToGreeUploadnotifylistService.updateById(upn);

        }
    }

    @NotNull
    private OutJiasmToGreeUploadnotifylist getOutJiasmToGreeUploadnotifylist(Long synReqId) {
        OutJiasmToGreeUploadnotifylist up = new OutJiasmToGreeUploadnotifylist();
        up.setSynReqId(synReqId);
        up.setSynStatus(1);
        up.setSynReqTime(new Date());
        return up;
    }

    private OrderBase generateTaskList(String itemTableName, String itemOrderNo, String itemTableNameId,
                                       OrderBase orderBase, List<OutJiasmToGreeUploadTaskList> ojtgutls) {
        // 工单状态(8, 9, 10, 11, 12, 13, 14) 派工状态:(13, 14, 15) 未下载总部采集数据
        if ((orderBase.getOrderStatus().equals(GDOrderStatusEnum.REPAIR_STATUS_G8.getCode()) ||
                orderBase.getOrderStatus().equals(GDOrderStatusEnum.REPAIR_STATUS_G9.getCode()) ||
                orderBase.getOrderStatus().equals(GDOrderStatusEnum.REPAIR_STATUS_G10.getCode()) ||
                orderBase.getOrderStatus().equals(GDOrderStatusEnum.REPAIR_STATUS_G11.getCode()) ||
                orderBase.getOrderStatus().equals(GDOrderStatusEnum.REPAIR_STATUS_G12.getCode())||
                orderBase.getOrderStatus().equals(GDOrderStatusEnum.REPAIR_STATUS_G13.getCode())||
                orderBase.getOrderStatus().equals(GDOrderStatusEnum.REPAIR_STATUS_G14.getCode())) &&
                (orderBase.getDispatchStatus().equals(GDAppointStatusEnum.REPAIR_STATUS_G13.getCode()) ||
                        orderBase.getDispatchStatus().equals(GDAppointStatusEnum.REPAIR_STATUS_G14.getCode())||
                        orderBase.getOrderStatus().equals(GDOrderStatusEnum.REPAIR_STATUS_G14.getCode())) &&
                orderBase.getOutCjDownloadFlag().equals(0)){
            OutJiasmToGreeUploadTaskList add = publicService.getUploadTaskList(itemOrderNo, itemTableNameId, itemTableName,
                    orderBase.getOrderType(),661);
            ojtgutls.add(add);
            OrderBase up = new OrderBase();
            up.setId(orderBase.getId());
            up.setOutCjDownloadFlag(1);
            return up;
        }
        return null;
    }

    public void updateError(String errMessage, OutJiasmToGreeUploadnotifylist item) {
        if (errMessage != null && errMessage.trim().length() > 255) {
            errMessage = errMessage.substring(0, 255);
        }
        OutJiasmToGreeUploadnotifylist up = new OutJiasmToGreeUploadnotifylist();
        up.setSynReqId(item.getSynReqId());
        up.setSynTimes(item.getSynTimes()+1);
        up.setSynErrMsg(errMessage);
        up.setSynReqTime(new Date());
        outJiasmToGreeUploadnotifylistService.updateById(up);
    }

    private String genInfoData(int taskId, String srcTabName, boolean isTimeOut, String errorMessage) {
        String result = "预处理任务[" + taskId + "," + srcTabName + "] " + (isTimeOut ? "超时!!!!" : "正常") + " "
                + (errorMessage != null ? "错误:[" + errorMessage + "]" : "");
        return result;
    }

}
