package com.yami.shop.api.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.yami.shop.bean.app.param.PayParam;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderSettlement;
import com.yami.shop.bean.model.RefundDelivery;
import com.yami.shop.bean.pay.PayInfoDto;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.IPHelper;
import com.yami.shop.security.api.model.YamiUser;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.OrderService;
import com.yami.shop.service.OrderSettlementService;
import com.yami.shop.service.PayService;
import com.yami.shop.service.RefundDeliveryService;
import com.yami.shop.wx.config.WechatPayServiceConfig;
import com.yami.shop.wx.po.JsapiPayInfoPo;
import com.yami.shop.wx.po.RefundInfoPo;
import com.yami.shop.wx.service.WxProviderService;
import com.yami.shop.wx.utils.CullenUtils;
import com.yami.shop.wx.utils.OrderUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequestMapping("/p/order")
@Api(tags = "订单接口（测试退款）")
@AllArgsConstructor
public class PayController {

    private final PayService payService;
    private final OrderService orderService;
    private final RefundDeliveryService refundDeliveryService;
    private final OrderSettlementService orderSettlementService;
    private final WxProviderService wxProviderService;
    private final String baseNotifyUrl ="https://shop.api.zswlgz.com";
    //测试
//    private final String baseNotifyUrl ="https://63332824.r36.cpolar.top";


    @GetMapping("/orderNumber")
    @ApiOperation(value = "测试退款")
    public ResponseEntity<?> refund(@RequestParam String orderNumber) {
        Order order = orderService.getOrderByOrderNumber(orderNumber);
        OrderSettlement one = orderSettlementService.getOne(new LambdaQueryWrapper<OrderSettlement>().eq(OrderSettlement::getOrderNumber, orderNumber));

        if (order.getActualTotal() == null || Math.abs(order.getActualTotal()) < 0.000001) {
            return ResponseEntity.ok("该订单支付金额为0, 无法退款!");
        }

        RefundInfoPo refundInfoPo = new RefundInfoPo();
        refundInfoPo.setOutTradeNo(one.getPayNo());
        refundInfoPo.setTotal((int)(order.getActualTotal()*100));
        refundInfoPo.setRefundMoney((int)(order.getActualTotal()*100));
        return ResponseEntity.ok(wxProviderService.refundOrder(refundInfoPo));
    }


    @SneakyThrows
    //@PostMapping("/doPay")
    @ApiOperation(value = "ApiV2版本的服务商支付")
    public ResponseEntity<?> doPay() {
        WechatPayServiceConfig wxConfig = wxProviderService.getWxConfig();
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(wxConfig.getSpAppId());
        payConfig.setMchId(wxConfig.getSpMchId());
        payConfig.setSubAppId(wxConfig.getSubAppId());
        payConfig.setSubMchId(wxConfig.getSubMchId());
        payConfig.setMchKey(wxConfig.getApiV3Key());
        payConfig.setKeyPath(wxConfig.getKeyPemPath());
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);

        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
        orderRequest.setBody("商城下单");
        orderRequest.setOutTradeNo(OrderUtils.getOrderNo(""));
        orderRequest.setTotalFee(1);
        orderRequest.setSpbillCreateIp(IPHelper.getIpAddr());
        orderRequest.setSubOpenid("owrSr6y0TGPHBU2tgMVoCO13Gjww");
        orderRequest.setNotifyUrl("http://localhost:8112");
        orderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);
        WxPayMpOrderResult wxPayMpOrderResult = wxPayService.createOrder(orderRequest);
        return ResponseEntity.ok(wxPayMpOrderResult);
    }


    @SneakyThrows
    @PostMapping("/pay")
    @ApiOperation(value = "根据订单号进行支付", notes = "根据订单号进行支付")
    public ResponseEntity<?> pay(@Valid @RequestBody PayParam payParam) {
        System.out.println("开始进行支付...");
        YamiUser user = SecurityUtils.getUser();
        CullenUtils.validateDataThrowException(!user.isEnabled(), "您已被禁用，不能购买，请联系平台客服");
        PayInfoDto payInfo = payService.pay(user.getUserId(), payParam);

        if (payInfo.getPayAmount() < 0.01 && payInfo.getIsScore() == 1) {
            return ResponseEntity.ok().build();
        }

        CullenUtils.validateDataThrowException(payInfo.getPayAmount() < 0.01, "订单金额有误，无法进行支付");
        JsapiPayInfoPo po = new JsapiPayInfoPo();
        po.setDescription(payInfo.getBody());
        po.setTotal((int) Arith.mul(payInfo.getPayAmount(), 100));
        //po.setTotal(1);
        po.setOpenId(user.getBizUserId());
        po.setOutTradeNo(payInfo.getPayNo());
        po.setNotifyUrl(getNotifyUrl(baseNotifyUrl));
        return ResponseEntity.ok(wxProviderService.subJsapi(po));
    }

    @PostMapping("/refundPay")
    @ApiOperation(value = "退货配送费", notes = "退货配送费")
    @SneakyThrows
    public ResponseEntity<?> refundPay(@Valid @RequestBody PayParam payParam) {
        RefundDelivery refundDelivery = refundDeliveryService.getOne(new LambdaQueryWrapper<RefundDelivery>()
                .eq(RefundDelivery::getRefundSn, payParam.getOrderNumbers()));

        CullenUtils.validateDataThrowException(refundDelivery.getPayer().equals("1"), "无需支付");
        CullenUtils.validateDataThrowException(refundDelivery.getPrice() < 0.01, "订单金额有误，无法进行支付");
        JsapiPayInfoPo po = new JsapiPayInfoPo();
        po.setDescription("退货配送费");
        po.setTotal((int) Arith.mul(refundDelivery.getPrice(), 100));
        po.setOpenId(SecurityUtils.getUser().getBizUserId());
        po.setOutTradeNo("refundSn" + payParam.getOrderNumbers());
        po.setNotifyUrl(getNotifyUrl(baseNotifyUrl));
        return ResponseEntity.ok(wxProviderService.subJsapi(po));
    }

    @GetMapping("/isPay/{orderNumbers}")
    @ApiOperation(value = "根据订单号查询该订单是否已经支付", notes = "根据订单号查询该订单是否已经支付")
    public ResponseEntity<Boolean> isPay(@PathVariable String orderNumbers) {
        String[] orderNumberArr = orderNumbers.split(StrUtil.COMMA);
        int count = orderService.count(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumberArr[0])
                .eq(Order::getUserId, SecurityUtils.getUser().getUserId())
                .eq(Order::getIsPayed, 1));
        return ResponseEntity.ok(count > 0);
    }

    private static String getNotifyUrl(String uri) {
        return uri.concat("/notice/pay/order/wxNotify");
    }
}
