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.security.domain.ClientInfo;
import com.ssyf.common.security.helper.ClientContextHelper;
import com.ssyf.common.web.apicode.ApiCodeUser;
import com.ssyf.common.web.error.ServiceRuntimeException;
import com.ssyf.module.robot.domain.entity.MessageTemplate;
import com.ssyf.module.robot.domain.entity.RConfigRelation;
import com.ssyf.module.robot.domain.entity.RRobotAccount;
import com.ssyf.module.robot.domain.entity.MessageTemplate;
import com.ssyf.module.robot.domain.query.RConfigRelationQuery;
import com.ssyf.module.robot.domain.query.RRobotAccountQuery;
import com.ssyf.module.robot.domain.query.MessageTemplateQuery;
import com.ssyf.module.robot.service.MessageTemplateService;
import com.ssyf.module.robot.mapper.MessageTemplateMapper;
import com.ssyf.module.robot.service.RConfigRelationService;
import com.ssyf.module.robot.service.RRobotAccountService;
import com.ssyf.plugs.mysql.helper.MybatisPlusHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
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.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
* @author ELSA
* @description 针对表【message_template(消息模板表)】的数据库操作Service实现
* @createDate 2026-01-19 15:11:13
*/
@Slf4j
@Service
public class MessageTemplateServiceImpl extends ServiceImpl<MessageTemplateMapper, MessageTemplate>
    implements MessageTemplateService{
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // Redis缓存键前缀
    private static final String MESSAGE_TEMPLATE_CACHE_KEY_PREFIX = "message:template:type:";
    private static final long CACHE_EXPIRE_HOURS = 2;
    @Override
    public synchronized MessageTemplate addOne(MessageTemplateQuery query) {
        if(StrUtil.isBlank(query.getContent())){
            ServiceRuntimeException.throw0(ApiCodeUser.PARAMETER_ERROR.getCode() , "内容不能为空");
        }

        MessageTemplate messageTemplate = BeanUtil.toBean(query ,MessageTemplate.class);
        messageTemplate.setUuid(IdUtil.simpleUUID());
        this.save(messageTemplate);

        // 清除相关类型的缓存
        if (StrUtil.isNotBlank(messageTemplate.getType())) {
            String cacheKey = MESSAGE_TEMPLATE_CACHE_KEY_PREFIX + messageTemplate.getType();
            redisTemplate.delete(cacheKey);
            log.info("新增消息模板后清除类型缓存: {}", messageTemplate.getType());
        }

        return messageTemplate;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeByUid(String uid) {
        MessageTemplate template = this.checkedExistAndGet(uid);

        this.remove(createBaseWrapper(null).eq(MessageTemplate::getUuid, uid));

        // 清除相关类型的缓存
        if (StrUtil.isNotBlank(template.getType())) {
            String cacheKey = MESSAGE_TEMPLATE_CACHE_KEY_PREFIX + template.getType();
            redisTemplate.delete(cacheKey);
            log.info("删除消息模板后清除类型缓存: {}", template.getType());
        }
    }


    @Override
    public void removeBatchByUids(List<String> uids) {
        if (CollectionUtil.isEmpty(uids)) {
            return;
        }

        List<MessageTemplate> templates = this.list(createBaseWrapper(null).in(MessageTemplate::getUuid, uids));

        this.remove(createBaseWrapper(null).in(MessageTemplate::getUuid, uids));

        // 清除涉及的所有类型缓存
        Set<String> typesToClear = templates.stream()
                .map(MessageTemplate::getType)
                .filter(StrUtil::isNotBlank)
                .collect(Collectors.toSet());

        for (String type : typesToClear) {
            String cacheKey = MESSAGE_TEMPLATE_CACHE_KEY_PREFIX + type;
            redisTemplate.delete(cacheKey);
            log.info("批量删除消息模板后清除类型缓存: {}", type);
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateByUid(String uid, MessageTemplateQuery query) {
        MessageTemplate oldTemplate = this.checkedExistAndGet(uid);

        //不能更新uid，和id
        query.setUuid(null);
        MessageTemplate update = BeanUtil.toBean(query ,MessageTemplate.class);
        LambdaQueryWrapper<MessageTemplate> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MessageTemplate::getUuid, uid);
        this.update(update , wrapper);

        // 清除旧类型和新类型的缓存
        String oldType = oldTemplate.getType();
        String newType = update.getType();

        if (StrUtil.isNotBlank(oldType)) {
            String oldCacheKey = MESSAGE_TEMPLATE_CACHE_KEY_PREFIX + oldType;
            redisTemplate.delete(oldCacheKey);
            log.info("更新消息模板后清除旧类型缓存: {}", oldType);
        }

        if (StrUtil.isNotBlank(newType) && !newType.equals(oldType)) {
            String newCacheKey = MESSAGE_TEMPLATE_CACHE_KEY_PREFIX + newType;
            redisTemplate.delete(newCacheKey);
            log.info("更新消息模板后清除新类型缓存: {}", newType);
        }
    }


    @Override
    public MessageTemplate getOneByUid(String uid) {
        return this.getOne(createBaseWrapper(null).eq(MessageTemplate::getUuid, uid));
    }

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

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

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

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

    @Override
    public List<MessageTemplate> getListByType(String type) {
        if (StrUtil.isBlank(type)) {
            return Collections.emptyList();
        }

        // 构建缓存键
        String cacheKey = MESSAGE_TEMPLATE_CACHE_KEY_PREFIX + type;

        // 先从缓存获取
        List<MessageTemplate> cachedTemplates = (List<MessageTemplate>) redisTemplate.opsForValue().get(cacheKey);
        if (cachedTemplates != null && !cachedTemplates.isEmpty()) {
            log.info("从缓存获取类型为 {} 的消息模板，数量: {}", type, cachedTemplates.size());
            return cachedTemplates;
        }

        // 缓存未命中，从数据库查询
        LambdaQueryWrapper<MessageTemplate> wrapper = createBaseWrapper(new MessageTemplateQuery().setType(type));

        List<MessageTemplate> templates = this.list(wrapper);

        // 存入缓存
        if (!templates.isEmpty()) {
            redisTemplate.opsForValue().set(cacheKey, templates, CACHE_EXPIRE_HOURS, TimeUnit.HOURS);
            log.info("从数据库查询类型为 {} 的消息模板，数量: {}，已存入缓存", type, templates.size());
        }

        return templates;
    }


    private LambdaQueryWrapper<MessageTemplate> createBaseWrapper(MessageTemplateQuery query) {
        LambdaQueryWrapper<MessageTemplate> wrapper = new LambdaQueryWrapper<>();
        if (query == null) {
            return wrapper;
        }
        wrapper.eq(query.getStatus() != null ,MessageTemplate::getStatus, query.getStatus());
        wrapper.like(StrUtil.isNotBlank(query.getUuid()) , MessageTemplate::getUuid, query.getUuid());
        // 根据实际业务需求补充更多查询条件
        wrapper.eq(StrUtil.isNotBlank(query.getType()), MessageTemplate::getType, query.getType());
        wrapper.eq(StrUtil.isNotBlank(query.getCode()), MessageTemplate::getCode, query.getCode());
        // 示例排序逻辑
        if (CollectionUtil.isNotEmpty(query.getSorts())) {
            MybatisPlusHelper.orderAndIgnoreError(MessageTemplate.class, wrapper, query.getSorts());
        }
        return wrapper;
    }
}




