package com.czg.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.PayCst;
import com.czg.PolyPayUtils;
import com.czg.constant.PayChannelCst;
import com.czg.constants.PayTypeConstants;
import com.czg.dto.req.WechatNotifyReqDto;
import com.czg.dto.req.WechatPayNotifyDataDto;
import com.czg.entity.PolyBaseResp;
import com.czg.exception.CzgException;
import com.czg.market.entity.MkShopConsumeDiscountRecord;
import com.czg.market.service.MkDistributionUserService;
import com.czg.market.service.MkShopConsumeDiscountRecordService;
import com.czg.market.service.OrderInfoService;
import com.czg.order.entity.OrderInfo;
import com.czg.order.entity.OrderPayment;
import com.czg.order.service.OrderInfoCustomService;
import com.czg.order.service.OrderPaymentService;
import com.czg.pay.PayNotifyRespDTO;
import com.czg.service.market.service.impl.AppWxServiceImpl;
import com.czg.third.wechat.WechatReqUtils;
import com.czg.utils.AssertUtil;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

/**
 * 回调
 *
 * @author ww
 */
@Slf4j
@RestController
@RequestMapping("/notify")
public class NotifyController {
    private static final String SUCCESS = "SUCCESS";
    @Resource
    private OrderInfoCustomService orderInfoCustomService;
    @Resource
    private OrderInfoService orderInfoService;
    @Resource
    private AppWxServiceImpl wxService;
    @Resource
    private MkDistributionUserService distributionUserService;
    @Resource
    private OrderPaymentService paymentService;
    @Resource
    private MkShopConsumeDiscountRecordService consumeDiscountRecordService;


    //新客立减清除数据 测试用
    @RequestMapping("clear")
    public String clear(@RequestParam Integer shopId) {
        consumeDiscountRecordService.remove(new QueryWrapper().eq(MkShopConsumeDiscountRecord::getShopId, shopId));
        orderInfoService.remove(new QueryWrapper().eq(OrderInfo::getShopId, shopId));
        return "success";
    }

    /**
     * 原生支付回调
     */
    @RequestMapping("/native/pay/{platform}")
    public String pay(@PathVariable String platform, @RequestBody JSONObject json) {
        if (PayCst.Type.WECHAT.equalsIgnoreCase(platform)) {
            // 微信
            WechatNotifyReqDto reqDto = JSONObject.parseObject(json.toJSONString(), WechatNotifyReqDto.class);
            log.info("【微信支付回调】收到微信支付回调 data: {}", JSONObject.toJSONString(reqDto));

            String decrypted = WechatReqUtils.decryptRespParam(null, reqDto);
            log.info("【微信支付回调】解密数据 {}", decrypted);

            WechatPayNotifyDataDto dataDto = JSONObject.parseObject(decrypted, WechatPayNotifyDataDto.class);
            PayNotifyRespDTO respDTO = dataDto.convertToPayNotifyRespDTO();
            orderInfoCustomService.payCallBackOrder(respDTO.getMchOrderNo(), respDTO, PayChannelCst.NATIVE, 0);
            return "success";
        } else if (PayCst.Type.ALIPAY.equalsIgnoreCase(platform)) {
            // 支付宝
            return "success";
        }
        throw new CzgException("不支持的支付平台");
    }

    /**
     * 原生退款回调
     */
    @RequestMapping("/native/refund/{platform}")
    public String refund(@PathVariable String platform, @RequestBody JSONObject json) {
        if (PayCst.Type.WECHAT.equalsIgnoreCase(platform)) {
            // 微信
            WechatNotifyReqDto reqDto = JSONObject.parseObject(json.toJSONString(), WechatNotifyReqDto.class);
            log.info("【微信退款回调】收到微信退款回调 data: {}", JSONObject.toJSONString(reqDto));
            String decrypted = WechatReqUtils.decryptRespParam(null, reqDto);
            log.info("【微信退款回调】解密数据 {}", decrypted);

            return "success";
        } else if (PayCst.Type.ALIPAY.equalsIgnoreCase(platform)) {
            // 支付宝
            return "success";
        }
        throw new CzgException("不支持的支付平台");
    }


    @RequestMapping("/payCallBack")
    public String notifyCallBack(@RequestBody PolyBaseResp respParams) {
        PayNotifyRespDTO respDTO = PolyPayUtils.getNotifyResp(respParams);
        AssertUtil.isNull(respDTO, "支付回调数据为空");
        log.info("支付回调数据为:{}", respDTO);
        orderInfoCustomService.payCallBackOrder(respDTO.getMchOrderNo(), respDTO, PayChannelCst.POLY, 0);
        return SUCCESS;
    }


    @RequestMapping("/native/wx/transfer")
    public String nativeTransferNotify(HttpServletRequest request) {
        log.info("接收到微信转账回调");
        JSONObject jsonObject = wxService.verifySignature(request);
        log.info("参数信息: {}", jsonObject.toJSONString());
        String outBillNo = jsonObject.getString("out_bill_no");
        String state = jsonObject.getString("state");
        String failReason = jsonObject.getString("fail_reason");
        try {
            distributionUserService.withdrawNotify(outBillNo, state, failReason);
        } catch (Exception e) {
            log.warn("转账回调失败", e);
        }
        return SUCCESS;
    }


    /**
     * 微信原生支付回调
     */
    @RequestMapping("/native/wx/pay/distributionRecharge")
    public String nativeNotify(HttpServletRequest request) throws IOException {
//        String timestamp = request.getHeader("Wechatpay-Timestamp");
//        String nonce = request.getHeader("Wechatpay-Nonce");
//        String serialNo = request.getHeader("Wechatpay-Serial");
//        String signature = request.getHeader("Wechatpay-Signature");
        String result = IoUtil.readUtf8(request.getInputStream());
        JSONObject jsonObject = JSONObject.parseObject(result);
        JSONObject resource = jsonObject.getJSONObject("resource");
        String associatedData = resource.getString("associated_data");
        String ciphertext = resource.getString("ciphertext");
        String nonceStr = resource.getString("nonce");

        String plainText = wxService.decryptToString(associatedData, nonceStr, ciphertext);
        log.info("充值支付通知明文 {}", plainText);

        JSONObject plainTextJson = JSONObject.parseObject(plainText);
        String outTradeNo = plainTextJson.getString("out_trade_no");
        String tradeState = plainTextJson.getString("trade_state");
        String transactionId = plainTextJson.getString("transaction_id");
        OrderPayment payment = paymentService.getOne(new QueryWrapper().eq(OrderPayment::getOrderNo, outTradeNo));
        payment.setPayStatus(PayTypeConstants.PayStatus.FAIL);
        if ("SUCCESS".equals(tradeState)) {
            try {
                payment.setTradeNumber(transactionId);
                payment.setPayTime(DateUtil.date().toLocalDateTime());
                payment.setRespJson(plainTextJson.toJSONString());
                payment.setPayStatus(PayTypeConstants.PayStatus.SUCCESS);
                distributionUserService.rechargeCallBack(payment.getShopId(), payment.getAmount(), payment.getId());
            } catch (Exception e) {
                log.error("充值回调失败", e);
                return "SUCCESS";
            }
        }
        paymentService.updateById(payment);
        return SUCCESS;
    }


    @RequestMapping("/refundCallBack")
    public String refundCallBack(@RequestBody PolyBaseResp respParams) {
        JSONObject czg = PolyPayUtils.getCzg(respParams);
        AssertUtil.isNull(czg, "退款回调数据为空");
        log.info("退款回调数据为:{}", czg);
        orderInfoCustomService.refundCallBackOrder(czg.getString("mchOrderNo"), czg);
        return SUCCESS;
    }
}
