package com.pj.task;

import cn.hutool.core.util.StrUtil;
import cn.hutool.log.StaticLog;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pj.api.consts.FeignFactory;
import com.pj.api.dto.*;
import com.pj.common.core.exception.ServiceException;
import com.pj.dto.DataDto;
import com.pj.api.dto.HtGoodsDto;
import com.pj.enummj.FinishStatus;
import com.pj.ht_byte.HtByte;
import com.pj.ht_byte.HtByteMapper;
import com.pj.ht_declare_chargeback.HtDeclareChargeback;
import com.pj.ht_declare_chargeback.HtDeclareChargebackMapper;
import com.pj.ht_import_declare_people.HtImportDeclarePeople;
import com.pj.ht_import_declare_people.HtImportDeclarePeopleMapper;
import com.pj.ht_pass_card_record.HtPassCardRecordMapper;
import com.pj.ht_trade_settlement.HtTradeSettlement;
import com.pj.ht_trade_settlement.HtTradeSettlementMapper;
import com.pj.rabbitmq.RabbitMQ;
import com.pj.utils.ht.AESUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


/**
 * @Author Mechrevo
 * @Date 2023 08 27 09 57
 **/
@Configuration
@EnableScheduling
@Transactional(rollbackFor = Exception.class)
public class HtByteTask {

    /**
     * 航通字节mapper
     */
    @Autowired
    private HtByteMapper htByteMapper;

    /**
     * 交易结算信息
     */
    @Autowired
    private HtImportDeclarePeopleMapper htImportDeclarePeopleMapper;
    /**
     * 放行记录（过卡记录）
     */
    @Autowired
    private HtPassCardRecordMapper htPassCardRecordMapper;
    /**
     * 方法抽取
     */
    @Autowired
    private MethodHtByteTask methodHtByteTask;
    /**
     * 交易结算信息
     */
    @Autowired
    private HtTradeSettlementMapper htTradeSettlementMapper;
    @Autowired
    private HtDeclareChargebackMapper htDeclareChargebackMapper;


    /**
     * 启动定时任务
     * <p>
     * * 报文类型
     * * 001=边民备案
     * * 002=商铺备案
     * * 003=边民互助组备案
     * * 004=边民合作社备案
     * * 005=商品基础信息
     * * 006=交易结算信息
     * * 007=放行记录（过卡记录）
     * * 008=进口申报单
     * * 010=进出口申报单退单
     */
    @Scheduled(cron = "*/9 * * * * ?")  // 测试阶段,每9秒扫描一次
    private void htByteTask() {
        StaticLog.info("----------------航通数据处理定时任务开始----------------------");
        /*  测试mq */
//        OrderDto orderDtoById = levelOneServerInterface.getOrderDtoById(8833342005355478419L);
//        asyncServerInterface.sendLevelOneOrderDto(orderDtoById, DataType.DATA_TYPE_ONE.getCode());
        /*  测试mq */
        //扫描表内是否有待处理任务
        List<HtByte> byteList = htByteMapper.selectList(
                new LambdaQueryWrapper<HtByte>().eq(HtByte::getFinishStatus, FinishStatus.FINISH_STATUS_ZERO.getCode()).orderByAsc(HtByte::getCreateTime));
        //判断是否有任务,没有则返回
        if (byteList.size() == 0) {
            StaticLog.info("\n  ---  暂无待处理任务。" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\n");
            return;
        }
        //执行任务处理流程
        byteList.forEach(item -> {
            //对象转换
            DataDto dataDto = JSONObject.parseObject(item.getBody(), DataDto.class);
            //todo: 届时开启该数据校验
//             amqpTemplateFeign.verifyContent(dataDto);
            //数据解析
            String body = AESUtil.decryptCBC(dataDto.getData(), RabbitMQ.ACC_KEY);
            //数据处理完成状态
            boolean flag = false;
            // 根据类型匹配对象
            switch (dataDto.getDataType()) {
                case "001":
                    //对象转换
                    HtPeopleDto peopleDto = JSONObject.parseObject(body, HtPeopleDto.class);
                    //根据其内的身份证,有则新增,无则修改???
                    flag = FeignFactory.levelOneServerInterface.peopleDto(peopleDto);
                    methodHtByteTask.updateHtByteInfo(flag, item, dataDto);
                    if (!flag) {
                      StaticLog.error("\n边民信息处理失败。 messageId = " + item.getMessageId() + "\n");
                    } else {
                        StaticLog.info("\n边民信息处理成功。 messageId = " + item.getMessageId() + "\n");
                    }
                    break;
                case "002":
                    //商铺备案
                    HtShopDTO shopDto = JSONObject.parseObject(body, HtShopDTO.class);
                    //保存
                    flag = FeignFactory.levelOneServerInterface.shopDto(shopDto);
                    methodHtByteTask.updateHtByteInfo(flag, item, dataDto);
                    if (!flag) {
                        StaticLog.error("\n店铺信息处理失败。 messageId = " + item.getMessageId() + "\n");
                    } else {
                        StaticLog.info("\n店铺信息处理完成。 messageId = " + item.getMessageId() + "\n");
                    }
                    break;
                case "003":
                    //边民互助组备案
                    HtGroupDto groupDto = JSONObject.parseObject(body, HtGroupDto.class);
                    //保存
                    flag = FeignFactory.levelOneServerInterface.groupDto(groupDto);
                    methodHtByteTask.updateHtByteInfo(flag, item, dataDto);
                    if (!flag) {
                        StaticLog.error("\n互助组信息处理失败。 messageId = " + item.getMessageId() + "\n");
                    } else {
                        StaticLog.info("\n互助组信息处理完成。 messageId = " + item.getMessageId() + "\n");
                    }
                    break;
                case "004":
                    //边民合作社备案
                    HtCooperativeDto cooperativeDto = JSONObject.parseObject(body, HtCooperativeDto.class);
                    //保存
                    flag = FeignFactory.levelOneServerInterface.cooperativeDto(cooperativeDto);
                    methodHtByteTask.updateHtByteInfo(flag, item, dataDto);
                    if (!flag) {
                        StaticLog.error("\n边民合作社信息处理失败。 messageId = " + item.getMessageId() + "\n");
                    } else {
                        StaticLog.info("\n边民合作社信息处理完成。 messageId = " + item.getMessageId() + "\n");
                    }
                    break;
                case "005":
                    //商品基础信息
                    HtGoodsDto goodsDto = JSONObject.parseObject(body, HtGoodsDto.class);
                    //保存
                    flag = FeignFactory.levelOneServerInterface.goodsDto(goodsDto);
                    methodHtByteTask.updateHtByteInfo(flag, item, dataDto);
                    if (!flag) {
                        StaticLog.error("\n海关监管商品信息处理失败。 messageId = " + item.getMessageId() + "\n");
                    } else {
                        StaticLog.info("\n海关监管商品信息处理完成。 messageId = " + item.getMessageId() + "\n");
                    }
                    break;
                case "006":
                    //交易结算信息
                    HtTradeSettlement importDeclarePeople = JSONObject.parseObject(body, HtTradeSettlement.class);
                    if (importDeclarePeople == null || !importDeclarePeople.getIEFlag().toLowerCase().contains("i")) {
                        StaticLog.info("出口商品，暂时忽略:{}", body);
                        break;
                    }
                    //购买边民列表
                    List<BordersListDto> bordersLists = JSON.parseArray(importDeclarePeople.getBordersList(), BordersListDto.class);
                    if (bordersLists == null) {
                        StaticLog.error("\n交易结算信息同步处理失败：购买边民列表为空！！！。 messageId = " + item.getMessageId() + "\n");
                        methodHtByteTask.updateHtByteInfo(false, item, dataDto);
                        break;
                    }
                    //边民购买商品列表
                    List<BorderBuyGoodsListDto> buyGoodsList = JSON.parseArray(importDeclarePeople.getBorderBuyGoodsList(), BorderBuyGoodsListDto.class);
                    //商铺卖货物列表
                    List<SellGoodsListDto> sellGoodsList = JSON.parseArray(importDeclarePeople.getSellGoodsList(), SellGoodsListDto.class);
                    //保存航通监听记录
                    TradeSettlementDto tradeSettlementDto = new TradeSettlementDto();
                    BeanUtils.copyProperties(importDeclarePeople,tradeSettlementDto);
                    tradeSettlementDto.setBordersListDtoList(bordersLists);
                    tradeSettlementDto.setBorderBuyGoodsListDtoList(buyGoodsList);
                    tradeSettlementDto.setSellGoodsListDtoList(sellGoodsList);
                    importDeclarePeople.setFinishStatus(FinishStatus.FINISH_STATUS_ZERO.getCode()); // 默认待处理
                    importDeclarePeople.setCreateTime(new Date());
                    flag = FeignFactory.levelOneServerInterface.tradeSettlementDto(tradeSettlementDto);
                    methodHtByteTask.updateHtByteInfo(flag, item, dataDto);
                    if (flag) {
                        StaticLog.info("\n交易结算信息同步处理成功。 messageId = " + item.getMessageId() + "\n");
                    } else {
                        StaticLog.error("\n交易结算信息同步处理失败。 messageId = " + item.getMessageId() + "\n");
                    }
                    break;
                case "007":
                    //放行记录（过卡记录）
                    HtPassCardDTO htPassCardDTO = JSONObject.parseObject(body, HtPassCardDTO.class);
                    //系统接收到航通过卡记录且卡口类型为'3卡'：车辆已出一级市场, 修改相对应的一级市场订单状态
                    if ("3卡".equals(htPassCardDTO.getChannelType())|| StrUtil.contains(htPassCardDTO.getChannelName(),"三卡")) {
                        StaticLog.info("\n3卡放行记录（过卡记录）信息： htPassCardDTO = " + htPassCardDTO.toString() + "\n");
                        flag = FeignFactory.levelOneServerInterface.orderFinish(htPassCardDTO);
                        methodHtByteTask.updateHtByteInfo(flag, item, dataDto);
                        if (flag) {
                            StaticLog.info("\n3卡放行记录（过卡记录）信息同步处理成功。 messageId = " + item.getMessageId() + "\n");
                        } else {
                            StaticLog.error("\n3卡放行记录（过卡记录）信息同步处理失败。 messageId = " + item.getMessageId() + "\n");
                        }
                    }
                    break;
                case "008":
                    //进口申报单
                    HtImportOrderDto importOrderDto = JSONObject.parseObject(body, HtImportOrderDto.class);
                    boolean result = FeignFactory.levelOneServerInterface.importOrderDto(importOrderDto);
                    methodHtByteTask.updateHtByteInfo(result, item, dataDto);
                    if (result) {
                        StaticLog.info("\n进口申报单同步处理成功。 messageId = " + item.getMessageId() + "\n");
                    } else {
                        StaticLog.error("\n进口申报单同步处理失败。 messageId = " + item.getMessageId() + "\n");
                    }
                    break;
                case "009":
                    //进口申报单边民确认
                    HtImportDeclarePeople htImportDeclarePeople = JSONObject.parseObject(body, HtImportDeclarePeople.class);
                    htImportDeclarePeople.setFinishStatus(FinishStatus.FINISH_STATUS_ZERO.getCode());
                    htImportDeclarePeople.setCreateTime(new Date());
                    int insert2 = htImportDeclarePeopleMapper.insert(htImportDeclarePeople);
                    methodHtByteTask.updateHtByteInfo(insert2 == 1, item, dataDto);
                    if (insert2 == 1) {
                        StaticLog.error("\n进口申报单边民确认信息处理成功。 messageId = " + item.getMessageId() + "\n");
                    } else {
                        StaticLog.info("\n进口申报单边民确认信息处理失败。 messageId = " + item.getMessageId() + "\n");
                    }
                    break;
                case "010":
                    //进出口申报单退单
                    HtDeclareChargeback htDeclareChargeback = JSONObject.parseObject(body, HtDeclareChargeback.class);
                    int insert3 = htDeclareChargebackMapper.insert(htDeclareChargeback);

                    //调用银行退款接口-逻辑处理
                    HtDeclareChargebackDto htDeclareChargebackDto = new HtDeclareChargebackDto();
                    BeanUtils.copyProperties(htDeclareChargeback, htDeclareChargebackDto);
                    boolean chargeback = FeignFactory.levelOneServerInterface.chargeback(htDeclareChargebackDto);
                    methodHtByteTask.updateHtByteInfo(chargeback, item, dataDto);
                    if (insert3 == 1) {
                        StaticLog.error("\n进出口申报单退单信息处理成功。 messageId = " + item.getMessageId() + "\n");
                    } else {
                        StaticLog.info("\n进出口申报单退单信息处理失败。 messageId = " + item.getMessageId() + "\n");
                    }
                default:
                    throw new ServiceException("类型错误。");
            }
        });

    }

}
