package cn.pluss.platform.userAccount.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.pluss.platform.entity.UserAccount;
import cn.pluss.platform.entity.UserAccountFlow;
import cn.pluss.platform.entity.UserExtra;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mapper.UserAccountFlowMapper;
import cn.pluss.platform.mapper.UserAccountMapper;
import cn.pluss.platform.mapper.UserExtraMapper;
import cn.pluss.platform.user.UserExtraService;
import cn.pluss.platform.userAccount.UserAccountService;
import cn.pluss.platform.util.N;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

@Service
public class UserAccountServiceImpl extends ServiceImpl<UserAccountMapper, UserAccount> implements UserAccountService {


    @Autowired
    private UserAccountMapper userAccountMapper;

    @Autowired
    private UserAccountFlowMapper userAccountFlowMapper;

    @Override
    public UserAccount getUserAccountByUserId(Integer userId) {
        return userAccountMapper.selectUserByUserId(userId,1);
    }

    @Override
    public UserAccount getUserAccountByUserId(Long userId) {
        return baseMapper.selectUserByUserId(userId.intValue(),1);
    }

    @Override
    public UserAccount getUserAccountByUserIdForUpdate(Integer userId) {
        return userAccountMapper.selectUserByUserId(userId);
    }



    public UserAccount initUserAccount(Integer userId){
        Assert.notNull(userId, "NOt Null");
        synchronized (this){
            UserAccount userAccount=getUserAccountByUserId(userId);
            if(ObjectUtil.isEmpty(userAccount)){
                userAccount=new UserAccount();
                userAccount.setUserId(userId);
                userAccount.setFreezeBalance(BigDecimal.ZERO);
                userAccount.setBalance(BigDecimal.ZERO);
                userAccount.setOutBalance(BigDecimal.ZERO);
                userAccount.setCreateTime(new Date());
                userAccount.setUpdateTime(new Date());
                int result=baseMapper.insert(userAccount);
                if(result<1){
                    MsgException.checkNull(null,"账户信息不存在");
                }
            }

            return userAccount;
        }
    }





    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.MANDATORY)
    public void modForzenFunds(Integer userId, String bizCode, String bizName, BigDecimal difference, String remark) {
        Assert.notNull(userId, "NOt Null");
        Assert.notNull(bizCode, "Not Null");
        Assert.notNull(bizName, "Not Null");
        Assert.notNull(difference, "Not Null");

        UserAccount userAccount= initUserAccount(userId);
        if(N.gt(BigDecimal.ZERO,difference)){
            difference=difference.abs().negate();
        }
        if(N.gt(difference,BigDecimal.ZERO)){
            difference=difference.abs();
        }


        userAccountMapper.updateFreezon(userId,difference);


        UserAccountFlow flow=new UserAccountFlow();

        flow.setUserId(userId);
        flow.setBizCode(bizCode);
        flow.setBizName(bizName);
        flow.setAmount(difference.abs());
        flow.setBalance(userAccount.getBalance());
        flow.setCreateTime(new Date());
        userAccountFlowMapper.insert(flow);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.MANDATORY)
    public void modFunds(Integer userId, String bizCode, String bizName, BigDecimal difference, String remark) {
        Assert.notNull(userId, "NOt Null");
        Assert.notNull(bizCode, "Not Null");
        Assert.notNull(bizName, "Not Null");
        Assert.notNull(difference, "Not Null");

        UserAccount userAccount= initUserAccount(userId);
        if(N.gt(BigDecimal.ZERO,difference)){
            difference=difference.abs().negate();
        }
        if(N.gt(difference,BigDecimal.ZERO)){
            difference=difference.abs();
        }


        userAccount.setBalance(userAccount.getBalance().add(difference));
        userAccount.setUpdateTime(new Date());
        userAccountMapper.updateById(userAccount);

        UserAccountFlow flow=new UserAccountFlow();
        flow.setUserId(userId);
        flow.setBizCode(bizCode);
        flow.setBizName(bizName);
        flow.setAmount(difference.abs());
        flow.setBalance(userAccount.getBalance());
        flow.setCreateTime(new Date());
        userAccountFlowMapper.insert(flow);

    }
}
