package com.hzs.third.pay.controller.api;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hzs.common.core.annotation.RepeatSubmitSimple;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.CommonUtil;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.domain.member.account.CuMemberRecharge;
import com.hzs.common.domain.third.pay.TOnlinePayment;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.member.account.IMemberTradeServiceApi;
import com.hzs.sale.order.ISaOrderServiceApi;
import com.hzs.sale.ticket.ITicketServiceApi;
import com.hzs.third.pay.constants.PayConfigConstants;
import com.hzs.third.pay.param.StatusParam;
import com.hzs.third.pay.param.UnifiedOrderParam;
import com.hzs.third.pay.service.*;
import com.hzs.third.pay.util.PayUtil;
import com.hzs.third.pay.vo.OnlinePayConfigVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 统一支付控制器
 */
@Slf4j
@RestController
@RequestMapping("/")
public class PayController {

    @Autowired
    private ITOnlinePaymentService itOnlinePaymentService;
    @Autowired
    private IHuiFuPayService iHuiFuPayService;
    @Autowired
    private IJdPayService iJdPayService;

    @Autowired
    private RedisTemplate redisTemplate;

    @DubboReference
    ISaOrderServiceApi iSaOrderServiceApi;
    @DubboReference
    IMemberTradeServiceApi iMemberTradeServiceApi;
    @DubboReference
    ITicketServiceApi iTicketServiceApi;

    /**
     * 统一下单
     *
     * @param source 请求来源（EDataSource）
     * @param param
     * @return
     */
    @RepeatSubmitSimple
    @PostMapping("/unifiedorder")
    public AjaxResult unifiedOrder(@RequestHeader("Source") String source,
                                   @Valid @RequestBody UnifiedOrderParam param) {
        EPayBusinessType payBusinessType = EPayBusinessType.getEnumByValue(param.getBusinessType());
        if (null == payBusinessType) {
            return AjaxResult.error("业务类型不存在");
        }
        EPayChannel payChannel = EPayChannel.getEnumByValue(param.getPayChannel());
        if (null == payChannel) {
            return AjaxResult.error("支付渠道不存在");
        }
        EPayType payType = EPayType.getEnumByValue(param.getPayType());
        if (null == payType) {
            return AjaxResult.error("支付类型不存在");
        }
        EDataSource dataSource = EDataSource.getEnumByValue(source);
        if (null == dataSource) {
            return AjaxResult.error("数据来源不存在");
        }

        // 登录用户ID
        Long userId = SecurityUtils.getUserId();
        // 登录用户国家
        Integer pkCountry = SecurityUtils.getPkCountry();

        // 1. 根据业务类型、业务单号进行校验。如果已经支付成功，直接返回；其它情况则继续执行
        TOnlinePayment onlinePayment = itOnlinePaymentService.queryByBusiness(payBusinessType.getValue(), param.getBusinessCode(), pkCountry);
        if (null != onlinePayment) {
            // 同一订单多次支付，需要校验是否已经支付过
            if (EPayStatus.PAID.getValue() == onlinePayment.getPayStatus()) {
                return AjaxResult.error("该订单已支付");
            }

            // 同一业务订单多次使用不同支付数据，以最新一次为准
            onlinePayment.setPayChannel(payChannel.getValue());
            onlinePayment.setPayType(payType.getValue());
            onlinePayment.setPkModified(userId);
            onlinePayment.setModifiedTime(new Date());
            onlinePayment.setPaySource(dataSource.getValue());
        } else {
            // 第一次生成支付信息
            onlinePayment = new TOnlinePayment();
            onlinePayment.setPaymentCode(CommonUtil.createSerialNumber(EOrderPrefix.THIRD_CODE));
            onlinePayment.setBusinessType(payBusinessType.getValue());
            onlinePayment.setBusinessCode(param.getBusinessCode());
            onlinePayment.setPayChannel(payChannel.getValue());
            onlinePayment.setPayType(payType.getValue());
            onlinePayment.setPkCountry(pkCountry);
            onlinePayment.setPkCreator(userId);
            onlinePayment.setCreationTime(new Date());
            onlinePayment.setPkModified(userId);
            onlinePayment.setModifiedTime(onlinePayment.getCreationTime());
            onlinePayment.setOriginalOrder(onlinePayment.getBusinessCode());
            onlinePayment.setPaySource(dataSource.getValue());
        }

        // 业务金额
        BigDecimal businessMoney = null;

        // 部分业务金额随机立减
        switch (payBusinessType) {
            case MEMBER_ORDER:
                // 会员订单
                R<BigDecimal> orderResult = iSaOrderServiceApi.getRetailPayOrder(userId, param.getBusinessCode());
                if (orderResult.isSuccess()) {
                    businessMoney = orderResult.getData().setScale(2, BigDecimal.ROUND_HALF_UP);
                } else {
                    return AjaxResult.error(orderResult.getMsg());
                }
                break;
            case RECHARGE:
                // 充值
                R<CuMemberRecharge> rechargeResult = iMemberTradeServiceApi.selectMemberRechargeByCodeAndPkMember(param.getBusinessCode(), userId);
                if (rechargeResult.isSuccess()) {
                    businessMoney = rechargeResult.getData().getRechargeAmount().setScale(2, BigDecimal.ROUND_HALF_UP);
                } else {
                    return AjaxResult.error(rechargeResult.getMsg());
                }
                break;
            case TICKET:
                // 购票
                R<BigDecimal> ticketResult = iTicketServiceApi.getTicketPayOrder(userId, param.getBusinessCode());
                if (ticketResult.isSuccess()) {
                    businessMoney = ticketResult.getData();
                } else {
                    return AjaxResult.error(ticketResult.getMsg());
                }
                break;
            default:
        }
        if (null == businessMoney) {
            return AjaxResult.error("当前支付金额有误");
        }
        if (businessMoney.compareTo(new BigDecimal("10000")) >= 0) {
            return AjaxResult.error("当前支付方式单笔金额不能超过10000元");
        }

        // 更新业务金额
        onlinePayment.setBusinessMoney(businessMoney);
        // 暂存于实际支付金额（业务进行随机立减后的）
        onlinePayment.setPayMoney(PayUtil.handleAmountRandom(businessMoney));

        // 结果实体
        R payResult = null;
        // 根据支付渠道、类型进行调用各渠道支付处理
        switch (payChannel) {
            case JD:
                // 京东
                switch (payType) {
                    case WECHAT:
                        // 微信
                        break;
                    case ALIPAY:
                        // 支付宝
                        break;
                    default:
                        // 默认京东收银台
                        payResult = iJdPayService.cashDeskPay(onlinePayment);
                }
                break;
            case HUIFU:
                // 新汇付
                switch (payType) {
                    case WECHAT:
                        // 微信
                        switch (dataSource) {
                            case H5:
                                // H5浏览器使用微信小程序支付
                                if (null != param.getAppletFlag() && EYesNo.YES.getIntValue() == param.getAppletFlag()) {
                                    // 小程序支付
                                    payResult = iHuiFuPayService.wechatPrePayUrl(onlinePayment, false);
                                    break;
                                }
                            default:
                                // PC以及默认按扫码支付
                                // 非小程序支付（微信内置浏览器）
                                payResult = iHuiFuPayService.wechatPrePayUrl(onlinePayment, true);
                                break;
                        }
                        break;
                    case ALIPAY:
                        // 支付宝
                        switch (dataSource) {
                            case H5:
                            case APP:
                                // H5浏览器 或者 APP
                                payResult = iHuiFuPayService.aliPrePayUrl(onlinePayment);
                            default:
                                // PC以及默认按扫码支付

                        }
                        break;
                    case BANK_CARD:
                        // 银行卡

                    default:
                }
            default:
        }

        // 根据各渠道支付处理结果，处理在线支付信息（T_ONLINE_PAYMENT）
        if (null != payResult) {
            if (payResult.isSuccess()) {
                // 实际支付金额在支付之前不需要入库，实际以取支付回调为准
                onlinePayment.setPayMoney(null);
                itOnlinePaymentService.saveOrUpdate(onlinePayment);

                return AjaxResult.success(payResult.getData());
            }
            return AjaxResult.error(payResult.getMsg());
        }
        return AjaxResult.error();
    }

    /**
     * 在线支付状态
     *
     * @param param
     * @return
     */
    @GetMapping("/status")
    public AjaxResult status(@Valid StatusParam param) {
        // 业务类型（校验业务类型）
        EPayBusinessType ePayBusinessType = EPayBusinessType.getEnumByValue(param.getBusinessType());
        if (null == ePayBusinessType) {
            return AjaxResult.success("支付业务类型错误", 0);
        }

        LambdaQueryWrapper<TOnlinePayment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TOnlinePayment::getBusinessType, param.getBusinessType());
        queryWrapper.eq(TOnlinePayment::getBusinessCode, param.getBusinessCode());
        TOnlinePayment onlinePayment = itOnlinePaymentService.getOne(queryWrapper);
        if (null == onlinePayment) {
            return AjaxResult.success("支付信息不存在", 0);
        }

        if (EPayStatus.PAID.getValue() == onlinePayment.getPayStatus()) {
            // 已支付
            return AjaxResult.success("已支付成功", 1);
        }
        return AjaxResult.success("未支付成功", 0);
    }

    /**
     * 获取当前支付配置
     *
     * @return
     */
    @GetMapping("/config")
    public AjaxResult config() {
        Integer pkCountry = SecurityUtils.getPkCountry();

        OnlinePayConfigVO payConfigVO = new OnlinePayConfigVO();

        // 各支付方式： true=显示，false=隐藏

        // 新汇付PC微信扫码支付
        String pay81 = String.format(PayConfigConstants.PAY_CONFIG_81, pkCountry);
        if (redisTemplate.hasKey(pay81)) {
            payConfigVO.setPay81((Boolean) redisTemplate.opsForValue().get(pay81));
        }
        // 新汇付PC支付宝扫码支付
        String pay82 = String.format(PayConfigConstants.PAY_CONFIG_82, pkCountry);
        if (redisTemplate.hasKey(pay82)) {
            payConfigVO.setPay82((Boolean) redisTemplate.opsForValue().get(pay82));
        }
        // 新汇付H5微信支付
        String pay83 = String.format(PayConfigConstants.PAY_CONFIG_83, pkCountry);
        if (redisTemplate.hasKey(pay83)) {
            payConfigVO.setPay83((Boolean) redisTemplate.opsForValue().get(pay83));
        }
        // 新汇付H5支付宝支付
        String pay84 = String.format(PayConfigConstants.PAY_CONFIG_84, pkCountry);
        if (redisTemplate.hasKey(pay84)) {
            payConfigVO.setPay84((Boolean) redisTemplate.opsForValue().get(pay84));
        }
        return AjaxResult.success(payConfigVO);
    }


}
