package com.ycwl.basic.service.mobile.impl;


import com.ycwl.basic.biz.OrderBiz;
import com.ycwl.basic.constant.NumberConstant;
import com.ycwl.basic.enums.BizCodeEnum;
import com.ycwl.basic.enums.OrderStateEnum;
import com.ycwl.basic.enums.StatisticEnum;
import com.ycwl.basic.exception.AppException;
import com.ycwl.basic.mapper.OrderMapper;
import com.ycwl.basic.mapper.PaymentMapper;
import com.ycwl.basic.mapper.StatisticsMapper;
import com.ycwl.basic.model.mobile.statistic.req.StatisticsRecordAddReq;
import com.ycwl.basic.model.pc.order.entity.OrderEntity;
import com.ycwl.basic.model.pc.order.req.OrderUpdateReq;
import com.ycwl.basic.model.pc.payment.entity.PaymentEntity;
import com.ycwl.basic.model.wx.WXPayOrderReqVO;
import com.ycwl.basic.model.wx.WechatCallbackSuccessData;
import com.ycwl.basic.pay.adapter.IPayAdapter;
import com.ycwl.basic.pay.entity.CancelOrderRequest;
import com.ycwl.basic.pay.entity.CreateOrderRequest;
import com.ycwl.basic.pay.entity.CreateOrderResponse;
import com.ycwl.basic.pay.entity.PayResponse;
import com.ycwl.basic.pay.entity.RefundResponse;
import com.ycwl.basic.pay.entity.RefundOrderRequest;
import com.ycwl.basic.pay.entity.RefundOrderResponse;
import com.ycwl.basic.repository.OrderRepository;
import com.ycwl.basic.service.mobile.WxPayService;
import com.ycwl.basic.service.pc.ScenicService;
import com.ycwl.basic.utils.SnowFlakeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

/**
 * @Author: songmingsong
 * @CreateTime: 2024-12-05
 * @Description: 微信支付实现
 * @Version: 1.0
 */
@Slf4j
@Service
public class WxPayServiceImpl implements WxPayService {

    @Autowired
    private PaymentMapper paymentMapper;
    @Autowired
    private StatisticsMapper statisticsMapper;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private OrderBiz orderBiz;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ScenicService scenicService;

    @Override
    public Map<String, Object> createOrder(Long scenicId, WXPayOrderReqVO req) {
        PaymentEntity entity = new PaymentEntity();
        entity.setOrderId(req.getOrderSn());
        entity.setMemberId(req.getMemberId());
        entity.setPayPrice(new BigDecimal(BigInteger.valueOf(req.getTotalPrice()), 2));
        Long entityId = paymentMapper.addGetId(entity);
        IPayAdapter scenicPayAdapter = scenicService.getScenicPayAdapter(scenicId);
        try {
            CreateOrderRequest request = new CreateOrderRequest()
                    .setOrderNo(String.valueOf(req.getOrderSn()))
                    .setPriceInCents(req.getTotalPrice())
                    .setDescription(req.getDescription())
                    .setGoodsName(req.getGoodsName())
                    .setUserIdentify(req.getOpenId())
                    .setNotifyUrl("https://zhentuai.com/api/mobile/wx/pay/v1/"+scenicId+"/payNotify");
            CreateOrderResponse order = scenicPayAdapter.createOrder(request);
            Map<String, Object> paymentParams = scenicPayAdapter.getPaymentParams(order);
            paymentParams.put("needPay", !order.isSkipPay());
            paymentParams.put("orderId", req.getOrderSn());
            return paymentParams;
        } catch (Exception e) {
            log.error("[微信支付]createOrder error", e);
            throw new AppException(BizCodeEnum.ADVANCE_PAYMENT_FAILED, e.toString());
        }
    }

    @Override
    public PayResponse payNotify(Long scenicId, HttpServletRequest request) {
        IPayAdapter scenicPayAdapter = scenicService.getScenicPayAdapter(scenicId);
        try {
            PayResponse callbackResponse = scenicPayAdapter.handleCallback(request);
            log.info("[微信支付]parse = {}", callbackResponse);

            // 更新订单信息
            new Thread(() -> {
                long orderId = Long.parseLong(callbackResponse.getOrderNo());
                if (callbackResponse.isPay()) {
                    orderBiz.paidOrder(orderId);
                } else if (callbackResponse.isCancel()) {
                    orderBiz.cancelOrder(orderId);
                } else if (callbackResponse.isRefund()) {
                    orderBiz.refundOrder(orderId);
                }
            }).start();
        } catch (Exception e) {
            throw new AppException(BizCodeEnum.ADVANCE_PAYMENT_CALLBACK_FAILED, e.toString());
        }
        return null;
    }

    @Override
    public void payNotify(HttpServletRequest request) {
        payNotify(0L, request);
    }

    @Override
    public WechatCallbackSuccessData queryPay(Long orderId) {
        return null;
    }

    @Override
    public Boolean refundOrder(String orderId) {
        OrderEntity order = orderRepository.getOrder(Long.parseLong(orderId));
        IPayAdapter scenicPayAdapter = scenicService.getScenicPayAdapter(order.getScenicId());
        BigDecimal payPrice = order.getPayPrice();
        int priceInCents = payPrice.multiply(new BigDecimal(NumberConstant.HUNDRED)).intValue(); // 转换为分（int）
        RefundOrderRequest request = new RefundOrderRequest()
                .setOrderNo(orderId)
                .setPrice(priceInCents)
                .setRefundNo(SnowFlakeUtil.getId())
                .setRefundPrice(priceInCents)
                .setNotifyUrl("https://zhentuai.com/api/mobile/wx/pay/v1/"+order.getScenicId()+"/refundNotify");
        RefundOrderResponse response = scenicPayAdapter.refund(request);
        if (response.isSuccess()) {
            OrderUpdateReq orderUpdateReq = new OrderUpdateReq();
            orderUpdateReq.setId(Long.parseLong(orderId));
            orderUpdateReq.setRefundStatus(OrderStateEnum.REFUNDED.getType());
            orderUpdateReq.setRefundAt(new Date());
            orderMapper.update(orderUpdateReq);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean refundNotify(Long scenicId, HttpServletRequest request) throws IOException {
        IPayAdapter scenicPayAdapter = scenicService.getScenicPayAdapter(scenicId);
        try {
            RefundResponse callbackResponse = scenicPayAdapter.handleRefundCallback(request);
            log.info("[微信支付]parse = {}", callbackResponse);

            // 更新订单信息
            long orderId = Long.parseLong(callbackResponse.getOrderNo());
            orderBiz.refundOrder(orderId);

            OrderEntity order = orderRepository.getOrder(orderId);
            StatisticsRecordAddReq statisticsRecordAddReq = new StatisticsRecordAddReq();
            statisticsRecordAddReq.setMemberId(order.getMemberId());
            statisticsRecordAddReq.setType(StatisticEnum.REFUND.code);
            statisticsRecordAddReq.setScenicId(order.getScenicId());
            statisticsRecordAddReq.setMorphId(orderId);
            statisticsMapper.addStatisticsRecord(statisticsRecordAddReq);
            return true;
        } catch (Exception e) {
            log.error("微信退款回调失败！", e);
            return false;
        }
    }

    @Override
    public void closeOrder(String orderId) {
        OrderEntity order = orderRepository.getOrder(Long.parseLong(orderId));
        IPayAdapter scenicPayAdapter = scenicService.getScenicPayAdapter(order.getScenicId());
        CancelOrderRequest request = new CancelOrderRequest()
                .setOrderNo(orderId);
        scenicPayAdapter.cancelOrder(request);
    }
}
