package com.izouma.nineth.web;

import com.alibaba.fastjson.JSONObject;
import com.izouma.nineth.domain.*;
import com.izouma.nineth.dto.pay.TradeType;
import com.izouma.nineth.dto.pay.UniformPayRequest;
import com.izouma.nineth.dto.pay.UniformPayResult;
import com.izouma.nineth.dto.userfund.BalanceInfoDTO;
import com.izouma.nineth.dto.userfund.RechargeOrderForm;
import com.izouma.nineth.dto.userfund.WithdrawApplyForm;
import com.izouma.nineth.enums.OrderStatus;
import com.izouma.nineth.exception.BusinessException;
import com.izouma.nineth.lock.RedisLockException;
import com.izouma.nineth.repo.PaymentInfoRepo;
import com.izouma.nineth.repo.UserBankCardRepo;
import com.izouma.nineth.service.*;
import com.izouma.nineth.service.pay.UniformPayConstants;
import com.izouma.nineth.service.pay.UniformPayUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * 杉德钱包
 */
@RestController
@RequestMapping("/walletSandpay")
@AllArgsConstructor
@Slf4j
public class WalletSandpayController extends BaseController{


    private UserFundAccountService userFundAccountService;

    private UserFundAccountForSandpayService userFundAccountForSandpayService;

    private SandAccountService sandAccountService;

    private RechargeOrderService rechargeOrderService;

    private WithdrawApplyService withdrawApplyService;

    private UserBankCardRepo userBankCardRepo;

    private UniformPayUtil uniformPayUtil;

    private SandpayService sandpayService;

    private PaymentInfoRepo paymentInfoRepo;


    /**
     * 获取杉德账户
     * @return
     */
    @PostMapping("getAccount")
    public JSONObject getAccount(){
        User user = currentUser();
        UserFundAccount userFundAccount = userFundAccountForSandpayService.getAccount(user.getId());
        BalanceInfoDTO balanceInfoDTO = null;
        if(userFundAccount != null){
            //查询余额
            balanceInfoDTO = userFundAccountForSandpayService.getBalance(user.getId());
        }

        JSONObject res = new JSONObject();
        res.put("account", userFundAccount);
        res.put("balance", balanceInfoDTO);
        return res;
    }


    /**
     * 杉德账户开通短信
     * @return
     */
    @PostMapping("sendSmsCode")
    public JSONObject sendSmsCode(){
        User user = currentUser();
        JSONObject res = sandAccountService.validateCodeSend(user.getId(), user.getPhone());
        return res;
    }


    /**
     * 开通杉德钱包账户
     * @return
     */
    @PostMapping("register")
    public UserFundAccount register(@RequestParam String smsCode, @RequestParam String smsSerialNo){
        User user = currentUser();
        UserFundAccount account = userFundAccountForSandpayService.addAccount(user.getId(), smsCode, smsSerialNo);
        //自动绑卡
        UserBankCard userBankCard = userBankCardRepo.findByUserId(user.getId()).stream().findAny().orElse(null);
        if(userBankCard != null){
            userFundAccountForSandpayService.bindCard(userBankCard);
        }

        return account;
    }



    /**
     * 创建充值订单
     * @return
     */
    @PostMapping("createRecharge")
    public RechargeOrder createRecharge(@RequestBody RechargeOrderForm rechargeOrderDTO){
        User user = currentUser();
        rechargeOrderDTO.setUserId(user.getId());
        RechargeOrder rechargeOrder = userFundAccountForSandpayService.createRechargeOrder(rechargeOrderDTO);
        return rechargeOrder;
    }

    /**
     * 充值订单确认
     * @param orderNo
     * @param smsCode
     */
    @PostMapping("rechargeConfirm")
    public Map<String,Object> rechargeConfirm(@RequestParam String orderNo, @RequestParam String smsCode){
        Map<String,Object> resultMap = new HashMap<>();
        try{
            JSONObject res = userFundAccountForSandpayService.rechargeConfirm(orderNo, smsCode);
            resultMap.put("orderNo", orderNo);
            resultMap.put("feeAmt", res.getString("feeAmt"));
        }catch(RedisLockException e){
            throw new BusinessException("提交过于频繁，请稍后再试");
        }

        return resultMap;
    }


    /**
     * 创建提现订单
     * @return
     */
    @PostMapping("createWithdraw")
    public WithdrawApply createWithdraw(@RequestBody WithdrawApplyForm withdrawApplyDTO){
        User user = currentUser();
        withdrawApplyDTO.setUserId(user.getId());
        WithdrawApply withdrawApply = userFundAccountForSandpayService.createWithdrawApply(withdrawApplyDTO);
        return withdrawApply;
    }

    /**
     * 提现申请确认
     * @param orderNo
     * @param smsCode
     */
    @PostMapping("withdrawConfirm")
    public Map<String,Object> withdrawConfirm(@RequestParam String orderNo, @RequestParam String smsCode){
        Map<String,Object> resultMap = new HashMap<>();
        try{
            JSONObject res = userFundAccountForSandpayService.withdrawConfirm(orderNo, smsCode);
            resultMap.put("orderNo", orderNo);
            resultMap.put("feeAmt", res.getString("feeAmt"));
        }catch(RedisLockException e){
            throw new BusinessException("提交过于频繁，请稍后再试");
        }

        return resultMap;
    }


    /**
     * 钱包支付创建
     * @param id
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/payCreate", method = RequestMethod.GET)
    @ResponseBody
    public PaymentInfo payCreate(@RequestParam Long id) throws Exception {
        UniformPayRequest request = UniformPayRequest.builder().orderId(id)
                .tradeType(TradeType.WALLET_ACCOUNT).build();
        //仅支持杉德钱包
        request.setPayPlatform(UniformPayConstants.SANDPAY_PLATFORM);
        UniformPayResult result = uniformPayUtil.pay(request);
        OrderStatus orderStatus = result.getOrderStatus();
        if(orderStatus == OrderStatus.CANCELLED){
            throw new BusinessException("订单已被取消，请重新下单");
        }

        if(orderStatus != OrderStatus.NOT_PAID){
            throw new BusinessException("订单交易已完成，不能重复支付");
        }

        PaymentInfo paymentInfo =  paymentInfoRepo.findByOrderNo(result.getOrderNo())
                .orElseThrow(new BusinessException("支付创建失败"));
        return paymentInfo;
    }

    /**
     * 钱包支付确认
     * @return
     * @throws Exception
     */
    @PostMapping("payConfirm")
    public JSONObject payConfirm(@RequestParam String orderNo, @RequestParam String smsCode){
        //默认只支持杉德
        try {
            JSONObject res = sandpayService.accountPayConfirm(orderNo, smsCode);
            return res;
        }catch(RedisLockException e){
            throw new BusinessException("交易正在提交，请稍后再试");
        }

    }




}
