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

import cn.hutool.core.util.NumberUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.BrandTypeEnum;
import com.kxs.common.core.constant.enums.ErrorTypeEnum;
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.model.KxsMachineAdvance;
import com.kxs.store.api.model.KxsWarehouseCreditAmount;
import com.kxs.store.api.vo.kxsapp.storeAdvance.AdvanceUserDetailVO;
import com.kxs.store.api.vo.kxsapp.storeLimit.WarehouseAmountVO;
import com.kxs.store.api.vo.kxsapp.userAdvance.AdvanceAmountVO;
import com.kxs.store.biz.constant.enums.StoreErrorTypeEnum;
import com.kxs.store.biz.constant.enums.StoreStatusEnum;
import com.kxs.store.biz.constant.enums.WarehouseLimitTypeEnum;
import com.kxs.store.biz.mapper.KxsMachineAdvanceMapper;
import com.kxs.store.biz.mapper.KxsWarehouseCreditAmountMapper;
import com.kxs.store.biz.mapper.KxsWarehouseLimitMapper;
import com.kxs.store.api.model.KxsWarehouseLimit;
import com.kxs.store.biz.service.KxsWarehouseLimitLogService;
import com.kxs.store.biz.service.KxsWarehouseLimitService;
import com.kxs.user.api.feign.RemoteKxsUserService;
import com.kxs.user.api.model.KxsUser;
import io.seata.core.context.RootContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

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

/**
 * 客小爽仓库额度表(KxsWarehouseLimit)表服务实现类
 *
 * @author 系统
 * @since 2024-01-08 09:46:02
 */
@Service("kxsWarehouseLimitService")
@RequiredArgsConstructor
@Slf4j
public class KxsWarehouseLimitServiceImpl extends ServiceImpl<KxsWarehouseLimitMapper, KxsWarehouseLimit> implements KxsWarehouseLimitService {

    private final RemoteKxsUserService remoteKxsUserService;

    private final KxsMachineAdvanceMapper kxsMachineAdvanceMapper;

    private final KxsWarehouseCreditAmountMapper kxsWarehouseCreditAmountMapper;

    @Override
    public AdvanceUserDetailVO getUserDetail(String userCode) {


        AdvanceUserDetailVO advanceUserDetailVO = new AdvanceUserDetailVO();

        R<KxsUser> kxsUserR = remoteKxsUserService.loadUserByCode(userCode, SecurityConstants.FROM_IN);
        KxsUser user = RetOps.of(kxsUserR)
                .getData()
                .orElseThrow(() -> new GlobalCustomerException(ErrorTypeEnum.USER_NOT_FOUND.getDescription()));
        advanceUserDetailVO.setUsername(user.getUsername());
        //预发额度
        KxsWarehouseLimit kxsWarehouseLimit = baseMapper.selectOne(Wrappers.<KxsWarehouseLimit>lambdaQuery().eq(KxsWarehouseLimit::getUserId, user.getId()));
        advanceUserDetailVO.setAdvanceAmount(kxsWarehouseLimit.getValidAmount());

        //预发机数量
        Long advanceCount = kxsMachineAdvanceMapper.selectUserByCount(user.getId());
        advanceUserDetailVO.setAdvanceTotal(advanceCount.intValue());

        return advanceUserDetailVO;
    }

    @Override
    public AdvanceAmountVO advanceAmount() {

        Long userId = SecurityUtils.getUser().getId();
        KxsWarehouseLimit kxsWarehouseLimit = baseMapper.selectOne(Wrappers.<KxsWarehouseLimit>lambdaQuery()
                .eq(KxsWarehouseLimit::getUserId, userId)
                .eq(KxsWarehouseLimit::getWarehouseType, WarehouseLimitTypeEnum.XFC.getType()));

        AdvanceAmountVO advanceAmountVO = new AdvanceAmountVO();

        BeanUtils.copyProperties(kxsWarehouseLimit, advanceAmountVO);

        advanceAmountVO.setTotalForAmt(NumberUtil.add(kxsWarehouseLimit.getForAmount(), kxsWarehouseLimit.getYueForAmount()));
        //可用额度大于等于临时总额度那就临时额度都可以提现 否则只能提现可用额度
        if(kxsWarehouseLimit.getValidAmount().compareTo(advanceAmountVO.getTotalForAmt()) >= 0){
            advanceAmountVO.setMaxSubAmt(advanceAmountVO.getTotalForAmt());
        }else{
            advanceAmountVO.setMaxSubAmt(kxsWarehouseLimit.getValidAmount());
        }
        advanceAmountVO.setTotalAmount(NumberUtil.add(kxsWarehouseLimit.getFixedAmount(), advanceAmountVO.getTotalForAmt()));
        return advanceAmountVO;
    }

    @Override
    public WarehouseAmountVO warehouseAmount() {

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

        KxsWarehouseLimit kxsWarehouseLimit = baseMapper.selectOne(Wrappers.<KxsWarehouseLimit>lambdaQuery()
                .eq(KxsWarehouseLimit::getUserId, userId)
                .eq(KxsWarehouseLimit::getWarehouseType, WarehouseLimitTypeEnum.FC.getType()));
        Optional.ofNullable(kxsWarehouseLimit).orElseThrow(() -> new GlobalCustomerException(StoreErrorTypeEnum.WAREHOUSE_NOT_FIND.getDescription()));
        WarehouseAmountVO warehouseAmountVO = new WarehouseAmountVO();
        BeanUtils.copyProperties(kxsWarehouseLimit, warehouseAmountVO);

        //统计为他人担保额度
        KxsWarehouseCreditAmount creditUserAmount = kxsWarehouseCreditAmountMapper.selectOne(Wrappers.query(KxsWarehouseCreditAmount.class)
                .select("IFNULL(SUM(credit_amount), 0) as creditAmount")
                .eq("status", StoreStatusEnum.C_ON_CFM.getType())
                .eq("credit_user_id", userId));
        if(creditUserAmount != null){
            warehouseAmountVO.setToCreditAmount(creditUserAmount.getCreditAmount());
        }
        warehouseAmountVO.setTotalForAmt(NumberUtil.add(kxsWarehouseLimit.getForAmount(), kxsWarehouseLimit.getYueForAmount()));

        //可用额度大于等于临时总额度那就临时额度都可以提现 否则只能提现可用额度
        if(kxsWarehouseLimit.getValidAmount().compareTo(warehouseAmountVO.getTotalForAmt()) >= 0){
            warehouseAmountVO.setMaxSubAmt(warehouseAmountVO.getTotalForAmt());
        }else{
            warehouseAmountVO.setMaxSubAmt(kxsWarehouseLimit.getValidAmount().compareTo(BigDecimal.ZERO) > 0 ? kxsWarehouseLimit.getValidAmount() : BigDecimal.ZERO);
        }
        warehouseAmountVO.setTotalAmount(NumberUtil.add(kxsWarehouseLimit.getCreditAmount(), warehouseAmountVO.getTotalForAmt(), kxsWarehouseLimit.getFixedAmount()));
        return warehouseAmountVO;
    }

    @Override
    public void refreshUserAmount(Integer userId, Integer amount, String kind) {
        //查询用户额度
        KxsWarehouseLimit userLimit = baseMapper.selectOne(Wrappers.<KxsWarehouseLimit>lambdaQuery()
                .eq(KxsWarehouseLimit::getWarehouseType, WarehouseLimitTypeEnum.XFC.getType())
                .eq(KxsWarehouseLimit::getUserId, userId));

        if(KindTypeEnum.ADD.getType().equals(kind)){
            //已用额度增加
//            userLimit.setUsedAmount(NumberUtil.add(userLimit.getUsedAmount(), amount));
            //可用额度减少
            userLimit.setValidAmount(NumberUtil.sub(userLimit.getValidAmount(), amount));
        }else{
            //已用额度减少
//            userLimit.setUsedAmount(NumberUtil.sub(userLimit.getUsedAmount(), amount));
            //可用额度增加
            userLimit.setValidAmount(NumberUtil.add(userLimit.getValidAmount(), amount));
        }

        baseMapper.updateById(userLimit);
    }

    @Override
    public void refreshWarehouseAmount(Integer userId, int amount, String kind) {

        //查询仓库额度
        KxsWarehouseLimit warehouseLimit = baseMapper.selectOne(Wrappers.<KxsWarehouseLimit>lambdaQuery()
                .eq(KxsWarehouseLimit::getWarehouseType, WarehouseLimitTypeEnum.FC.getType())
                .eq(KxsWarehouseLimit::getUserId, userId));

        if(KindTypeEnum.ADD.getType().equals(kind)){
            //已用额度增加
//            warehouseLimit.setUsedAmount(NumberUtil.add(warehouseLimit.getUsedAmount(), amount));
            //可用额度减少
            warehouseLimit.setValidAmount(NumberUtil.sub(warehouseLimit.getValidAmount(), amount));
        }else{
            //已用额度减少
//            warehouseLimit.setUsedAmount(NumberUtil.sub(warehouseLimit.getUsedAmount(), amount));
            //可用额度增加
            warehouseLimit.setValidAmount(NumberUtil.add(warehouseLimit.getValidAmount(), amount));
        }

        baseMapper.updateById(warehouseLimit);

    }

    @Override
    public Boolean addUserAdvanceLimit(KxsWarehouseLimit kxsWarehouseLimit) {

        //查询用户预发额度
        KxsWarehouseLimit warehouseLimit = baseMapper.selectOne(Wrappers.<KxsWarehouseLimit>lambdaQuery()
                .eq(KxsWarehouseLimit::getWarehouseType, WarehouseLimitTypeEnum.XFC.getType())
                .eq(KxsWarehouseLimit::getUserId, kxsWarehouseLimit.getUserId()));

        if(warehouseLimit == null){
            kxsWarehouseLimit.setWarehouseType(WarehouseLimitTypeEnum.XFC.getType());
            baseMapper.insert(kxsWarehouseLimit);
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean addForAmount(KxsWarehouseLimit param) {

        if(param.getWarehouseType() == null){
            return Boolean.FALSE;
        }

        //查询仓库/小分仓额度 加锁查询
        KxsWarehouseLimit warehouseLimit = baseMapper.selectOne(Wrappers.<KxsWarehouseLimit>lambdaQuery()
                .eq(KxsWarehouseLimit::getWarehouseType, param.getWarehouseType())
                .eq(KxsWarehouseLimit::getUserId, param.getUserId()).last("FOR UPDATE"));

        log.info("仓库/小分仓临时增加:{}", JSON.toJSONString(param));
        if(warehouseLimit == null){
            return Boolean.FALSE;
        }
        //支付宝临时额度 可用额度增加
        if(param.getForAmount() != null){
            warehouseLimit.setForAmount(param.getForAmount().add(warehouseLimit.getForAmount()));
            warehouseLimit.setValidAmount(warehouseLimit.getValidAmount().add(param.getForAmount()));
        }
        //余额临时额度 可用额度增加
        if(param.getYueForAmount() != null){
            warehouseLimit.setYueForAmount(param.getYueForAmount().add(warehouseLimit.getYueForAmount()));
            warehouseLimit.setValidAmount(warehouseLimit.getValidAmount().add(param.getYueForAmount()));
        }
        return update(Wrappers.<KxsWarehouseLimit>lambdaUpdate()
                .eq(KxsWarehouseLimit::getId, warehouseLimit.getId())
                .set(KxsWarehouseLimit::getValidAmount, warehouseLimit.getValidAmount())
                .set(KxsWarehouseLimit::getForAmount, warehouseLimit.getForAmount())
                .set(KxsWarehouseLimit::getYueForAmount, warehouseLimit.getYueForAmount()));
    }


}

