package com.njyunzhi.pet_identity.service.impl;

import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result;
import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.njyunzhi.pet_identity.common.Constants;
import com.njyunzhi.pet_identity.common.ResponseBean;
import com.njyunzhi.pet_identity.common.StringUtils;
import com.njyunzhi.pet_identity.common.WxPayUtils;
import com.njyunzhi.pet_identity.entity.SysSetting;
import com.njyunzhi.pet_identity.entity.TaApplication;
import com.njyunzhi.pet_identity.entity.TaOrder;
import com.njyunzhi.pet_identity.entity.TaPerson;
import com.njyunzhi.pet_identity.mapper.TaApplicationMapper;
import com.njyunzhi.pet_identity.mapper.TaOrderMapper;
import com.njyunzhi.pet_identity.service.ISysSettingService;
import com.njyunzhi.pet_identity.service.ITaOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author yansen
 * @since 2022-05-24
 */
@Service
public class TaOrderServiceImpl extends BaseServiceImpl<TaOrderMapper, TaOrder> implements ITaOrderService {

    @Autowired
    TaApplicationMapper applicationMapper;

    @Autowired
    ISysSettingService iSysSettingService;

    @Autowired
    WxPayUtils wxPayUtils;

    @Override
    public void notifyOrderPay(WxPayOrderNotifyV3Result.DecryptNotifyResult result) throws Exception {
        TaOrder taOrder = getExistBy("order_no", result.getOutTradeNo(), false, true);
        if (null == taOrder) {
            throw new Exception("未找到单号 [" + result.getOutTradeNo() + "] 对应的订单");
        }

        if (taOrder.getStatus() == Constants.PAY_STATUS_PAID) {
            return;
        }

        boolean isSuccess = WxPayConstants.ResultCode.SUCCESS.equals(result.getTradeState());
        if (!isSuccess) return;

        taOrder.setStatus(Constants.PAY_STATUS_PAID);
        taOrder.setPayDate(LocalDateTime.now());

        baseMapper.updateById(taOrder);

        // 更新申请单状态
        if (StringUtils.isEmpty(taOrder.getApplyId())) return;
        TaApplication taApplication = applicationMapper.selectById(taOrder.getApplyId());
        if (null == taApplication || Constants.STATUS_DELETE == taApplication.getStatus()) return;

        taApplication.setPayStatus(Constants.PAY_STATUS_PAID);
        taApplication.setStatus(Constants.WORKFLOW_STATUS_PROCESSING);
        applicationMapper.updateById(taApplication);
    }

    @Override
    public String createOrderNo() throws Exception {
        return baseMapper.getShortUUID();
    }

    @Override
    public boolean refundByApplication(TaApplication taApplication) throws Exception {
        TaOrder taOrder = baseMapper.getByApplyId(taApplication.getApplyId().toString());
        if (null == taOrder) {
            throw new Exception("未找到支付订单信息");
        }

        WxPayRefundV3Request request = new WxPayRefundV3Request();
        request.setOutTradeNo(taOrder.getOrderNo()); // 原单号
        request.setOutRefundNo("R-" + taOrder.getOrderNo()); // 退款单号
        WxPayRefundV3Request.Amount amount = new  WxPayRefundV3Request.Amount();
        amount.setTotal(taOrder.getCharges());
        amount.setRefund(taOrder.getCharges());
        amount.setCurrency("CNY");
        request.setAmount(amount);
        wxPayUtils.refund(request);

        return true;
    }

    @Override
    public TaOrder createByApplication(TaPerson taPerson, TaApplication taApplication) throws Exception {
        if (!taPerson.getPersonId().equals(taApplication.getPersonId())) {
            throw new Exception("非本人订单, 不能支付");
        }

        if (Constants.PAY_STATUS_PAID == taApplication.getPayStatus()) {
            throw new Exception("当前申请已支付");
        }

        // 快递费
        SysSetting expressFeeSetting = iSysSettingService.getById(Constants.SYSSETTING_EXPRESS_FEE);
        float expressFee = Float.parseFloat(expressFeeSetting.getContent());
        // 工本费
        SysSetting productionCostSetting = iSysSettingService.getById(Constants.SYSSETTING_PRODUCTION_COST);
        float productionCost = Float.parseFloat(productionCostSetting.getContent());

        TaOrder taOrder = new TaOrder();
        String orderNo = createOrderNo();
        taOrder.setOrderNo(orderNo);
        taOrder.setApplyId(taApplication.getApplyId().toString());
        taOrder.setProductionCost((int) (productionCost * 100));
        // 如果没有选择快递提取, 则没有快递费用
        taOrder.setExpressFee(taApplication.getApplyMethod() == 2 ? (int) (expressFee * 100) : 0);
        taOrder.setCharges(taOrder.getExpressFee() + taOrder.getProductionCost());
        taOrder.setStatus(Constants.PAY_STATUS_READY);
        taOrder.setCreateDate(LocalDateTime.now());

        if (save(taOrder)) {
            return taOrder;
        } else {
            throw new Exception("生成订单失败");
        }
    }

    @Override
    public void refundNotifyOrder(WxPayRefundNotifyV3Result.DecryptNotifyResult result) throws Exception {
        String orderNo = result.getOutTradeNo();
        TaOrder taOrder = getExistBy("order_no", orderNo, false, true);
        if (null == taOrder) {
            log.error("退款通知处理失败: 单号 " + orderNo);
            log.error(result.toString());
            return;
        }

        boolean isSuccess = WxPayConstants.RefundStatus.SUCCESS.equals(result.getRefundStatus());
        if (isSuccess) {
            // 更新订单
            taOrder.setStatus(Constants.PAY_STATUS_REFUND);
            taOrder.setRefundDate(LocalDateTime.now());
            updateById(taOrder);
            // 更新申请
            TaApplication taApplication = applicationMapper.selectById(taOrder.getApplyId());
            taApplication.setPayStatus(Constants.PAY_STATUS_REFUND);
            applicationMapper.updateById(taApplication);
        }

    }
}
