package com.xinelu.applet.controller.wechatpaymentinfo;

import com.xinelu.applet.service.wechatpaymentinfo.WeChatPayNotifyService;
import com.xinelu.applet.service.wechatpaymentinfo.WeChatPaymentService;
import com.xinelu.applet.service.wechatpaymentinfo.WeChatRefundService;
import com.xinelu.applet.vo.wechatpaymentinfo.dto.CloseOrderDTO;
import com.xinelu.applet.vo.wechatpaymentinfo.dto.PaymentDTO;
import com.xinelu.applet.vo.wechatpaymentinfo.dto.RefundDTO;
import com.xinelu.common.annotation.MobileRequestAuthorization;
import com.xinelu.common.core.controller.BaseController;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.custominterface.Insert;
import com.xinelu.common.enums.BuySourceEnum;
import com.xinelu.common.exception.ServiceException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Objects;

/**
 * @Description 微信小程序和App支付控制器
 * @Author 纪寒
 * @Date 2022-10-18 14:47:11
 * @Version 1.0
 */
@Api(tags = "微信小程序和App支付控制器")
@RestController
@RequestMapping("/nurseApp/weChatPayment")
public class WeChatPaymentController extends BaseController {

    @Resource
    private WeChatPaymentService weChatPaymentService;
    @Resource
    private WeChatPayNotifyService weChatPayNotifyService;
    @Resource
    private WeChatRefundService weChatRefundService;

    /**
     * 微信小程序购买商品和健康咨询支付接口
     *
     * @param paymentDTO 输入参数
     * @return 支付返回结果
     * @throws Exception 异常信息
     */
    @MobileRequestAuthorization
    @PostMapping("/appletGoodsOrderPay")
    public AjaxResult appletGoodsOrderPay(@Validated(Insert.class) @RequestBody PaymentDTO paymentDTO, BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            throw new ServiceException(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        if (StringUtils.isBlank(paymentDTO.getOpenid())) {
            return AjaxResult.error("微信openid不能为空！");
        }
        if (Objects.nonNull(paymentDTO.getPaymentPrice()) && paymentDTO.getPaymentPrice().compareTo(BigDecimal.ZERO) < 0) {
            return AjaxResult.error("订单支付金额不能为负数，无法支付！");
        }
        if (Objects.nonNull(paymentDTO.getPaymentPrice()) && paymentDTO.getPaymentPrice().compareTo(BigDecimal.ZERO) == 0) {
            return AjaxResult.error("订单支付金额不能为零，无法支付！");
        }
        return weChatPaymentService.appletGoodsOrderPay(paymentDTO);
    }

    /**
     * 微信小程序预约服务订单支付接口
     *
     * @param paymentDTO 输入参数
     * @return 支付返回结果信息
     * @throws Exception 异常信息
     */
    @MobileRequestAuthorization
    @PostMapping("/appletAppointmentOrderPay")
    public AjaxResult appletAppointmentOrderPay(@Validated(Insert.class) @RequestBody PaymentDTO paymentDTO, BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            throw new ServiceException(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        if (StringUtils.isBlank(paymentDTO.getOpenid())) {
            return AjaxResult.error("微信openid不能为空！");
        }
        if (!BuySourceEnum.NURSE_STATION.getInfo().equals(paymentDTO.getBuySource())) {
            return AjaxResult.error("当前订单非预约服务项，请重新预约！");
        }
        if (Objects.nonNull(paymentDTO.getPaymentPrice()) && paymentDTO.getPaymentPrice().compareTo(BigDecimal.ZERO) < 0) {
            return AjaxResult.error("订单支付金额不能为负数，无法支付！");
        }
        return weChatPaymentService.appletAppointmentOrderPay(paymentDTO);
    }

    /**
     * 新医路微信支付回调通知接口
     *
     * @param request  请求头信息
     * @param response 响应信息
     * @return 应答信息，避免微信平台重复发送回调通知
     * @throws Exception 异常信息
     */
    @PostMapping("/xylWeChatPayNotify")
    public String xylWeChatPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return weChatPayNotifyService.xylWeChatPayNotify(request, response);
    }

    /**
     * 微信确认退款接口
     *
     * @param refundDTO 退款参数
     * @return 退款申请结果
     */
    @PostMapping("/weChatRefundOrderApply")
    public AjaxResult weChatRefundOrderApply(@Validated(Insert.class) @RequestBody RefundDTO refundDTO) {
        return weChatRefundService.weChatRefundOrderApply(refundDTO);
    }

    /**
     * 新医路微信退款回调通知接口
     *
     * @param request  请求头信息
     * @param response 响应信息
     * @return 应答信息，避免微信平台重复发送回调通知
     * @throws Exception 异常信息
     */
    @PostMapping("/xylWeChatRefundNotify")
    public String xylWeChatRefundNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return weChatPayNotifyService.xylWeChatRefundNotify(request, response);
    }

    /**
     * 专家咨询订单-医生端App拒单接口
     *
     * @param closeOrderDTO 订单关闭参数
     * @return 退款申请结果
     */
    @ApiOperation("专家咨询订单-医生端App拒单接口")
    @PostMapping("/closeHealthConsultationOrder")
    public AjaxResult closeHealthConsultationOrder(@Validated(Insert.class) @RequestBody CloseOrderDTO closeOrderDTO) {
        return weChatRefundService.closeHealthConsultationOrder(closeOrderDTO);
    }
    /**
     * 泉医助手小程序-学习培训微信支付
     *
     * @param paymentDTO 支付参数
     * @return 支付结果
     * @throws Exception 异常信息
     */
    @MobileRequestAuthorization
    @PostMapping("/appletTrainingOrderPay")
    public AjaxResult appletTrainingOrderPay(@RequestBody PaymentDTO paymentDTO) throws Exception {
        AjaxResult ajaxResult = judgeTrainingOrderPayParam(paymentDTO);
        if (Objects.nonNull(ajaxResult)) {
            return ajaxResult;
        }
        return weChatPaymentService.appletTrainingOrderPay(paymentDTO);
    }

    /**
     * 手动校验学习培训微信支付参数校验
     *
     * @param paymentDTO 支付参数
     * @return 校验结果
     */
    private AjaxResult judgeTrainingOrderPayParam(PaymentDTO paymentDTO) {
        if (Objects.isNull(paymentDTO)) {
            return AjaxResult.error("当前订单信息不存在，无法支付！");
        }
        if (Objects.isNull(paymentDTO.getNurseStationPersonId()) || StringUtils.isBlank(paymentDTO.getOpenid())) {
            return AjaxResult.error("当前护理员信息不存在，无法支付！");
        }
        if (StringUtils.isBlank(paymentDTO.getOrderNo())) {
            return AjaxResult.error("当前订单信息不存在，无法支付！");
        }
        if (StringUtils.isBlank(paymentDTO.getOrderChannel())) {
            return AjaxResult.error("当前支付方式非小程序支付，无法支付！");
        }
        if (StringUtils.isBlank(paymentDTO.getBuySource())) {
            return AjaxResult.error("订单购买来源不能为空，无法支付！");
        }
        if (Objects.isNull(paymentDTO.getPaymentPrice()) || paymentDTO.getPaymentPrice().compareTo(BigDecimal.ZERO) <= 0) {
            return AjaxResult.error("订单支付金额应大于零，无法支付！");
        }
        return null;
    }
}
