package com.ruoyi.xq.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.xq.domain.AccountChangeLog;
import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.dto.admin.log.AccountChangeLogAdminVo;
import com.ruoyi.xq.dto.admin.user.req.UpdateIncomeCoinReq;
import com.ruoyi.xq.dto.app.account.AccountDetailVo;
import com.ruoyi.xq.dto.common.user.MinUser;
import com.ruoyi.xq.enums.user.AccountCateEnum;
import com.ruoyi.xq.enums.user.AccountChangeCodeEnum;
import com.ruoyi.xq.mapper.AccountChangeLogMapper;
import com.ruoyi.xq.service.AccountChangeLogService;
import com.ruoyi.xq.service.UserService;
import com.ruoyi.xq.util.PageConvert;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 账户明细Service业务层处理
 *
 * @author 77
 * @date 2024-03-04
 */
@RequiredArgsConstructor
@Service
public class AccountChangeLogServiceImpl extends ServiceImpl<AccountChangeLogMapper,AccountChangeLog> implements AccountChangeLogService {

    @Autowired
    private UserService userService;

    @Override
    public void saveLogNoAdminOfConsumer(User user, AccountChangeCodeEnum accountChangeCodeEnum, BigDecimal price, String traceId, Long tarUserId) {
        AccountChangeLog accountChangeLog = new AccountChangeLog();
        accountChangeLog.setUserId(user.getId());
        accountChangeLog.setUsercode(user.getUsercode());
        accountChangeLog.setTarUserId(tarUserId);
        MinUser tarMinUser = userService.getMinUserById(tarUserId);
        if(tarMinUser != null){
            accountChangeLog.setTarUsercode(tarMinUser.getUsercode());
        }
        accountChangeLog.setCateId(accountChangeCodeEnum.getCate().getCode());
        accountChangeLog.setChangeType(accountChangeCodeEnum.getCode());
        accountChangeLog.setChangeValue(price);
        accountChangeLog.setTraceId(traceId);
        accountChangeLog.setIsAdmin(0);
        this.save(accountChangeLog);
    }

    @Override
    public void saveLogNoAdmin(Long userId, AccountChangeCodeEnum accountChangeCodeEnum, BigDecimal withdrawPrice, String traceId) {
        MinUser minUser = userService.getMinUserById(userId);
        AccountChangeLog accountChangeLog = new AccountChangeLog();
        accountChangeLog.setUserId(minUser.getId());
        accountChangeLog.setUsercode(minUser.getUsercode());
        accountChangeLog.setCateId(accountChangeCodeEnum.getCate().getCode());
        accountChangeLog.setChangeType(accountChangeCodeEnum.getCode());
        accountChangeLog.setChangeValue(withdrawPrice);
        accountChangeLog.setTraceId(traceId);
        accountChangeLog.setIsAdmin(0);
        this.save(accountChangeLog);
    }

    @Override
    public void saveLogAdminOfSystem(User user, AccountChangeCodeEnum accountChangeCodeEnum, UpdateIncomeCoinReq bo, LoginUser loginUser) {
        AccountChangeLog accountChangeLog = new AccountChangeLog();
        accountChangeLog.setUserId(user.getId());
        accountChangeLog.setUsercode(user.getUsercode());
        accountChangeLog.setCateId(accountChangeCodeEnum.getCate().getCode());
        accountChangeLog.setChangeType(accountChangeCodeEnum.getCode());
        accountChangeLog.setChangeValue(bo.getRechargeCoin());
        accountChangeLog.setRemark(bo.getRemark());
        accountChangeLog.setIsAdmin(1);
        if(loginUser != null){
            accountChangeLog.setAdminId(loginUser.getUserId());
            accountChangeLog.setAdminName(loginUser.getUsername());
        }
        this.save(accountChangeLog);
    }

    @Override
    public Page<AccountChangeLogAdminVo> pageAdmin(PageQuery pageQuery, AccountChangeLogAdminVo bo) {
        Page<AccountChangeLogAdminVo> result = baseMapper.pageAdmin(pageQuery.build(), bo);
        List<AccountChangeLogAdminVo> records = result.getRecords();
        List<Long> userIds = records.stream().map(AccountChangeLog::getUserId).collect(Collectors.toList());
        List<User> usersList = userService.listByIds(userIds);
        Map<Long, User> userMap = usersList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
        for (AccountChangeLogAdminVo record : records) {
            User user = userMap.get(record.getUserId());
            if(user != null){
                record.setNickname(user.getNickname());
                record.setAvatar(user.getAvatar());
                record.setMobile(user.getMobile());
            }
            AccountChangeCodeEnum accountChangeCodeEnum = AccountChangeCodeEnum.getByCode(record.getChangeType());
            if(accountChangeCodeEnum != null){
                AccountCateEnum cate = accountChangeCodeEnum.getCate();
                record.setCateName(cate.getText());
                switch (cate){
                    case SYSTEM_TRANS:
                        double price = record.getChangeValue().doubleValue();
                        String content = String.format("系统调整手动%s收益: %s", price > 0 ? "新增" : "减少", price);
                        record.setContent(content);
                        break;
                    case WITHDRAW:
                        record.setContent(accountChangeCodeEnum.getText());
                        break;
                    case AWARD_INVITE:
                        record.setContent(accountChangeCodeEnum.getText());
                        break;
                    default:
                        break;
                }
            }
        }
        return result;
    }

    @Override
    public Page<AccountDetailVo> pageApp(PageQuery pageQuery, Long userId) {
        Page<AccountChangeLog> page = this.page(pageQuery.build(),
                Wrappers.lambdaQuery(AccountChangeLog.class).eq(AccountChangeLog::getUserId, userId).orderByDesc(AccountChangeLog::getCreateTime));
        List<AccountChangeLog> records = page.getRecords();
        if(CollectionUtils.isEmpty(records)){
            return PageConvert.convertEmpty(page);
        }
        List<Long> userIds = new ArrayList<>();
        for (AccountChangeLog record : records) {
            if(record.getTarUserId() != null){
                userIds.add(record.getTarUserId());
            }
        }
        List<User> usersList = userService.listByIds(userIds);
        Map<Long, User> userMap = usersList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
        List<AccountDetailVo> vos = new ArrayList<>();
        for (AccountChangeLog record : records) {
            AccountDetailVo vo = new AccountDetailVo();
            vo.setUserId(record.getUserId());
            vo.setUsercode(record.getUsercode());
            vo.setCreateTime(record.getCreateTime());
            vo.setValue(record.getChangeValue());
            User user = userMap.get(record.getTarUserId());
            if(user != null){
                vo.setSourceUserId(user.getId());
                vo.setSourceNickname(user.getNickname());
                vo.setSourceImg(user.getAvatar());
            }
            AccountChangeCodeEnum accountChangeCodeEnum = AccountChangeCodeEnum.getByCode(record.getChangeType());
            if(accountChangeCodeEnum != null){
                AccountCateEnum cate = accountChangeCodeEnum.getCate();
                vo.setTitle(cate.getText());
                switch (cate){
                    case SYSTEM_TRANS:
                        double price = record.getChangeValue().doubleValue();
                        String content = String.format("系统调整手动%s收益: %s", price > 0 ? "新增" : "减少", price);
                        vo.setContent(content);
                        break;
                    case WITHDRAW:
                        vo.setContent(accountChangeCodeEnum.getText());
                        break;
                    case AWARD_INVITE:
                        vo.setContent(accountChangeCodeEnum.getText());
                        break;
                    default:
                        break;
                }
            }
            vos.add(vo);
        }
        return PageConvert.convert(page,vos);
    }


}
