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.amqp.rabbit.RabbitGdActQueueMQ;
import com.kxs.product.api.model.KxsGdOrder;
import com.kxs.product.api.model.KxsGdReport;
import com.kxs.product.api.req.gd.GdCommonReq;
import com.kxs.product.api.req.gd.GdQueryCardOrderReq;
import com.kxs.product.api.req.gd.GdSimOrderReq;
import com.kxs.product.api.res.gd.GdCommRes;
import com.kxs.product.api.res.gd.GdQueryOrderRes;
import com.kxs.product.api.res.gd.GdSimOrderRes;
import com.kxs.product.biz.config.RsaProperties;
import com.kxs.product.biz.constant.enums.GdReportEnum;
import com.kxs.product.biz.mapper.KxsGdOrderMapper;
import com.kxs.product.biz.mapper.KxsGdReportMapper;
import com.kxs.product.biz.service.KxsGdOrderService;
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 org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 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 {
            GdQueryCardOrderReq req = GdQueryCardOrderReq.builder()
                    .queryBeginTime(startTime)
                    .queryEndTime(endTime)
                    .pageNo(String.valueOf(pageNo))
                    .pageSize(String.valueOf(pageSize)).build();
            String response = sendToGd(rsaProperties.getGd().getUrl() + "/ycsim-business/openapi/query_card_order_info", req);
            GdCommRes<GdQueryOrderRes> commRes = JSONUtil.toBean(response, new TypeReference<>() {}, true);
            if(commRes.getResultCode() != 1){
                throw new GlobalCustomerException(commRes.getErrorDesc());
            }
            List<GdQueryOrderRes.GdQueryOrder> list = commRes.getData().getRecords();
            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 List<GdSimOrderRes> onlineSimOrder(List<String> orderNos) {
        GdSimOrderReq req = GdSimOrderReq.builder()
                .orderNos(JSON.toJSONString(orderNos))
                .build();
        String response = sendToGd(rsaProperties.getGd().getDqUrl() + "/ycsim-agent-service/openapi/online_sim_order/get_order_info", req);
        GdCommRes<List<GdSimOrderRes>> commRes = JSONUtil.toBean(response, new TypeReference<GdCommRes<List<GdSimOrderRes>>>() {}, true);
        if(commRes.getResultCode() != 1){
            throw new GlobalCustomerException(commRes.getErrorDesc());
        }
        return commRes.getData();

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONArray acceptGdActData(Map<String, Object> param) {

        JSONArray dataList = JSON.parseArray(param.get("data").toString());
        if(dataList.isEmpty()){
            log.error("接收广电订单数据失败:{}", JSON.toJSONString(param));
            throw new GlobalCustomerException("接收广电订单数据失败" + JSON.toJSONString(param));
        }
        try {
            boolean checkSign = GdRsaUtils.checkSign(param, rsaProperties.getGd().getPublicKey());
            if(!checkSign) {
                throw new GlobalCustomerException("广电接收激活数据验证签名失败");
            }
        } catch (Exception e) {
            throw new GlobalCustomerException("广电接收激活数据验证签名失败");
        }

        return dataList;
    }


    @Override
    public void toSendMq(KxsGdOrder order, String sn){
        RabbitGdActQueueMQ.MsgEntity msgEntity = new RabbitGdActQueueMQ.MsgEntity();
        msgEntity.setPosSn(sn);
        msgEntity.setPhoneNo(order.getGdMobile());
        msgEntity.setProductName(order.getProductName());
        msgEntity.setActivationStatusName("已激活");
        msgEntity.setPromotionName(order.getProductName());
        msgEntity.setProvince(order.getProvince());
        msgEntity.setCity(order.getCity());
        msgEntity.setInitialChargeAmount(order.getFirstRechargeAmount());
        msgEntity.setOrderCreateTime(LocalDateTimeUtil.format(order.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN));
        msgEntity.setActivationTime(LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.NORM_DATETIME_PATTERN));

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

        log.info("发送电渠广电激活数据{}", sn
                + "," + order.getGdMobile());
    }

    private  String sendToGd(String url, GdCommonReq req){
        try {

            long timestamp = System.currentTimeMillis() / 1000;
            req.setTimestamp(timestamp);
            req.setBrhNo(rsaProperties.getGd().getBrhNo());

            String sign = GdRsaUtils.rsa256Sign(BeanUtil.beanToMap(req), rsaProperties.getGd().getPrivateKey());
            req.setSign(sign);
            String body = JSON.toJSONString(req);
            String response = HttpRequest.post(url)
                    .header(Header.CONTENT_TYPE, "application/json")
                    .body(body)
                    .timeout(50000)//超时，毫秒
                    .execute().body();
            if (response == null || !JSONUtil.isTypeJSON(response)) {
                log.error("响应报文非有效格式{}", response);
                throw new GlobalCustomerException("广电响应报文非有效格式");
            }

            return response;

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

}
