package com.kxs.product.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kxs.common.core.exception.GlobalCustomerException;
import com.kxs.common.mq.handlers.IMQSender;
import com.kxs.product.api.model.KxsGdReport;
import com.kxs.product.api.req.gd.GdQueryCardOrderReq;
import com.kxs.product.api.res.gd.GdCommRes;
import com.kxs.product.api.res.gd.GdQueryOrderRes;
import com.kxs.product.api.amqp.rabbit.RabbitGdActQueueMQ;
import com.kxs.product.biz.config.RsaProperties;
import com.kxs.product.biz.constant.enums.GdReportEnum;
import com.kxs.product.biz.mapper.KxsGdReportMapper;
import com.kxs.product.biz.service.KxsGdService;
import com.kxs.product.biz.util.GdRsaUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * KXS 广电 服务实现
 *
 * @author 没秃顶的码农
 * @date 2024-04-23
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class KxsGdServiceImpl implements KxsGdService {

    private final RsaProperties rsaProperties;

    private final KxsGdReportMapper kxsGdReportMapper;

    private final IMQSender mqSender;

    @Async("getAsyncExecutor")
    @Override
    public void checkGdAsyncData(String startTime, String endTime) {
        int pageNo = 1;
        int pageSize = 50;

        do {
            List<GdQueryOrderRes.GdQueryOrder> list = this.queryCardOrders(startTime, endTime, pageNo, pageSize);
            if (list.isEmpty()) {
                pageNo = -1;
            } else {
                for (GdQueryOrderRes.GdQueryOrder gdQueryOrder : list) {
                    if ("已激活".equals(gdQueryOrder.getActivationStatusName())) {
                        KxsGdReport kxsGdReport = kxsGdReportMapper.selectOne(Wrappers.<KxsGdReport>lambdaQuery()
                                .eq(KxsGdReport::getIsCheck, GdReportEnum.CHECK_NO.getType())
//                                .eq(KxsGdReport::getGdSn, gdQueryOrder.getIccId())
                                .eq(KxsGdReport::getGdMobile, gdQueryOrder.getPhoneNo()));
                        if (kxsGdReport == null) {
                            continue;
                        }
                        //发送广电激活MQ消息
                        RabbitGdActQueueMQ.MsgEntity msgEntity = new RabbitGdActQueueMQ.MsgEntity();
                        BeanUtil.copyProperties(gdQueryOrder, msgEntity);
                        msgEntity.setPosSn(kxsGdReport.getGdSn());
                        mqSender.send(RabbitGdActQueueMQ.build(msgEntity));

                        kxsGdReportMapper.update(null, Wrappers.<KxsGdReport>lambdaUpdate().eq(KxsGdReport::getId, kxsGdReport.getId())
                                .set(KxsGdReport::getIsCheck, GdReportEnum.CHECK_SUC.getType())
                                .set(KxsGdReport::getGdMobile, gdQueryOrder.getPhoneNo()));
                        log.info("发送广电激活数据{}", kxsGdReport.getGdSn()
                                + "," + kxsGdReport.getGdMobile());
                    }
                }
                pageNo++;
            }
        } while (pageNo != -1);

    }

    @Override
    public void checkGdAsyncData(Map<String, Object> param) {

        JSONArray dataList = JSON.parseArray(param.get("data").toString());
        if(dataList.isEmpty()){
            log.error("接收广电订单数据失败:{}", JSON.toJSONString(param));
            return;
        }
        try {
            boolean checkSign = GdRsaUtils.checkSign(param, rsaProperties.getGd().getPublicKey());
            if(!checkSign) {
                throw new GlobalCustomerException("广电接收激活数据验证签名失败");
            }
        } catch (Exception e) {
            throw new GlobalCustomerException("广电接收激活数据验证签名失败");
        }
        for (Object obj : dataList) {
            JSONObject orderData = JSON.parseObject(obj.toString());
            //订单流转接口，暂不处理
            if (!orderData.containsKey("status") || !orderData.containsKey("mobile")) {
                continue;
            }
            //1 订单生成2 订单正在运行3 待发货4 配送中5 订单成功结束6 已激活成功11 办理失败12 拒签13 订单取消中14 订单取消
            int status = orderData.getInteger("status");
            if(status != 6){
                continue;
            }
            String gdMobile = orderData.getString("mobile");
            if(StrUtil.isBlank(gdMobile)){
                continue;
            }
            KxsGdReport kxsGdReport = kxsGdReportMapper.selectOne(Wrappers.<KxsGdReport>lambdaQuery()
                    .eq(KxsGdReport::getIsCheck, GdReportEnum.CHECK_NO.getType())
                    .eq(KxsGdReport::getGdMobile, gdMobile));
            if (kxsGdReport == null) {
                return;
            }

            RabbitGdActQueueMQ.MsgEntity msgEntity = new RabbitGdActQueueMQ.MsgEntity();
            msgEntity.setPosSn(orderData.getString("iccid"));
            msgEntity.setPhoneNo(orderData.getString("mobile"));
            msgEntity.setProductName(orderData.getString("productName"));
            msgEntity.setActivationStatusName("已激活");
            msgEntity.setPromotionName(orderData.getString("offerName"));
            msgEntity.setProvince(orderData.getString("province"));
            msgEntity.setCity(orderData.getString("city"));
            msgEntity.setOrderCreateTime(orderData.getString("createTime"));
            msgEntity.setActivationTime(LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.NORM_DATETIME_PATTERN));

            mqSender.send(RabbitGdActQueueMQ.build(msgEntity));

            kxsGdReportMapper.update(null, Wrappers.<KxsGdReport>lambdaUpdate().eq(KxsGdReport::getId, kxsGdReport.getId())
                    .set(KxsGdReport::getIsCheck, GdReportEnum.CHECK_SUC.getType())
                    .set(KxsGdReport::getGdMobile, gdMobile));
            log.info("发送电渠广电激活数据{}", kxsGdReport.getGdSn()
                    + "," + kxsGdReport.getGdMobile());
        }
    }


    public List<GdQueryOrderRes.GdQueryOrder> queryCardOrders(String startTime, String endTime, int pageNo, int pageSize) {

        try {
            String url = "https://" + rsaProperties.getGd().getUrl() + "/ycsim-business/openapi/query_card_order_info";

            long timestamp = System.currentTimeMillis() / 1000;

            GdQueryCardOrderReq req = GdQueryCardOrderReq.builder()
                    .queryBeginTime(startTime)
                    .queryEndTime(endTime)
                    .brhNo(rsaProperties.getGd().getBrhNo())
                    .pageNo(String.valueOf(pageNo))
                    .pageSize(String.valueOf(pageSize))
                    .timestamp(String.valueOf(timestamp)).build();
            String sign = GdRsaUtils.rsa256Sign(BeanUtil.beanToMap(req), rsaProperties.getGd().getPrivateKey());
            req.setSign(sign);
            boolean b = GdRsaUtils.checkSign(BeanUtil.beanToMap(req), rsaProperties.getGd().getPublicKey());
            String body = JSONUtil.toJsonStr(req);
            String response = HttpRequest.post(url)
                    .header(Header.CONTENT_TYPE, "application/json")
                    .body(body)
                    .timeout(50000)//超时，毫秒
                    .execute().body();
            Optional.ofNullable(response).orElseThrow(() -> new GlobalCustomerException("调用接口失败"));
            GdCommRes<GdQueryOrderRes> commRes = JSONUtil.toBean(response, new TypeReference<GdCommRes<GdQueryOrderRes>>() {
            }, true);
            if (commRes.getResultCode() == 1) {
                return commRes.getData().getRecords();
            } else {
                throw new GlobalCustomerException(commRes.getErrorDesc());
            }

        } catch (Exception e) {
            log.error("请求广电接口报错:{}", e.getLocalizedMessage());
            throw new GlobalCustomerException(e.getLocalizedMessage());
        }
    }

}
