package com.ruoyi.cai.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.*;
import com.ruoyi.cai.enums.ConsumeLogStatus;
import com.ruoyi.cai.enums.ConsumeLogType;
import com.ruoyi.cai.enums.account.AccountChangeCodeEnum;
import com.ruoyi.cai.mapper.ConsumeLogMapper;
import com.ruoyi.cai.service.*;
import com.ruoyi.cai.util.NumCaUtil;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

/**
 * 消费记录Service业务层处理
 *
 * @author 77
 * @date 2023-12-24
 */
@Service
@Slf4j
public class ConsumeLogServiceImpl extends ServiceImpl<ConsumeLogMapper, ConsumeLog> implements ConsumeLogService {
    @Autowired
    private UserInviteService userInviteService;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private UserService userService;
    @Autowired
    private UnionUserService unionUserService;
    @Autowired
    private UnionService unionService;
    @Autowired
    private AccountService accountService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dealFenxiao(Long id,boolean system){
        ConsumeLog consumer = this.getById(id);
        if(consumer == null){
            return;
        }
        if(!ConsumeLogStatus.READY.getCode().equals(consumer.getStatus())){
            // 已经分销完成，无需继续分销
            return;
        }
        if(!BooleanUtils.isTrue(consumer.getCalculateStatus())){
            // 先计算
            boolean update = this.update(Wrappers.lambdaUpdate(ConsumeLog.class)
                    .eq(ConsumeLog::getId, id)
                    .eq(ConsumeLog::getCalculateStatus, false)
                    .set(ConsumeLog::getOpCreate, LocalDateTime.now())
                    .set(ConsumeLog::getCalculateStatus, true));
            if(update){
                consumer = calculateInitFenxiao(consumer);
                consumer.setCalculateStatus(true);
                this.updateById(consumer);
            }
        }
        String opName = "system";
        Long opId = null;
        if(!system){
            LoginUser loginUser = LoginHelper.getLoginUser();
            if(loginUser != null){
                opName = loginUser.getUsername();
                opId = loginUser.getUserId();
            }
        }
        // 在分销
        boolean update = this.update(Wrappers.lambdaUpdate(ConsumeLog.class)
                .eq(ConsumeLog::getId, id)
                .eq(ConsumeLog::getStatus, ConsumeLogStatus.READY.getCode())
                .set(ConsumeLog::getOpName, opName)
                .set(ConsumeLog::getOpId, opId)
                .set(ConsumeLog::getStatus, ConsumeLogStatus.ALREADY.getCode()));
        if(!update){
            log.error("无需分销 consumer={}", JSON.toJSONString(consumer));
            return;
        }
        ConsumeLogType code = ConsumeLogType.getByCode(consumer.getType());
        if(code == null){
            log.error("分销失败 BusinessEnum状态错误! consumerLog={}",JSON.toJSONString(consumer));
            throw new ServiceException("分销失败！请联系管理员排查问题！");
        }
        try {
            // 计算一级
            if(consumer.getOneUserId() != null && BooleanUtils.isTrue(consumer.getOneJoin())
                    && consumer.getOneAmount() > 0){
                AccountChangeCodeEnum changeCodeEnum = ConsumeLogType.getOneInviteChange(code);
                accountService.distribution(consumer,consumer.getOneUserId(),consumer.getOneAmount(),changeCodeEnum);
            }
            // 计算工会
            if(consumer.getUnionUserId() != null && BooleanUtils.isTrue(consumer.getUnionJoin())
                    && consumer.getUnionAmount() > 0){
                AccountChangeCodeEnum changeCodeEnum = ConsumeLogType.getUnionChange(code);
                accountService.distribution(consumer,consumer.getUnionUserId(),consumer.getUnionAmount(),changeCodeEnum);
            }
        }catch (Exception e){
            log.error("分销发生未知错误，请联系开发检查!",e);
        }
    }

    @Override
    public ConsumeLog calculateInitFenxiao(ConsumeLog consumeLog){
        if(ConsumeLogType.RECHARGE.getCode().equals(consumeLog.getType())){
            Long sourceUserId = consumeLog.getSourceUserId();
            UserInvite userInvite = userInviteService.getByUserId(sourceUserId);
            if(userInvite != null){
                User oneUser = userService.getById(userInvite.getInviteId());
                if(oneUser != null && oneUser.getStatus() == 0){
                    UserInfo userInfo = userInfoService.getByUserId(userInvite.getUserId());
                    consumeLog.setOneRate(userInfo.getPayIncomeRate());
                    consumeLog.setOneUserId(userInvite.getInviteId());
                    consumeLog.setOneUsercode(oneUser.getUsercode());
                    consumeLog.setOnePhone(oneUser.getMobile());
                    consumeLog.setOneJoin(userInvite.getEnableRate());
                    consumeLog.setOneIsUnion(oneUser.getIsUnion());
                    consumeLog.setOneAmount(NumCaUtil.coin(consumeLog.getAmount(),consumeLog.getOneRate()));
                }
            }
            consumeLog.setCalculateStatus(true);
            return consumeLog;
        }
        Long targetUserId = consumeLog.getTargetUserId();
        if(targetUserId != null){
            // 获取一级分销
            UserInvite userInvite = userInviteService.getByUserId(targetUserId);
            if(userInvite != null){
                User oneUser = userService.getById(userInvite.getInviteId());
                if(oneUser != null && oneUser.getStatus() == 0){
                    UserInfo userInfo = userInfoService.getByUserId(userInvite.getUserId());
                    if(ConsumeLogType.GUARD.getCode().equals(consumeLog.getType())){
                        consumeLog.setOneRate(userInfo.getGuardIncomeRate());
                    }else if(ConsumeLogType.GIFT.getCode().equals(consumeLog.getType())){
                        consumeLog.setOneRate(userInfo.getGiftIncomeRate());
                    }else if(ConsumeLogType.VIDEO.getCode().equals(consumeLog.getType())){
                        consumeLog.setOneRate(userInfo.getVideoIncomeRate());
                    }
                    consumeLog.setOneUserId(userInvite.getInviteId());
                    consumeLog.setOneUsercode(oneUser.getUsercode());
                    consumeLog.setOnePhone(oneUser.getMobile());
                    consumeLog.setOneJoin(userInvite.getEnableRate());
                    consumeLog.setOneIsUnion(oneUser.getIsUnion());
                    consumeLog.setOneAmount(NumCaUtil.coin(consumeLog.getAnchorAmount(),consumeLog.getOneRate()));
                }
            }
            // 工会分销 只有通话和礼物才有
            if(ConsumeLogType.GIFT.getCode().equals(consumeLog.getType())
                    || ConsumeLogType.VIDEO.getCode().equals(consumeLog.getType())){
                UnionUser unionUser = unionUserService.getByUserId(targetUserId);
                if(unionUser != null){
                    User user = userService.getById(unionUser.getUnionUserId());
                    if(user != null && user.getIsUnion() == 1 && user.getStatus() == 0){
                        Union union = unionService.getById(unionUser.getUnionId());
                        if(union != null){
                            consumeLog.setUnionUsercode(user.getUsercode());
                            consumeLog.setUnionPhone(user.getMobile());
                            consumeLog.setUnionUserId(user.getId());
                            consumeLog.setUnionJoin(false);
                            if(unionUser.getEnableRate() && union.getEnableRate()){
                                consumeLog.setUnionJoin(true);
                            }
                            if(ConsumeLogType.GIFT.getCode().equals(consumeLog.getType())){
                                consumeLog.setUnionRate(unionUser.getGiftDivide());
                            }else if(ConsumeLogType.VIDEO.getCode().equals(consumeLog.getType())){
                                consumeLog.setUnionRate(unionUser.getVideoDivide());
                            }
                            consumeLog.setUnionAmount(NumCaUtil.coin(consumeLog.getAnchorAmount(),consumeLog.getUnionRate()));
                        }
                    }
                }
            }
        }
        consumeLog.setCalculateStatus(true);
        return consumeLog;
    }

}
