package com.kxs.store.biz.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kxs.common.core.constant.SecurityConstants;
import com.kxs.common.core.constant.enums.AmountLogChangeTypesEnum;
import com.kxs.common.core.constant.enums.KindTypeEnum;
import com.kxs.common.core.exception.GlobalCustomerException;
import com.kxs.common.core.util.R;
import com.kxs.common.core.util.RetOps;
import com.kxs.common.security.util.SecurityUtils;
import com.kxs.store.api.dto.kxsapp.storeLimit.ForAmountWithdrawDTO;
import com.kxs.store.api.model.KxsWarehouseLimit;
import com.kxs.store.biz.constant.enums.StoreErrorTypeEnum;
import com.kxs.store.biz.constant.enums.WarehouseLimitTypeEnum;
import com.kxs.store.biz.mapper.KxsForAmountWithdrawMapper;
import com.kxs.store.api.model.KxsForAmountWithdraw;
import com.kxs.store.biz.mapper.KxsWarehouseLimitMapper;
import com.kxs.store.biz.service.KxsForAmountWithdrawService;
import com.kxs.user.api.feign.RemoteKxsUserService;
import com.kxs.user.api.model.KxsUserAmountLog;
import com.kxs.user.api.vo.kxsapp.user.RealUserInfoVO;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Objects;

/**
 * 客小爽仓库临额提现申请表(KxsForAmountWithdraw)表服务实现类
 *
 * @author 系统
 * @since 2024-01-08 09:46:02
 */
@Service("kxsForAmountWithdrawService")
@RequiredArgsConstructor
public class KxsForAmountWithdrawServiceImpl extends ServiceImpl<KxsForAmountWithdrawMapper, KxsForAmountWithdraw> implements KxsForAmountWithdrawService {

    private final RemoteKxsUserService  remoteKxsUserService;

    private final KxsWarehouseLimitMapper kxsWarehouseLimitMapper;

    @Override
    @GlobalTransactional
    public R forAmountWithdraw(ForAmountWithdrawDTO param) {

        Long userId = SecurityUtils.getUser().getId();

        //查询实名信息
        R<RealUserInfoVO> realUserInfoR = remoteKxsUserService.loadUserRealBankById(userId.intValue(), SecurityConstants.FROM_IN);
        RealUserInfoVO realUserInfoVO = RetOps.of(realUserInfoR)
                .getData()
                .orElseThrow(() -> new GlobalCustomerException(StoreErrorTypeEnum.DATA_ERROR.getDescription()));

        KxsForAmountWithdraw kxsForAmountWithdraw = new KxsForAmountWithdraw();
        kxsForAmountWithdraw.setUserId(userId.intValue());
        kxsForAmountWithdraw.setIdCard(realUserInfoVO.getIdCard());
        kxsForAmountWithdraw.setBankCode(realUserInfoVO.getBankCode());
        kxsForAmountWithdraw.setUsername(realUserInfoVO.getRealName());
        kxsForAmountWithdraw.setUserCode(realUserInfoVO.getUserCode());
        kxsForAmountWithdraw.setBankName(realUserInfoVO.getBankName());
        kxsForAmountWithdraw.setBankPhone(realUserInfoVO.getPhone());
        kxsForAmountWithdraw.setAmountType(param.getAmountType());
        kxsForAmountWithdraw.setWithdrawType(param.getWhsType());

        KxsWarehouseLimit userLimit = kxsWarehouseLimitMapper.selectOne(Wrappers.<KxsWarehouseLimit>lambdaQuery()
                .eq(KxsWarehouseLimit::getWarehouseType, param.getWhsType())
                .eq(KxsWarehouseLimit::getUserId, userId));

        //临时额度总和
        BigDecimal totalForAmt = NumberUtil.add(userLimit.getYueForAmount(), userLimit.getForAmount());

        if(param.getAmount().compareTo(userLimit.getValidAmount()) > 0){
            return R.failed("可用额度不足");
        }

        if(param.getAmount().compareTo(totalForAmt) > 0){
            return R.failed("临额不足");
        }
        //余额提现
        if(param.getAmountType() == 0){

            yueWithdrawAmount(kxsForAmountWithdraw, param, userLimit);
        }
        //银行卡提现
        if(param.getAmountType() == 1){
            bankWithdrawAmount(kxsForAmountWithdraw, param, userLimit);
        }

        return R.ok();

    }


    /**
     * 提现到银行卡
     *
     * @param kxsForAmountWithdraw KXS 提取金额
     * @param param                参数
     * @param userLimit            用户限制
     */
    private void bankWithdrawAmount(KxsForAmountWithdraw kxsForAmountWithdraw, ForAmountWithdrawDTO param, KxsWarehouseLimit userLimit) {
        //银行卡最大提现金额
        BigDecimal bankCashAmount = userLimit.getForAmount();
        //银行卡提现
        if(param.getAmount().compareTo(bankCashAmount) > 0){
            throw new GlobalCustomerException("提现到银行卡超出限额");
        }
        kxsForAmountWithdraw.setAmount(param.getAmount());
        baseMapper.insert(kxsForAmountWithdraw);

        //扣减可用余额，扣减临额
        userLimit.setForAmount(NumberUtil.sub(userLimit.getForAmount(),param.getAmount()));
        userLimit.setValidAmount(NumberUtil.sub(userLimit.getValidAmount(),param.getAmount()));
        kxsWarehouseLimitMapper.updateById(userLimit);

    }

    /**
     * 提现到余额
     *
     * @param kxsForAmountWithdraw KXS 提取金额
     * @param param                参数
     * @param userLimit            用户限制
     */
    public void yueWithdrawAmount(KxsForAmountWithdraw kxsForAmountWithdraw, ForAmountWithdrawDTO param, KxsWarehouseLimit userLimit){

        //余额最大提现金额
        BigDecimal yueCashAmount = userLimit.getYueForAmount();
        //余额提现
        if(param.getAmount().compareTo(yueCashAmount) > 0){
            throw new GlobalCustomerException("提现到余额超出限额");
        }
        kxsForAmountWithdraw.setAmount(param.getAmount());
        kxsForAmountWithdraw.setStatus(1);
        baseMapper.insert(kxsForAmountWithdraw);

        //扣减可用余额，扣减临额
        userLimit.setYueForAmount(NumberUtil.sub(userLimit.getYueForAmount(), param.getAmount()));
        userLimit.setValidAmount(NumberUtil.sub(userLimit.getValidAmount(), param.getAmount()));
        kxsWarehouseLimitMapper.updateById(userLimit);

        KxsUserAmountLog userAmountLog = new KxsUserAmountLog();
        userAmountLog.setUserId(kxsForAmountWithdraw.getUserId());
        userAmountLog.setKind(KindTypeEnum.ADD.getType());
        //分仓临时额度提现
        if(Objects.equals(param.getWhsType(), WarehouseLimitTypeEnum.FC.getType())){
            userAmountLog.setVariationType(AmountLogChangeTypesEnum.FOR_WILL_BE_REFUNDED.getType());
            userAmountLog.setRemark(AmountLogChangeTypesEnum.FOR_WILL_BE_REFUNDED.getDescription());
        }else{
            userAmountLog.setVariationType(AmountLogChangeTypesEnum.ADVANCE_ISSUANCE_TEMPORARY_QUOTA_REFUND.getType());
            userAmountLog.setRemark(AmountLogChangeTypesEnum.ADVANCE_ISSUANCE_TEMPORARY_QUOTA_REFUND.getDescription());
        }
        userAmountLog.setAmount(param.getAmount());

        R<Boolean> booleanR = remoteKxsUserService.userAmountChange(userAmountLog, SecurityConstants.FROM_IN);
        if(booleanR.getStatus() == 1 && !booleanR.getData()){
            throw new GlobalCustomerException("提现申请失败");
        }

    }















}

