package com.czg.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.thread.ThreadUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.CzgPayUtils;
import com.czg.entity.CzgBaseRespParams;
import com.czg.market.service.MkDistributionUserService;
import com.czg.market.service.TbMemberConfigService;
import com.czg.mq.PrintMqListener;
import com.czg.order.entity.OrderPayment;
import com.czg.order.service.OrderInfoService;
import com.czg.order.service.OrderPaymentService;
import com.czg.order.service.ShopTableOrderStatisticService;
import com.czg.service.market.service.impl.AppWxServiceImpl;
import com.czg.service.market.service.impl.WxServiceImpl;
import com.czg.task.StatisticTask;
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;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 回调
 * @author ww
 * @description
 */
@Slf4j
@RestController
@RequestMapping("/notify")
public class NotifyController {
    private static final String SUCCESS = "SUCCESS";

    @Resource
    private OrderInfoService orderInfoService;

    @Resource
    private StatisticTask statisticTask;

    @Resource
    private ShopTableOrderStatisticService shopTableOrderStatisticService;
    @Resource
    private AppWxServiceImpl wxService;
    @Resource
    private WxServiceImpl wxService2;
    @Resource
    private MkDistributionUserService distributionUserService;
    @Resource
    private OrderPaymentService paymentService;
    @Resource
    private TbMemberConfigService memberConfigService;


    @GetMapping("testOpen")
    public JSONObject test1(String code) throws Exception {
        JSONObject czg = JSONObject.parseObject("{\"amount\":10,\"cashFee\":0,\"channelSendNo\":\"20251113110113130266202235210653\",\"channelTradeNo\":\"4200002932202511131794511090\",\"currency\":\"cny\",\"drType\":\"00\",\"ifCode\":\"lklspay\",\"mchOrderNo\":\"WX1988788559919120384\",\"mercNo\":\"B251107293903\",\"msgType\":\"sft.trade.notify\",\"note\":\"成功\",\"payOrderId\":\"2025111319887885609440501775VT\",\"payTime\":\"2025-11-13 09:58:44\",\"payType\":\"WECHAT\",\"refundAmt\":0,\"refundState\":0,\"settlementType\":\"D1\",\"state\":\"TRADE_SUCCESS\",\"storeId\":\"S2511077140\",\"subject\":\"万维时光的店铺\",\"tradeFee\":0,\"userId\":\"oVxsc1QNZRRsWdWDmTdwPJGT9BWc\"}");
        AssertUtil.isNull(czg, "支付回调数据为空");
        log.info("支付回调数据为:{}", czg);
        orderInfoService.payCallBackOrder(czg.getString("mchOrderNo"), czg, 0);
        return null;
    }



    @RequestMapping("/payCallBack")
    public String notifyCallBack(@RequestBody CzgBaseRespParams respParams) {
        JSONObject czg = CzgPayUtils.getCzg(respParams);
        AssertUtil.isNull(czg, "支付回调数据为空");
        log.info("支付回调数据为:{}", czg);
        orderInfoService.payCallBackOrder(czg.getString("mchOrderNo"), czg, 0);
        return SUCCESS;
    }


    @RequestMapping("/native/wx/transfer")
    public String nativeTransferNotify(HttpServletRequest request) throws IOException {
        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");
        if ("SUCCESS".equals(tradeState)) {
            try {
                OrderPayment payment = paymentService.getOne(new QueryWrapper().eq(OrderPayment::getOrderNo, outTradeNo));
                payment.setTradeNumber(transactionId);
                payment.setPayTime(DateUtil.date().toLocalDateTime());
                payment.setRespJson(plainTextJson.toJSONString());
                paymentService.updateById(payment);
                distributionUserService.rechargeCallBack(payment.getShopId(), payment.getAmount(), payment.getId());
            }catch (Exception e) {
                log.error("充值回调失败", e);
                return "SUCCESS";
            }
        }

        return "SUCCESS";
    }


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

    @Resource
    private PrintMqListener printMqListener;

    @RequestMapping("/test")
    public void test(@RequestParam String id) {
        shopTableOrderStatisticService.statistic(DateUtil.date());
    }

    @GetMapping("/anew/statistic/history/data")
    public String statistic(@RequestParam String now) {
        String format = DateUtil.format(new Date(), "yyyyMMddHHmm");
        if (format.equals(now)) {
            ThreadUtil.execAsync(() -> statisticTask.statisticHistoryData());
        }
        return SUCCESS;
    }
}
