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

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hzs.activity.base.IActivityServiceApi;
import com.hzs.common.core.annotation.RepeatSubmitSimple;
import com.hzs.common.core.constant.SysConstants;
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.utils.StringUtils;
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.third.pay.constants.PayConfigConstants;
import com.hzs.third.pay.param.PayParam;
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 java.math.BigDecimal;
import java.util.Date;

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

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

    @Autowired
    private RedisTemplate redisTemplate;

    @DubboReference
    ISaOrderServiceApi iSaOrderServiceApi;
    @DubboReference
    IMemberTradeServiceApi iMemberTradeServiceApi;
    @DubboReference
    IActivityServiceApi iActivityServiceApi;

    /**
     * 统一下单
     *
     * @param source   请求来源（EDataSource）
     * @param payParam
     * @return
     */
    @RepeatSubmitSimple
    @PostMapping("/unifiedorder")
    public AjaxResult unifiedOrder(@RequestHeader("Source") String source,
                                   @RequestBody PayParam payParam) {
        if (null == payParam.getBusinessType() || StringUtils.isEmpty(payParam.getBusinessCode())
                || null == payParam.getPayChannel() || null == payParam.getPayType()) {
            return AjaxResult.error("缺少参数");
        }
        EPayBusinessType payBusinessType = EPayBusinessType.getEnumByValue(payParam.getBusinessType());
        if (null == payBusinessType) {
            return AjaxResult.error("业务类型不存在");
        }
        EPayChannel payChannel = EPayChannel.getEnumByValue(payParam.getPayChannel());
        if (null == payChannel) {
            return AjaxResult.error("支付渠道不存在");
        }
        EPayType payType = EPayType.getEnumByValue(payParam.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();
        // 微信 openId（用于微信小程序支付）
        String openId = null;

        // 1. 根据业务类型、业务单号进行校验。如果已经支付成功，直接返回；其它情况则继续执行
        TOnlinePayment onlinePayment = itOnlinePaymentService.queryByBusiness(payBusinessType.getValue(), payParam.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(payParam.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());
        }
        onlinePayment.setExtParam(payParam.getExtParam());

        // 业务金额
        BigDecimal businessMoney = null;
        // 实际支付金额（随机立减之后）
        BigDecimal amount = null;

        // 部分业务金额随机立减
        switch (payBusinessType) {
            case DIRECT_SELLING:
                // 直销订单
                R<BigDecimal> orderResult = iSaOrderServiceApi.querySaOrderByOrderCode(userId, payParam.getBusinessCode());
                if (orderResult.isSuccess()) {
                    businessMoney = orderResult.getData();
                    businessMoney = businessMoney.setScale(2, BigDecimal.ROUND_HALF_UP);
                    // 订单支付金额最后2角处理
                    amount = PayUtil.handleAmountRandom(businessMoney);
                } else {
                    return AjaxResult.error(orderResult.getMsg());
                }
                break;
            case RECHARGE:
                // 充值
                R<CuMemberRecharge> rechargeResult = iMemberTradeServiceApi.selectMemberRechargeByCodeAndPkMember(payParam.getBusinessCode(), userId);
                if (rechargeResult.isSuccess()) {
                    businessMoney = rechargeResult.getData().getRechargeAmount();
                    amount = PayUtil.handleAmountRandom(businessMoney);
                } else {
                    return AjaxResult.error(rechargeResult.getMsg());
                }
                break;
            case LUCK:
                // 抽奖
                R<BigDecimal> luckResult = iActivityServiceApi.queryDrawRewardPayNumMoney(userId, payParam.getBusinessCode());
                if (luckResult.isSuccess()) {
                    businessMoney = luckResult.getData();
                    amount = businessMoney;
                } else {
                    return AjaxResult.error(luckResult.getMsg());
                }
                break;
            default:
        }
        // 更新业务金额
        onlinePayment.setBusinessMoney(businessMoney);
        // 暂存于实际支付金额（部分业务进行随机立减）
        onlinePayment.setPayMoney(amount);

        // 结果实体
        R payResult = null;
        // 根据支付渠道、类型进行调用各渠道支付处理
        switch (payChannel) {
            case ALLIN:
                // 通联
                switch (payType) {
//                    case WECHAT:
//                        // 微信
//                        switch (dataSource) {
//                            case APP:
//                            case H5:
//                                if (null != payParam.getAppletFlag() && payParam.getAppletFlag() == EYesNo.YES.getIntValue()) {
//                                    payResult = iAllInPayService.createCode(onlinePayment);
//                                    break;
//                                }
//                            default:
////                                // 默认按扫码支付
////                                payResult = iAllInPayService.scanPay(onlinePayment);
////                                break;
//                        }
//                        break;
                    case BANK_CARD:
                        // 银行卡支付
                        if (StringUtils.isEmpty(payParam.getBindCode())) {
                            return AjaxResult.error("银行绑卡编号不能为空");
                        }
                        payResult = iAllInPayService.bankPay(onlinePayment, payParam.getBindCode());
                        break;
                    default:
                }
                break;
            case JD:
                // 京东
                switch (payType) {
                    case WECHAT:
                    case ALIPAY:
                        // 微信、支付宝 扫码支付
//                        payResult = iJdPayService.scanPay(onlinePayment);
                        payResult = iJdPayService.cashRegister(onlinePayment, dataSource);
                        break;
                    case BANK_CARD:
                        // 银行卡支付
                        if (StringUtils.isEmpty(payParam.getBindCode())) {
                            return AjaxResult.error("银行绑卡编号不能为空");
                        }
                        payResult = iJdPayService.bankPay(onlinePayment, payParam.getBindCode());
                        break;
                    case BANK_ONLINE:
                        // 网上银行（收银台）
                        payResult = iJdPayService.cashRegister(onlinePayment, dataSource);
                        break;
                    default:
                }
                break;
            case HUIFU:
                // 汇付新
                switch (payType) {
                    case WECHAT:
                        // 微信
                        switch (dataSource) {
                            case H5:
                                // H5浏览器使用微信小程序支付
                                // TODO H5微信使用公众号支付
                            default:
                                // PC以及默认按扫码支付
                                payResult = iHuiFuPayService.prePayScan(onlinePayment);
                                break;
                        }
                        break;
                    case ALIPAY:
                        // 支付宝

                        break;
                    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(PayParam param) {
//        if (null == param.getBusinessType() || StringUtils.isEmpty(param.getBusinessCode())) {
//            return AjaxResult.success("缺少参数");
//        }
        if (StringUtils.isEmpty(param.getBusinessCode())) {
            return AjaxResult.success("缺少参数");
        }

        // 业务类型（校验业务类型）
//        EPayBusinessType ePayBusinessType = EPayBusinessType.getEnumByValue(param.getBusinessType());
//        if (null == ePayBusinessType) {
//            return AjaxResult.success("支付业务类型错误", 0);
//        }

        QueryWrapper<TOnlinePayment> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("BUSINESS_TYPE", param.getBusinessType());
        queryWrapper.eq("BUSINESS_CODE", 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=隐藏

        // 京东收银台（H5）
        String pay5 = String.format(PayConfigConstants.PAY_CONFIG_5, pkCountry);
        if (redisTemplate.hasKey(pay5)) {
            payConfigVO.setPay5((Boolean) redisTemplate.opsForValue().get(pay5));
        }
        // 京东收银台（PC）
        String pay6 = String.format(PayConfigConstants.PAY_CONFIG_6, pkCountry);
        if (redisTemplate.hasKey(pay6)) {
            payConfigVO.setPay6((Boolean) redisTemplate.opsForValue().get(pay6));
        }

        // 通联微信
        String pay32 = String.format(PayConfigConstants.PAY_CONFIG_32, pkCountry);
        if (redisTemplate.hasKey(pay32)) {
            payConfigVO.setPay32((Boolean) redisTemplate.opsForValue().get(pay32));
        }
        // 通联银行卡
        String pay33 = String.format(PayConfigConstants.PAY_CONFIG_33, pkCountry);
        if (redisTemplate.hasKey(pay33)) {
            payConfigVO.setPay33((Boolean) redisTemplate.opsForValue().get(pay33));
        }

        // 新汇付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));
        }

        if (SysConstants.SPECIAL_CODE.equals(SecurityUtils.getMemberCode())) {
            // 在线支付测试账号，强制显示支付方式
            payConfigVO.setPay5(true);
        }

        return AjaxResult.success(payConfigVO);
    }


}
