package org.xyzh.news.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.resource.TbResourceTag;
import org.xyzh.common.dto.resource.TbTag;
import org.xyzh.common.utils.IDUtils;
import org.xyzh.news.mapper.ResourceTagMapper;
import org.xyzh.news.mapper.TagMapper;
import org.xyzh.api.news.tag.TagService;

/**
 * @description 标签服务实现类
 * @filename NCTagServiceImpl.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-10-15
 */
@Service
public class NCTagServiceImpl implements TagService {

    private static final Logger logger = LoggerFactory.getLogger(NCTagServiceImpl.class);

    @Autowired
    private TagMapper tagMapper;

    @Autowired
    private ResourceTagMapper resourceTagMapper;

    // ----------------标签管理相关--------------------------------

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbTag> createTag(TbTag tag) {
        ResultDomain<TbTag> resultDomain = new ResultDomain<>();
        try {
            // 参数验证
            if (tag == null || !StringUtils.hasText(tag.getName())) {
                resultDomain.fail("标签名称不能为空");
                return resultDomain;
            }

            // 检查标签名称是否已存在
            int count = tagMapper.countByName(tag.getName(), null);
            if (count > 0) {
                resultDomain.fail("标签名称已存在");
                return resultDomain;
            }

            // 设置默认值
            if (tag.getID() == null) {
                tag.setID(IDUtils.generateID());
            }
            if (tag.getTagID() == null) {
                tag.setTagID(IDUtils.generateID());
            }
            
            tag.setCreateTime(new Date());
            tag.setUpdateTime(new Date());
            tag.setDeleted(false);

            // 插入数据库
            int result = tagMapper.insertTag(tag);
            if (result > 0) {
                logger.info("创建标签成功: {}", tag.getName());
                resultDomain.success("创建标签成功", tag);
                return resultDomain;
            } else {
                resultDomain.fail("创建标签失败");
                return resultDomain;
            }
        } catch (Exception e) {
            logger.error("创建标签异常: {}", e.getMessage(), e);
            resultDomain.fail("创建标签失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbTag> updateTag(TbTag tag) {
        ResultDomain<TbTag> resultDomain = new ResultDomain<>();
        try {
            // 参数验证
            if (tag == null || !StringUtils.hasText(tag.getID())) {
                resultDomain.fail("标签ID不能为空");
                return resultDomain;
            }

            // 检查标签是否存在
            TbTag existingTag = tagMapper.selectById(tag.getID());
            if (existingTag == null || existingTag.getDeleted()) {
                resultDomain.fail("标签不存在");
                return resultDomain;
            }

            // 检查标签名称是否重复（排除自身）
            if (StringUtils.hasText(tag.getName())) {
                int count = tagMapper.countByName(tag.getName(), tag.getID());
                if (count > 0) {
                    resultDomain.fail("标签名称已存在");
                    return resultDomain;
                }
            }

            // 更新时间
            tag.setUpdateTime(new Date());

            // 更新数据库
            int result = tagMapper.updateTag(tag);
            if (result > 0) {
                logger.info("更新标签成功: {}", tag.getID());
                // 重新查询返回完整数据
                TbTag updated = tagMapper.selectById(tag.getID());
                resultDomain.success("更新标签成功", updated);
                return resultDomain;
            } else {
                resultDomain.fail("更新标签失败");
                return resultDomain;
            }
        } catch (Exception e) {
            logger.error("更新标签异常: {}", e.getMessage(), e);
            resultDomain.fail("更新标签失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<Boolean> deleteTag(String tagID) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();
        try {
            // 参数验证
            if (!StringUtils.hasText(tagID)) {
                resultDomain.fail("标签ID不能为空");
                return resultDomain;
            }

            // 检查标签是否存在
            TbTag tag = tagMapper.selectByTagId(tagID);
            if (tag == null || tag.getDeleted()) {
                resultDomain.fail("标签不存在");
                return resultDomain;
            }

            // 检查是否有关联资源
            List<TbResourceTag> resourceTags = resourceTagMapper.selectByTagId(tagID);
            if (resourceTags != null && !resourceTags.isEmpty()) {
                resultDomain.fail("该标签下存在关联资源，无法删除");
                return resultDomain;
            }

            // 物理删除
            int result = tagMapper.deleteTag(tag);
            if (result > 0) {
                logger.info("删除标签成功: {}", tagID);
                resultDomain.success("删除标签成功", true);
                return resultDomain;
            } else {
                resultDomain.fail("删除标签失败");
                return resultDomain;
            }
        } catch (Exception e) {
            logger.error("删除标签异常: {}", e.getMessage(), e);
            resultDomain.fail("删除标签失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbTag> getTagById(String tagID) {
        ResultDomain<TbTag> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(tagID)) {
                resultDomain.fail("标签ID不能为空");
                return resultDomain;
            }

            TbTag tag = tagMapper.selectByTagId(tagID);
            if (tag == null || tag.getDeleted()) {
                resultDomain.fail("标签不存在");
                return resultDomain;
            }

            resultDomain.success("查询成功", tag);
            return resultDomain;
        } catch (Exception e) {
            logger.error("查询标签异常: {}", e.getMessage(), e);
            resultDomain.fail("查询标签失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbTag> getAllTags() {
        ResultDomain<TbTag> resultDomain = new ResultDomain<>();
        try {
            List<TbTag> tags = tagMapper.selectTags(new TbTag());
            resultDomain.success("查询成功", tags);
            return resultDomain;
        } catch (Exception e) {
            logger.error("查询标签列表异常: {}", e.getMessage(), e);
            resultDomain.fail("查询标签列表失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbTag> searchTagsByName(String name) {
        ResultDomain<TbTag> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(name)) {
                resultDomain.fail("搜索关键词不能为空");
                return resultDomain;
            }

            TbTag filter = new TbTag();
            filter.setName(name);
            List<TbTag> tags = tagMapper.selectTags(filter);
            
            resultDomain.success("查询成功", tags);
            return resultDomain;
        } catch (Exception e) {
            logger.error("搜索标签异常: {}", e.getMessage(), e);
            resultDomain.fail("搜索标签失败: " + e.getMessage());
            return resultDomain;
        }
    }

    // ----------------资源标签关联相关--------------------------------

    @Override
    public ResultDomain<TbTag> getResourceTags(String resourceID) {
        ResultDomain<TbTag> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(resourceID)) {
                resultDomain.fail("资源ID不能为空");
                return resultDomain;
            }

            // 查询资源标签关联
            List<TbResourceTag> resourceTags = resourceTagMapper.selectByResourceId(resourceID);
            
            // 根据标签ID查询标签详情
            List<TbTag> tags = new ArrayList<>();
            for (TbResourceTag resourceTag : resourceTags) {
                TbTag tag = tagMapper.selectByTagId(resourceTag.getTagID());
                if (tag != null && !tag.getDeleted()) {
                    tags.add(tag);
                }
            }

            resultDomain.success("查询成功", tags);
            return resultDomain;
        } catch (Exception e) {
            logger.error("查询资源标签异常: {}", e.getMessage(), e);
            resultDomain.fail("查询资源标签失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbResourceTag> addResourceTag(String resourceID, String tagID) {
        ResultDomain<TbResourceTag> resultDomain = new ResultDomain<>();
        try {
            // 参数验证
            if (!StringUtils.hasText(resourceID) || !StringUtils.hasText(tagID)) {
                resultDomain.fail("资源ID和标签ID不能为空");
                return resultDomain;
            }

            // 检查标签是否存在
            TbTag tag = tagMapper.selectByTagId(tagID);
            if (tag == null || tag.getDeleted()) {
                resultDomain.fail("标签不存在");
                return resultDomain;
            }

            // 检查是否已经关联
            int count = resourceTagMapper.countByResourceIdAndTagId(resourceID, tagID, null);
            if (count > 0) {
                resultDomain.fail("该资源已关联此标签");
                return resultDomain;
            }

            // 创建关联
            TbResourceTag resourceTag = new TbResourceTag();
            resourceTag.setID(IDUtils.generateID());
            resourceTag.setResourceID(resourceID);
            resourceTag.setTagID(tagID);
            resourceTag.setCreateTime(new Date());
            resourceTag.setUpdateTime(new Date());
            resourceTag.setDeleted(false);

            int result = resourceTagMapper.insertResourceTag(resourceTag);
            if (result > 0) {
                logger.info("添加资源标签成功: resourceID={}, tagID={}", resourceID, tagID);
                resultDomain.success("添加标签成功", resourceTag);
                return resultDomain;
            } else {
                resultDomain.fail("添加标签失败");
                return resultDomain;
            }
        } catch (Exception e) {
            logger.error("添加资源标签异常: {}", e.getMessage(), e);
            resultDomain.fail("添加标签失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbResourceTag> batchAddResourceTags(String resourceID, List<String> tagIDs) {
        ResultDomain<TbResourceTag> resultDomain = new ResultDomain<>();
        try {
            // 参数验证
            if (!StringUtils.hasText(resourceID) || tagIDs == null || tagIDs.isEmpty()) {
                resultDomain.fail("资源ID和标签ID列表不能为空");
                return resultDomain;
            }

            List<TbResourceTag> resourceTags = new ArrayList<>();
            for (String tagID : tagIDs) {
                // 检查标签是否存在
                TbTag tag = tagMapper.selectByTagId(tagID);
                if (tag == null || tag.getDeleted()) {
                    continue;
                }

                // 检查是否已经关联
                int count = resourceTagMapper.countByResourceIdAndTagId(resourceID, tagID, null);
                if (count > 0) {
                    continue;
                }

                // 创建关联
                TbResourceTag resourceTag = new TbResourceTag();
                resourceTag.setID(IDUtils.generateID());
                resourceTag.setResourceID(resourceID);
                resourceTag.setTagID(tagID);
                resourceTag.setCreateTime(new Date());
                resourceTag.setUpdateTime(new Date());
                resourceTag.setDeleted(false);
                
                resourceTags.add(resourceTag);
            }

            if (resourceTags.isEmpty()) {
                resultDomain.fail("没有可添加的标签");
                return resultDomain;
            }

            int result = resourceTagMapper.batchInsertResourceTags(resourceTags);
            if (result > 0) {
                logger.info("批量添加资源标签成功: resourceID={}, count={}", resourceID, result);
                resultDomain.success("批量添加标签成功", resourceTags);
                return resultDomain;
            } else {
                resultDomain.fail("批量添加标签失败");
                return resultDomain;
            }
        } catch (Exception e) {
            logger.error("批量添加资源标签异常: {}", e.getMessage(), e);
            resultDomain.fail("批量添加标签失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<Boolean> removeResourceTag(String resourceID, String tagID) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();
        try {
            // 参数验证
            if (!StringUtils.hasText(resourceID) || !StringUtils.hasText(tagID)) {
                resultDomain.fail("资源ID和标签ID不能为空");
                return resultDomain;
            }

            // 查找关联
            TbResourceTag resourceTag = resourceTagMapper.selectByResourceIdAndTagId(resourceID, tagID);
            if (resourceTag == null) {
                resultDomain.fail("资源标签关联不存在");
                return resultDomain;
            }

            // 物理删除
            int result = resourceTagMapper.deleteResourceTag(resourceTag);
            if (result > 0) {
                logger.info("移除资源标签成功: resourceID={}, tagID={}", resourceID, tagID);
                resultDomain.success("移除标签成功", true);
                return resultDomain;
            } else {
                resultDomain.fail("移除标签失败");
                return resultDomain;
            }
        } catch (Exception e) {
            logger.error("移除资源标签异常: {}", e.getMessage(), e);
            resultDomain.fail("移除标签失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<Boolean> clearResourceTags(String resourceID) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();
        try {
            // 参数验证
            if (!StringUtils.hasText(resourceID)) {
                resultDomain.fail("资源ID不能为空");
                return resultDomain;
            }

            // 删除所有关联
            int result = resourceTagMapper.deleteByResourceId(resourceID);
            logger.info("清空资源标签成功: resourceID={}, count={}", resourceID, result);
            resultDomain.success("清空标签成功", true);
            return resultDomain;
        } catch (Exception e) {
            logger.error("清空资源标签异常: {}", e.getMessage(), e);
            resultDomain.fail("清空标签失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<String> getResourcesByTag(String tagID) {
        ResultDomain<String> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(tagID)) {
                resultDomain.fail("标签ID不能为空");
                return resultDomain;
            }

            // 查询标签关联的资源
            List<TbResourceTag> resourceTags = resourceTagMapper.selectByTagId(tagID);
            
            // 提取资源ID列表
            List<String> resourceIDs = new ArrayList<>();
            for (TbResourceTag resourceTag : resourceTags) {
                resourceIDs.add(resourceTag.getResourceID());
            }

            resultDomain.success("查询成功", resourceIDs);
            return resultDomain;
        } catch (Exception e) {
            logger.error("查询标签资源异常: {}", e.getMessage(), e);
            resultDomain.fail("查询标签资源失败: " + e.getMessage());
            return resultDomain;
        }
    }
}
