package com.ruoyi.cai.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.*;
import com.ruoyi.cai.dto.app.dto.GuardNum;
import com.ruoyi.cai.dto.app.query.GiveGuardReq;
import com.ruoyi.cai.dto.app.dto.GuardTotalDTO;
import com.ruoyi.cai.dto.app.vo.index.GuardIndexVo;
import com.ruoyi.cai.dto.app.vo.index.GuardListPageVo;
import com.ruoyi.cai.enums.ConsumeLogType;
import com.ruoyi.cai.enums.SystemConfigEnum;
import com.ruoyi.cai.manager.SystemConfigManager;
import com.ruoyi.cai.mapper.GuardTotalMapper;
import com.ruoyi.cai.service.*;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 守护用户累计Service业务层处理
 *
 * @author 77
 * @date 2023-12-23
 */
@Service
public class GuardTotalServiceImpl extends ServiceImpl<GuardTotalMapper, GuardTotal> implements GuardTotalService {

    @Autowired
    private UserService userService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private AnchorService anchorService;
    @Autowired
    private GuardLogService guardLogService;
    @Autowired
    private SystemConfigManager systemConfigManager;

    @Override
    public GuardIndexVo guardInfoVo(Long fromUserId, Long toUserId, Integer limit) {
        GuardIndexVo vo = new GuardIndexVo();
        vo.setGuardPrice(systemConfigManager.getSystemConfigOfLong(SystemConfigEnum.GUARD_PRICE));
        // 查询守护总数
        Long count = baseMapper.guardCount(toUserId);
        if(count > 0){
            List<GuardTotalDTO> total = baseMapper.selectGuardTotal(toUserId, limit);
            GuardTotalDTO maxUser = total.get(0);
            vo.setUserList(total.stream().map(GuardTotalDTO::getAvatar).collect(Collectors.toList()));
            vo.setNickname(maxUser.getNickname());
            vo.setAvatar(maxUser.getAvatar());
            vo.setUserId(maxUser.getToUserId());
            vo.setGuardSymbolTotal(count);
            // 获取总数总人数
            vo.setGuardPersonTotal(baseMapper.guardPersonCount(toUserId));
            // 获取差距
            GuardNum guardNum = this.getGuardNum(fromUserId, toUserId);
            vo.setDiffNum(guardNum.getDiffNum());
        }
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean giveGuard(GiveGuardReq query) {
        Long fromUserId = LoginHelper.getUserId();
        User fromUser = userService.getById(fromUserId);
        User toUser = userService.getById(query.getToUserId());
        if(toUser == null){
            throw new ServiceException("女神不存在");
        }
        if(toUser.getIsAnchor() != 1){
            throw new ServiceException("只能给女神送守护");
        }
        Anchor anchor = anchorService.getByUserId(toUser.getId());
        if(anchor == null){
            throw new ServiceException("女神不存在");
        }
        Long guardPrice = systemConfigManager.getSystemConfigOfLong(SystemConfigEnum.GUARD_PRICE);
        if(!query.getGuardPrice().equals(guardPrice)){
            throw new ServiceException("守护价格发生变化");
        }
        Long guardValue = query.getGuardNum() * guardPrice;
        CaiConsumeLog consumeLog = new CaiConsumeLog();
        consumeLog.init(fromUser,toUser);
        consumeLog.setType(ConsumeLogType.GUARD.getCode());
        consumeLog.setAmount(guardValue);
        consumeLog.setTargetRate(anchor.getGuardRate());
        consumeLog = accountService.decr(consumeLog);
        GuardLog guardLog = new GuardLog();
        guardLog.setFromUserId(fromUserId);
        guardLog.setFromUsercode(fromUser.getUsercode());
        guardLog.setFromMobile(fromUser.getMobile());
        guardLog.setToUserId(query.getToUserId());
        guardLog.setToMobile(toUser.getMobile());
        guardLog.setToUsercode(toUser.getUsercode());
        guardLog.setGuardNum(query.getGuardNum());
        guardLog.setGuardValue(guardValue);
        guardLog.setGuardPrice(guardPrice);
        guardLog.setConsumeLogId(consumeLog.getId());
        guardLogService.save(guardLog);
        GuardTotal one = this.getOne(Wrappers.lambdaQuery(GuardTotal.class)
                .eq(GuardTotal::getToUserId, query.getToUserId())
                .eq(GuardTotal::getFromUserId, fromUserId));
        if(one == null){
            one = new GuardTotal();
            one.setFromUserId(fromUserId);
            one.setFromUsercode(fromUser.getUsercode());
            one.setFromMobile(fromUser.getMobile());
            one.setToUserId(query.getToUserId());
            one.setToMobile(toUser.getMobile());
            one.setToUsercode(toUser.getUsercode());
            this.save(one);
        }
        baseMapper.incs(fromUserId,query.getToUserId(),query.getGuardNum(),guardValue);
        return true;
    }

    @Override
    public GuardNum getGuardNum(Long fromUserId, Long toUserId){
        GuardNum num = new GuardNum();
        GuardTotal one = this.getOne(Wrappers.lambdaQuery(GuardTotal.class)
                .select(GuardTotal::getGuardNum)
                .eq(GuardTotal::getFromUserId, fromUserId)
                .eq(GuardTotal::getToUserId, toUserId)
                .last("limit 1"));
        Long myGuardNum = one == null ? 0 : one.getGuardNum();
        GuardTotal up = this.getOne(Wrappers.lambdaQuery(GuardTotal.class)
                .eq(GuardTotal::getToUserId, toUserId)
                .ge(GuardTotal::getGuardNum, myGuardNum)
                .orderByAsc(GuardTotal::getGuardNum)
                .last("limit 1"));
        Long upGuardNum = up == null ? 0L : up.getGuardNum();
        num.setMyGuardNum(myGuardNum);
        num.setUpGuardNum(upGuardNum);
        num.setDiffNum((upGuardNum - myGuardNum) < 0 ? 0 : (upGuardNum - myGuardNum));
        return num;
    }

    @Override
    public Page<GuardListPageVo> userGuardPage(PageQuery pageQuery,Long toUserId) {
        return baseMapper.userGuardPage(pageQuery.build(),toUserId);
    }
}
