package top.continew.admin.business.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.continew.admin.business.mapper.PlantformBalanceMapper;
import top.continew.admin.business.model.entity.FreeQuotaConfigDO;
import top.continew.admin.business.model.entity.PlantformBalanceDO;
import top.continew.admin.business.model.req.FreeQuotaGrantReq;
import top.continew.admin.business.model.resp.FreeQuotaGrantResp;
import top.continew.admin.business.service.FreeQuotaConfigService;
import top.continew.admin.business.service.FreeQuotaGrantService;
import top.continew.admin.system.mapper.UserMapper;
import top.continew.admin.system.model.entity.UserDO;
import top.continew.starter.core.exception.BusinessException;

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

/**
 * 免费额度赠送服务实现
 *
 * @author jiay
 * @since 2025/11/17
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FreeQuotaGrantServiceImpl implements FreeQuotaGrantService {

    private final FreeQuotaConfigService freeQuotaConfigService;
    private final PlantformBalanceMapper plantformBalanceMapper;
    private final UserMapper userMapper;

    /**
     * 批量赠送免费额度
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FreeQuotaGrantResp batchGrant(FreeQuotaGrantReq req) {
        List<String> logs = new ArrayList<>();
        List<Long> allUserIds = new ArrayList<>();

        // 1. 收集所有用户ID
        if (CollUtil.isNotEmpty(req.getUserIds())) {
            allUserIds.addAll(req.getUserIds());
            logs.add("指定用户数: " + req.getUserIds().size());
        }

        if (CollUtil.isNotEmpty(req.getDeptIds())) {
            for (Long deptId : req.getDeptIds()) {
                List<UserDO> deptUsers = userMapper.selectList(new LambdaQueryWrapper<UserDO>()
                    .eq(UserDO::getDeptId, deptId));
                List<Long> deptUserIds = deptUsers.stream().map(UserDO::getId).collect(Collectors.toList());
                allUserIds.addAll(deptUserIds);
                logs.add(StrUtil.format("部门ID {} 用户数: {}", deptId, deptUserIds.size()));
            }
        }

        if (CollUtil.isEmpty(allUserIds)) {
            throw new BusinessException("未找到需要赠送的用户");
        }

        // 去重
        allUserIds = allUserIds.stream().distinct().collect(Collectors.toList());
        logs.add("总用户数(去重后): " + allUserIds.size());

        // 2. 准备赠送配置
        List<FreeQuotaGrantReq.QuotaItem> quotaItems;
        if (CollUtil.isNotEmpty(req.getQuotaItems())) {
            // 使用自定义配置
            quotaItems = req.getQuotaItems()
                .stream()
                .filter(item -> item.getEnabled() != null && item.getEnabled())
                .collect(Collectors.toList());
            logs.add("使用自定义配置，项数: " + quotaItems.size());
        } else {
            // 使用默认配置
            List<FreeQuotaConfigDO> configs = freeQuotaConfigService.listEnabled();
            quotaItems = configs.stream().map(config -> {
                FreeQuotaGrantReq.QuotaItem item = new FreeQuotaGrantReq.QuotaItem();
                item.setConfigId(config.getId());
                item.setCategoryCode(config.getCategoryCode());
                item.setCategoryName(config.getCategoryName());
                item.setGrantQuota(config.getQuota());
                item.setChargeType(config.getChargeType());
                item.setType(config.getType());
                item.setEnabled(true);
                return item;
            }).collect(Collectors.toList());
            logs.add("使用默认配置，项数: " + quotaItems.size());
        }

        if (CollUtil.isEmpty(quotaItems)) {
            throw new BusinessException("未找到可赠送的额度配置");
        }

        // 3. 执行批量赠送
        int totalUsers = allUserIds.size();
        int successUsers = 0;
        int failedUsers = 0;
        int totalItems = 0;
        int successItems = 0;
        int failedItems = 0;

        for (Long userId : allUserIds) {
            boolean userSuccess = true;
            logs.add(StrUtil.format("\n--- 用户 ID: {} ---", userId));

            for (FreeQuotaGrantReq.QuotaItem item : quotaItems) {
                totalItems++;
                try {
                    // 执行赠送
                    boolean success = grantQuotaToUser(userId, item);
                    if (success) {
                        successItems++;
                        logs.add(StrUtil.format("✓ {} : {} {}", item.getCategoryName(), item.getGrantQuota(), "[成功]"));
                    } else {
                        failedItems++;
                        userSuccess = false;
                        logs.add(StrUtil.format("✗ {} [失败]", item.getCategoryName()));
                    }
                } catch (Exception e) {
                    failedItems++;
                    userSuccess = false;
                    log.error("赠送额度失败: userId={}, item={}", userId, item.getCategoryName(), e);
                    logs.add(StrUtil.format("✗ {} [异常: {}]", item.getCategoryName(), e.getMessage()));
                }
            }

            if (userSuccess) {
                successUsers++;
            } else {
                failedUsers++;
            }
        }

        logs.add("\n========== 赠送完成 ==========");
        logs.add(StrUtil.format("用户: 成功 {} 个, 失败 {} 个", successUsers, failedUsers));
        logs.add(StrUtil.format("项目: 成功 {} 项, 失败 {} 项", successItems, failedItems));

        return FreeQuotaGrantResp.builder()
            .success(failedItems == 0)
            .totalUsers(totalUsers)
            .successUsers(successUsers)
            .failedUsers(failedUsers)
            .totalItems(totalItems)
            .successItems(successItems)
            .failedItems(failedItems)
            .message(StrUtil.format("批量赠送完成! 用户: {}/{}, 项目: {}/{}", successUsers, totalUsers, successItems, totalItems))
            .logs(logs)
            .build();
    }

    /**
     * 给单个用户赠送默认免费额度
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FreeQuotaGrantResp grantToUser(Long userId) {
        FreeQuotaGrantReq req = new FreeQuotaGrantReq();
        req.setUserIds(CollUtil.newArrayList(userId));
        return batchGrant(req);
    }

    /**
     * 给部门下所有用户赠送默认免费额度
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FreeQuotaGrantResp grantToDept(Long deptId) {
        FreeQuotaGrantReq req = new FreeQuotaGrantReq();
        req.setDeptIds(CollUtil.newArrayList(deptId));
        return batchGrant(req);
    }

    /**
     * 给用户赠送单项额度
     */
    private boolean grantQuotaToUser(Long userId, FreeQuotaGrantReq.QuotaItem item) {
        // 查询是否已存在
        PlantformBalanceDO existingBalance = plantformBalanceMapper
            .selectOne(new LambdaQueryWrapper<PlantformBalanceDO>().eq(PlantformBalanceDO::getUserId, userId)
                .eq(PlantformBalanceDO::getType, item.getType())
                .eq(item.getChargeType() != null, PlantformBalanceDO::getChargeType, item.getChargeType()));

        Long grantAmount = item.getGrantQuota().longValue();

        if (existingBalance != null) {
            // 更新余额（增加）
            existingBalance.setBalance(existingBalance.getBalance() + grantAmount);
            return plantformBalanceMapper.updateById(existingBalance) > 0;
        } else {
            // 插入新记录
            PlantformBalanceDO newBalance = new PlantformBalanceDO();
            newBalance.setUserId(userId);
            newBalance.setType(item.getType());
            newBalance.setBalance(grantAmount);
            newBalance.setChargeType(item.getChargeType());
            newBalance.setPreDeductBalance(0L);
            return plantformBalanceMapper.insert(newBalance) > 0;
        }
    }
}
