package com.tangguo.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.dfa.FoundWord;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tangguo.common.constant.MomentConstant;
import com.tangguo.common.core.redis.RedisCache;
import com.tangguo.common.enums.TopicTopStatus;
import com.tangguo.common.exception.ServiceException;
import com.tangguo.common.utils.SecurityUtils;
import com.tangguo.common.utils.SensitiveWordUtils;
import com.tangguo.common.utils.StringUtils;
import com.tangguo.domain.BbsTopic;
import com.tangguo.domain.bo.CreateTopicBO;
import com.tangguo.domain.vo.BbsTopicListVO;
import com.tangguo.mapper.BbsTopicMapper;
import com.tangguo.service.IBbsTopicService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 话题Service业务层处理
 *
 * @author ruoyi
 * @date 2025-08-27
 */
@Service
public class BbsTopicServiceImpl extends ServiceImpl<BbsTopicMapper, BbsTopic> implements IBbsTopicService {

	@Resource
	private BbsTopicMapper bbsTopicMapper;

	@Resource
	private RedisCache redisCache;


	/**
	 * 查询话题列表
	 *
	 * @param topic 话题
	 * @return 话题
	 */
	@Override
	public List<BbsTopic> selectBbsTopicList(BbsTopic topic) {
		LambdaQueryWrapper<BbsTopic> lqw = Wrappers.lambdaQuery();
		lqw.like(StringUtils.isNotBlank(topic.getSource()), BbsTopic::getSource, topic.getSource());
		lqw.like(StringUtils.isNotBlank(topic.getName()), BbsTopic::getName, topic.getName());
		lqw.orderByDesc(BbsTopic::getIsTop);
		lqw.orderByDesc(BbsTopic::getTopTime);
		lqw.orderByAsc(BbsTopic::getSort);
		lqw.orderByDesc(BbsTopic::getCreateTime);
		return bbsTopicMapper.selectList(lqw);
	}


	/**
	 * 新增话题
	 *
	 * @param topic 话题
	 */
	@Override
	public void addTopic(BbsTopic topic) {
		long nameCount = this.count(
			Wrappers.lambdaQuery(BbsTopic.class).eq(BbsTopic::getName, topic.getName())
		);
		if (nameCount > 0) {
			throw new ServiceException("新增失败，当前话题名称已存在。");
		}

		BbsTopic newTopic = new BbsTopic();
		newTopic.setSource("后台管理");
		newTopic.setName(topic.getName());
		newTopic.setSort(topic.getSort());
		this.save(newTopic);
	}


	/**
	 * 修改话题
	 *
	 * @param topic 话题
	 */
	@Override
	public void editeTopic(BbsTopic topic) {
		BbsTopic dbTopic = this.getById(topic.getId());
		if (Objects.isNull(dbTopic)) {
			throw new ServiceException("修改失败，当前话题数据不存在。");
		}

		if (!dbTopic.getName().equals(topic.getName())) {
			long nameCount = this.count(
				Wrappers.lambdaQuery(BbsTopic.class).eq(BbsTopic::getName, topic.getName())
			);
			if (nameCount > 0) {
				throw new ServiceException("修改失败，当前话题名称已存在。");
			}
		}

		BbsTopic updTopic = new BbsTopic();
		updTopic.setId(dbTopic.getId());
		updTopic.setName(topic.getName());
		updTopic.setSort(topic.getSort());
		this.updateById(updTopic);
	}


	/**
	 * 置顶话题
	 *
	 * @param topic 话题
	 */
	@Override
	public void topTopic(BbsTopic topic) {
		BbsTopic dbTopic = this.getById(topic.getId());
		if (Objects.isNull(dbTopic)) {
			throw new ServiceException("置顶失败，当前话题数据不存在。");
		}

		Integer isTop = topic.getIsTop();
		if (!dbTopic.getIsTop().equals(isTop)) {
			LambdaUpdateWrapper<BbsTopic> wrapper = Wrappers.lambdaUpdate(BbsTopic.class);
			wrapper.eq(BbsTopic::getId, dbTopic.getId());
			if (TopicTopStatus.ZD.getValue() == isTop) {
				wrapper.set(BbsTopic::getIsTop, TopicTopStatus.ZD.getValue());
				wrapper.set(BbsTopic::getTopTime, new Date());
			} else {
				wrapper.set(BbsTopic::getIsTop, TopicTopStatus.BZD.getValue());
				wrapper.set(BbsTopic::getTopTime, null);
			}
			this.update(wrapper);
		}
 	}


	/**
	 * 删除话题
	 *
	 * @param topicId 话题Id
	 */
	@Override
	public void deleteTopic(Long topicId) {
		this.removeById(topicId);
	}


	/**
	 * 查询选择话题
	 *
	 * @param name 话题名称
	 * @return 话题
	 */
	@Override
	public List<BbsTopicListVO> getSelectTopics(String name) {
		return this.baseMapper.selectSelectTopics(name);
	}


	/**
	 * 刷新热搜话题
	 */
	@Override
	public void refreshRankingTopic() {
		this.baseMapper.refreshRankingTopic();
		this.redisCache.deleteObject(MomentConstant.HOT_TOPIC);
	}


	/**
	 * 查询热搜话题
	 *
	 * @param name 话题名称
	 * @return 话题
	 */
	@Override
	public List<BbsTopicListVO> getRankingTopic(String name) {
		List<BbsTopicListVO> topics = this.redisCache.getCacheObject(MomentConstant.HOT_TOPIC);
		if (CollUtil.isEmpty(topics)) {
			topics = this.baseMapper.selectRankingTopic();
			this.redisCache.setCacheObject(MomentConstant.HOT_TOPIC, topics, 1, TimeUnit.HOURS);
		}

		if (StrUtil.isNotBlank(name)) {
			topics = topics.stream()
				.filter(t -> t.getName().contains(name)).collect(Collectors.toList());
		}
		return topics;
	}


	/**
	 * 创建话题
	 *
	 * @param bo 话题
	 */
	@Override
	public BbsTopicListVO createTopic(CreateTopicBO bo) {
		String topicName = bo.getName();
		synchronized (topicName.intern()) {
			long nameCount = this.count(
				Wrappers.lambdaQuery(BbsTopic.class).eq(BbsTopic::getName, topicName)
			);
			if (nameCount > 0) {
				throw new ServiceException("创建失败，当前话题名称已存在。");
			}

			FoundWord fw = SensitiveWordUtils.getFoundFirstSensitive(topicName);
			if (Objects.nonNull(fw)) {
				String msg = String.format("创建失败，当前话题名称存在敏感词【%s】。", fw.getFoundWord());
				throw new ServiceException(msg);
			}

			BbsTopic newTopic = new BbsTopic();
			newTopic.setCreateBy(SecurityUtils.getUsername());
			newTopic.setSource("移动端用户");
			newTopic.setName(topicName);
			this.save(newTopic);

			BbsTopicListVO topicVO = new BbsTopicListVO();
			topicVO.setId(newTopic.getId());
			topicVO.setName(newTopic.getName());
			return topicVO;
		}
	}

}
