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.core.util.EntityUtil;
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.auth.emuns.UserTypeEnum;
import com.ssyf.module.robot.domain.entity.LiveRoomRelation;
import com.ssyf.module.robot.domain.entity.RConfigRelation;
import com.ssyf.module.robot.domain.entity.RRobotGroup;
import com.ssyf.module.robot.domain.query.LiveRoomRelationQuery;
import com.ssyf.module.robot.domain.query.RRobotGroupQuery;
import com.ssyf.module.robot.service.LiveRoomRelationService;
import com.ssyf.module.robot.mapper.LiveRoomRelationMapper;
import com.ssyf.plugs.mysql.helper.MybatisPlusHelper;
import com.ssyf.third.bmiss.model.ApiResponse;
import com.ssyf.third.bmiss.model.OtherUserCenter;
import com.ssyf.third.bmiss.services.BusinessService;
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.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author ELSA
 * @description 针对表【live_room_relation(直播间关联数据表)】的数据库操作Service实现
 * @createDate 2026-01-07 15:18:11
 */
@Service
public class LiveRoomRelationServiceImpl extends ServiceImpl<LiveRoomRelationMapper, LiveRoomRelation>
        implements LiveRoomRelationService{

    private final RedisTemplate<String, Object> redisTemplate;

    @Lazy
    @Autowired
    private BusinessService businessService;

    public LiveRoomRelationServiceImpl(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public LiveRoomRelation addOne(LiveRoomRelationQuery query) {
        if(StrUtil.isBlank(query.getAnchorCode())){
            ServiceRuntimeException.throw0(ApiCodeUser.PARAMETER_ERROR.getCode(),
                    "主播编码不能为空");
        }
        LiveRoomRelation userInfo = getLastOneBy(query.getAnchorCode());
        if(userInfo == null){
            int userNumber = 0;
            try{
                userNumber = Integer.parseInt(query.getAnchorCode());
            } catch (NumberFormatException e) {
                ServiceRuntimeException.throw0(ApiCodeUser.PARAMETER_ERROR.getCode(),
                        "主播编码格式错误,只能是数字编码");
            }
            ApiResponse<OtherUserCenter> response = businessService.searchForUserByNumber(userNumber);
            if(!response.isSuccess()){
                ServiceRuntimeException.throw0(ApiCodeUser.PARAMETER_ERROR.getCode(),
                        "未查询到该主播： " + query.getAnchorCode());
            }
            query.setAnchorName(response.getData().getNick_name());
            query.setAnchorCode(response.getData().getUser_number());
            query.setAnchorAvatar(response.getData().getHead_portrait());
            query.setAnchorId(response.getData().getUser_id());
        }else{
            query.setAnchorName(userInfo.getAnchorName());
            query.setAnchorCode(userInfo.getAnchorCode());
            query.setAnchorAvatar(userInfo.getAnchorAvatar());
            query.setAnchorId(userInfo.getAnchorId());
        }

        // 去重验证
        validateDuplicate(query);

        LiveRoomRelation liveRoomRelation = BeanUtil.toBean(query, LiveRoomRelation.class);
        liveRoomRelation.setUuid(IdUtil.simpleUUID());
        this.save(liveRoomRelation);

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

        return liveRoomRelation;
    }

    private LiveRoomRelation getLastOneBy(String anchorCode){
        return this.getOne(new LambdaQueryWrapper<LiveRoomRelation>()
                .eq(LiveRoomRelation::getAnchorCode, anchorCode).last("LIMIT 1"));
    }

    /**
     * 验证重复数据 - 根据类型、关联编码、直播ID、用户编码去重
     */
    private void validateDuplicate(LiveRoomRelationQuery query) {
        LambdaQueryWrapper<LiveRoomRelation> wrapper = new LambdaQueryWrapper<>();

        // 构建去重条件：类型、关联编码、直播ID、用户编码都相同则认为是重复
        wrapper.eq(StrUtil.isNotBlank(query.getRelationType()), LiveRoomRelation::getRelationType, query.getRelationType())
                .eq(StrUtil.isNotBlank(query.getRelationCode()), LiveRoomRelation::getRelationCode, query.getRelationCode())
                .eq(StrUtil.isNotBlank(query.getLiveRoomId()), LiveRoomRelation::getLiveRoomId, query.getLiveRoomId())
                .eq(StrUtil.isNotBlank(query.getAnchorCode()), LiveRoomRelation::getAnchorCode, query.getAnchorCode());

        // 检查是否存在重复记录
        long count = this.count(wrapper);
        if (count > 0) {
            ServiceRuntimeException.throw0(ApiCodeUser.PARAMETER_ERROR.getCode(),
                    "该直播间关联数据已存在，无法重复添加");
        }
    }

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

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

        // 清除相关缓存
        clearCacheByRelationCode(relationCode ,oldAccount.getRelationType());
    }

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


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

        LambdaQueryWrapper<LiveRoomRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(LiveRoomRelation::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, LiveRoomRelationQuery query) {
        LiveRoomRelation oldAccount = this.checkedExistAndGet(uid);
        //不能更新uid，和id
        query.setUuid(null);
        LiveRoomRelation update = BeanUtil.toBean(query, LiveRoomRelation.class);
        LambdaQueryWrapper<LiveRoomRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LiveRoomRelation::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 LiveRoomRelation getOneByUid(String uid) {
        // 缓存中没有，从数据库查询
        LiveRoomRelation account = this.getOne(createBaseWrapper(null).eq(LiveRoomRelation::getUuid, uid));

        return account;
    }

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

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

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

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

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

        List<LiveRoomRelation> olds = null;

        List<LiveRoomRelation> entities = new ArrayList<>();
        for (LiveRoomRelationQuery query : queries) {
            if (BeanUtil.isEmpty(query)) {
                throw new ServiceRuntimeException(ApiCodeUser.PARAMETER_ERROR.getCode(), "批量新增数据中存在空数据");
            }
            if(olds == null){
                olds = this.getListByRelationCode(query.getRelationCode() ,query.getRelationType());
            }
            if(isDuplicate(olds ,query)){
                continue;
            }

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

        if(entities.isEmpty()){
            return Collections.emptyList();
        }

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

        // 清除相关缓存
        Set<String> relationCodes = entities.stream()
                .map(LiveRoomRelation::getRelationCode)
                .collect(Collectors.toSet());

        // 按关系类型分组清理缓存
        Map<String, Set<String>> relationCodeToTypes = entities.stream()
                .collect(Collectors.groupingBy(
                        LiveRoomRelation::getRelationCode,
                        Collectors.mapping(LiveRoomRelation::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;
    }

    /**
     * 检查是否为重复数据 - 根据类型、关联编码、直播ID、用户编码去重
     */
    private boolean isDuplicate(List<LiveRoomRelation> list,LiveRoomRelationQuery query) {
        if(CollectionUtil.isEmpty(list)){
            return false;
        }
        for(LiveRoomRelation entity : list){
            if(!StrUtil.equals(entity.getRelationCode(), query.getRelationCode())){
                continue;
            }
            if(!StrUtil.equals(entity.getRelationType(), query.getRelationType())){
                continue;
            }
            if(StrUtil.equals(entity.getLiveRoomId(), query.getLiveRoomId())){
                return true;
            }
            if(StrUtil.equals(entity.getAnchorCode(), query.getAnchorCode())){
                return true;
            }
        }
        return false;
    }

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

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

        // 缓存未命中，查询数据库
        LambdaQueryWrapper<LiveRoomRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LiveRoomRelation::getRelationCode, relationCode);
        wrapper.eq(LiveRoomRelation::getRelationType, relationType);
        List<LiveRoomRelation> 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 "live_room_relation:relation_code:" + relationType + ":" + relationCode;
    }


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

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

    private LambdaQueryWrapper<LiveRoomRelation> createBaseWrapper(LiveRoomRelationQuery query) {
        LambdaQueryWrapper<LiveRoomRelation> wrapper = new LambdaQueryWrapper<>();
        if(query == null){
            query = new LiveRoomRelationQuery();
        }
        wrapper.eq(StrUtil.isNotBlank(query.getRelationType()), LiveRoomRelation::getRelationType, query.getRelationType());
        wrapper.like(StrUtil.isNotBlank(query.getRelationCode()), LiveRoomRelation::getRelationCode, query.getRelationCode());
        wrapper.like(StrUtil.isNotBlank(query.getLiveRoomId()), LiveRoomRelation::getLiveRoomId, query.getLiveRoomId());
        wrapper.like(StrUtil.isNotBlank(query.getLiveRoomName()), LiveRoomRelation::getLiveRoomName, query.getLiveRoomName());
        wrapper.like(StrUtil.isNotBlank(query.getAnchorId()), LiveRoomRelation::getAnchorId, query.getAnchorId());
        wrapper.like(StrUtil.isNotBlank(query.getAnchorName()), LiveRoomRelation::getAnchorName, query.getAnchorName());
        wrapper.like(StrUtil.isNotBlank(query.getAnchorCode()), LiveRoomRelation::getAnchorCode, query.getAnchorCode());

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