package com.ssyf.module.robot.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ssyf.common.web.apicode.ApiCodeUser;
import com.ssyf.common.web.error.ServiceRuntimeException;
import com.ssyf.module.robot.domain.entity.GiftRelation;
import com.ssyf.module.robot.domain.query.GiftRelationQuery;
import com.ssyf.module.robot.service.GiftRelationService;
import com.ssyf.module.robot.mapper.GiftRelationMapper;
import com.ssyf.plugs.mysql.helper.MybatisPlusHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author ELSA
 * @description 针对表【gift_relation(礼物关联表（记录礼物与其他业务对象的关联关系）)】的数据库操作Service实现
 * @createDate 2026-01-14 18:20:57
 */
@Service
public class GiftRelationServiceImpl extends ServiceImpl<GiftRelationMapper, GiftRelation>
        implements GiftRelationService{

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public GiftRelation addOne(GiftRelationQuery query) {
        GiftRelation giftRelation = BeanUtil.toBean(query, GiftRelation.class);
        giftRelation.setUuid(IdUtil.simpleUUID());
        this.save(giftRelation);

        // 清除相关缓存
        clearCacheByRelationCode(giftRelation.getRelationCode(), giftRelation.getRelationType());

        return giftRelation;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeByUid(String uid) {
        GiftRelation oldAccount = checkedExistAndGet(uid);
        LambdaQueryWrapper<GiftRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GiftRelation::getUuid, uid);

        // 获取删除前的数据，用于清除缓存
        String relationCode = oldAccount.getRelationCode();
        String relationType = oldAccount.getRelationType();
        this.remove(wrapper);

        // 清除相关缓存
        clearCacheByRelationCode(relationCode, relationType);
    }

    @Override
    public void removeBatchByUids(List<String> uids) {
        // 获取待删除的数据，用于清除缓存
        List<GiftRelation> toBeDeleted = this.list(new LambdaQueryWrapper<GiftRelation>()
                .in(GiftRelation::getUuid, uids));

        Map<String, Set<String>> relationCodeToTypes = toBeDeleted.stream()
                .collect(Collectors.groupingBy(
                        GiftRelation::getRelationCode,
                        Collectors.mapping(GiftRelation::getRelationType, Collectors.toSet())
                ));

        LambdaQueryWrapper<GiftRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(GiftRelation::getUuid, uids);
        this.remove(wrapper);

        // 清除相关缓存
        for (Map.Entry<String, Set<String>> entry : relationCodeToTypes.entrySet()) {
            String relationCode = entry.getKey();
            Set<String> relationTypes = entry.getValue();

            for (String relationType : relationTypes) {
                clearCacheByRelationCode(relationCode, relationType);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateByUid(String uid, GiftRelationQuery query) {
        GiftRelation oldAccount = this.checkedExistAndGet(uid);
        //不能更新uid，和id
        query.setUuid(null);
        GiftRelation update = BeanUtil.toBean(query, GiftRelation.class);
        LambdaQueryWrapper<GiftRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GiftRelation::getUuid, uid);
        this.update(update, wrapper);

        // 清除相关缓存 - 删除旧的和新的关系码缓存
        clearCacheByRelationCode(oldAccount.getRelationCode(), oldAccount.getRelationType());
        if (!StrUtil.equals(oldAccount.getRelationCode(), update.getRelationCode()) ||
                !StrUtil.equals(oldAccount.getRelationType(), update.getRelationType())) {
            clearCacheByRelationCode(update.getRelationCode(), update.getRelationType());
        }
    }

    @Override
    public GiftRelation getOneByUid(String uid) {
        // 缓存中没有，从数据库查询
        GiftRelation account = this.getOne(createBaseWrapper(null).eq(GiftRelation::getUuid, uid));

        return account;
    }

    @Override
    public PageInfo<GiftRelation> getPage(GiftRelationQuery query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        return PageInfo.of(this.list(createBaseWrapper(query)));
    }

    @Override
    public List<GiftRelation> getList(GiftRelationQuery query) {
        return this.list(createBaseWrapper(query));
    }

    @Override
    public GiftRelation checkedExistAndGet(String uid) {
        GiftRelation old = this.getOne(createBaseWrapper(null).eq(GiftRelation::getUuid, uid));
        if (old == null) {
            ServiceRuntimeException.throw0(ApiCodeUser.PARAMETER_ERROR.getCode(), "数据不存在");
        }
        return old;
    }

    @Override
    public Integer countBy(GiftRelationQuery query) {
        return this.count(createBaseWrapper(query));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<GiftRelation> addBatch(List<GiftRelationQuery> queries) {
        if (CollectionUtil.isEmpty(queries)) {
            throw new ServiceRuntimeException(ApiCodeUser.PARAMETER_ERROR.getCode(), "批量新增数据不能为空");
        }

        List<GiftRelation> entities = new ArrayList<>();
        for (GiftRelationQuery query : queries) {
            if (BeanUtil.isEmpty(query)) {
                throw new ServiceRuntimeException(ApiCodeUser.PARAMETER_ERROR.getCode(), "批量新增数据中存在空数据");
            }

            GiftRelation entity = BeanUtil.toBean(query, GiftRelation.class);
            entity.setUuid(IdUtil.simpleUUID());
            entities.add(entity);
        }

        // 批量保存
        boolean saveResult = this.saveBatch(entities);
        if (!saveResult) {
            throw new ServiceRuntimeException(ApiCodeUser.PARAMETER_ERROR.getCode(), "批量新增数据失败");
        }

        // 清除相关缓存
        Map<String, Set<String>> relationCodeToTypes = entities.stream()
                .collect(Collectors.groupingBy(
                        GiftRelation::getRelationCode,
                        Collectors.mapping(GiftRelation::getRelationType, Collectors.toSet())
                ));

        for (Map.Entry<String, Set<String>> entry : relationCodeToTypes.entrySet()) {
            String relationCode = entry.getKey();
            Set<String> relationTypes = entry.getValue();

            for (String relationType : relationTypes) {
                clearCacheByRelationCode(relationCode, relationType);
            }
        }

        return entities;
    }

    @Override
    public List<GiftRelation> getListByRelationCode(String relationCode, String relationType) {
        // 生成缓存键
        String cacheKey = generateCacheKeyByRelationCode(relationCode, relationType);

        // 尝试从缓存获取
        @SuppressWarnings("unchecked")
        List<GiftRelation> cachedResult = (List<GiftRelation>) redisTemplate.opsForValue().get(cacheKey);
        if (cachedResult != null) {
            return cachedResult;
        }

        // 缓存未命中，查询数据库
        LambdaQueryWrapper<GiftRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GiftRelation::getRelationCode, relationCode);
        wrapper.eq(StrUtil.isNotBlank(relationType), GiftRelation::getRelationType, relationType);
        List<GiftRelation> result = this.list(wrapper);

        // 将结果存入缓存，设置过期时间为1小时
        redisTemplate.opsForValue().set(cacheKey, result, 3600, TimeUnit.SECONDS);

        return result;
    }

    /**
     * 根据relationCode和relationType生成缓存键
     */
    private String generateCacheKeyByRelationCode(String relationCode, String relationType) {
        return "gift_relation:relation_code:" + relationType + ":" + relationCode;
    }

    /**
     * 清除指定relationCode和relationType的缓存
     */
    private void clearCacheByRelationCode(String relationCode, String relationType) {
        if (StrUtil.isNotBlank(relationCode) && StrUtil.isNotBlank(relationType)) {
            String cacheKey = generateCacheKeyByRelationCode(relationCode, relationType);
            redisTemplate.delete(cacheKey);
        }
    }

    /**
     * 清除指定relationCode的所有类型缓存
     */
    private void clearCacheByRelationCode(String relationCode) {
        if (StrUtil.isNotBlank(relationCode)) {
            // 删除特定类型的缓存键
            Set<String> keys = redisTemplate.keys("gift_relation:relation_code:*:" + relationCode);
            if (CollectionUtil.isNotEmpty(keys)) {
                redisTemplate.delete(keys);
            }
        }
    }

    private LambdaQueryWrapper<GiftRelation> createBaseWrapper(GiftRelationQuery query) {
        LambdaQueryWrapper<GiftRelation> wrapper = new LambdaQueryWrapper<>();
        if(query == null){
            query = new GiftRelationQuery();
        }
        wrapper.eq(StrUtil.isNotBlank(query.getRelationType()), GiftRelation::getRelationType, query.getRelationType());
        wrapper.like(StrUtil.isNotBlank(query.getRelationCode()), GiftRelation::getRelationCode, query.getRelationCode());
        wrapper.like(StrUtil.isNotBlank(query.getGiftName()), GiftRelation::getGiftName, query.getGiftName());
        wrapper.like(StrUtil.isNotBlank(query.getIconUrl()), GiftRelation::getIconUrl, query.getIconUrl());
        wrapper.eq(query.getUnitPrice() != null, GiftRelation::getUnitPrice, query.getUnitPrice());
        wrapper.eq(query.getQuantity() != null, GiftRelation::getQuantity, query.getQuantity());
        wrapper.eq(query.getTotalPrice() != null, GiftRelation::getTotalPrice, query.getTotalPrice());
        wrapper.eq(query.getGiftId() != null, GiftRelation::getGiftId, query.getGiftId());

        wrapper.like(StrUtil.isNotBlank(query.getUuid()), GiftRelation::getUuid, query.getUuid());
        // 示例排序逻辑
        if (CollectionUtil.isNotEmpty(query.getSorts())) {
            MybatisPlusHelper.orderAndIgnoreError(GiftRelation.class, wrapper, query.getSorts());
        } else {
            wrapper.orderByDesc(GiftRelation::getId);
        }
        return wrapper;
    }
}
