package cn.meowrain.aioj.backend.blogservice.service.impl;

import cn.meowrain.aioj.backend.blogservice.dao.entity.Article;
import cn.meowrain.aioj.backend.blogservice.dao.entity.ArticleTag;
import cn.meowrain.aioj.backend.blogservice.dao.entity.Tag;
import cn.meowrain.aioj.backend.blogservice.dao.mapper.ArticleMapper;
import cn.meowrain.aioj.backend.blogservice.dao.mapper.ArticleTagMapper;
import cn.meowrain.aioj.backend.blogservice.dto.req.ArticleCreateRequestDTO;
import cn.meowrain.aioj.backend.blogservice.dto.req.ArticleQueryRequestDTO;
import cn.meowrain.aioj.backend.blogservice.dto.req.ArticleUpdateRequestDTO;
import cn.meowrain.aioj.backend.blogservice.dto.resp.ArticleListResponseDTO;
import cn.meowrain.aioj.backend.blogservice.dto.resp.ArticleResponseDTO;
import cn.meowrain.aioj.backend.blogservice.dto.resp.CategoryResponseDTO;
import cn.meowrain.aioj.backend.blogservice.dto.resp.TagResponseDTO;
import cn.meowrain.aioj.backend.blogservice.service.ArticleService;
import cn.meowrain.aioj.backend.blogservice.service.CategoryService;
import cn.meowrain.aioj.backend.blogservice.service.LikeService;
import cn.meowrain.aioj.backend.blogservice.service.TagService;
import cn.meowrain.aioj.backend.framework.core.exception.ClientException;
import cn.meowrain.aioj.backend.framework.core.utils.ContextHolderUtils;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 文章服务实现类
 *
 * @author AIOJ
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    private final ArticleTagMapper articleTagMapper;
    private final CategoryService categoryService;
    private final TagService tagService;
    private final LikeService likeService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createArticle(ArticleCreateRequestDTO request) {
        Long currentUserId = ContextHolderUtils.getCurrentUserId();

        // 检查分类是否存在
        CategoryResponseDTO category = categoryService.getCategoryById(request.getCategoryId());
        if (category == null) {
            throw new ClientException("分类不存在");
        }

        // 创建文章
        Article article = new Article()
                .setTitle(request.getTitle())
                .setSlug(request.getSlug())
                .setSummary(request.getSummary())
                .setContent(request.getContent())
                .setCoverImage(request.getCoverImage())
                .setAuthorId(currentUserId)
                .setCategoryId(request.getCategoryId())
                .setViewCount(0)
                .setLikeCount(0)
                .setCommentCount(0)
                .setCollectCount(0)
                .setIsTop(request.getIsTop() != null ? request.getIsTop() : 0)
                .setIsEssence(request.getIsEssence() != null ? request.getIsEssence() : 0)
                .setIsPublished(request.getIsPublished() != null ? request.getIsPublished() : 0)
                .setStatus(1);

        if (request.getIsPublished() == 1) {
            article.setPublishTime(new Date());
        }

        this.save(article);

        // 保存文章标签关联
        if (request.getTagIds() != null && !request.getTagIds().isEmpty()) {
            for (Long tagId : request.getTagIds()) {
                ArticleTag articleTag = new ArticleTag()
                        .setArticleId(article.getId())
                        .setTagId(tagId);
                articleTagMapper.insert(articleTag);
            }
        }

        return article.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateArticle(ArticleUpdateRequestDTO request) {
        Long currentUserId = ContextHolderUtils.getCurrentUserId();

        // 查询文章
        Article article = this.getById(request.getId());
        if (article == null) {
            throw new ClientException("文章不存在");
        }

        // 检查权限
        if (!article.getAuthorId().equals(currentUserId)) {
            throw new ClientException("无权修改此文章");
        }

        // 更新文章信息
        article.setTitle(request.getTitle())
                .setSlug(request.getSlug())
                .setSummary(request.getSummary())
                .setContent(request.getContent())
                .setCoverImage(request.getCoverImage())
                .setCategoryId(request.getCategoryId())
                .setIsTop(request.getIsTop())
                .setIsEssence(request.getIsEssence())
                .setIsPublished(request.getIsPublished());

        if (request.getIsPublished() == 1 && article.getPublishTime() == null) {
            article.setPublishTime(new Date());
        }

        this.updateById(article);

        // 更新文章标签关联
        // 先删除旧的标签关联
        articleTagMapper.delete(new LambdaQueryWrapper<ArticleTag>()
                .eq(ArticleTag::getArticleId, article.getId()));

        // 再添加新的标签关联
        if (request.getTagIds() != null && !request.getTagIds().isEmpty()) {
            for (Long tagId : request.getTagIds()) {
                ArticleTag articleTag = new ArticleTag()
                        .setArticleId(article.getId())
                        .setTagId(tagId);
                articleTagMapper.insert(articleTag);
            }
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteArticle(Long articleId) {
        Long currentUserId = ContextHolderUtils.getCurrentUserId();

        // 查询文章
        Article article = this.getById(articleId);
        if (article == null) {
            throw new ClientException("文章不存在");
        }

        // 检查权限
        if (!article.getAuthorId().equals(currentUserId)) {
            throw new ClientException("无权删除此文章");
        }

        // 逻辑删除
        article.setStatus(4);
        this.updateById(article);

        return true;
    }

    @Override
    public ArticleResponseDTO getArticleById(Long articleId) {
        Article article = this.getById(articleId);
        if (article == null) {
            throw new ClientException("文章不存在");
        }

        return convertToResponseDTO(article);
    }

    @Override
    public ArticleResponseDTO getArticleBySlug(String slug) {
        Article article = this.lambdaQuery()
                .eq(Article::getSlug, slug)
                .one();
        if (article == null) {
            throw new ClientException("文章不存在");
        }

        return convertToResponseDTO(article);
    }

    @Override
    public IPage<ArticleListResponseDTO> getArticleList(ArticleQueryRequestDTO request) {
        Page<Article> page = new Page<>(request.getCurrent(), request.getSize());

        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();

        // 构建查询条件
        if (request.getId() != null) {
            queryWrapper.eq(Article::getId, request.getId());
        }
        if (StringUtils.hasText(request.getTitle())) {
            queryWrapper.like(Article::getTitle, request.getTitle());
        }
        if (request.getCategoryId() != null) {
            queryWrapper.eq(Article::getCategoryId, request.getCategoryId());
        }
        if (request.getAuthorId() != null) {
            queryWrapper.eq(Article::getAuthorId, request.getAuthorId());
        }
        if (request.getIsTop() != null) {
            queryWrapper.eq(Article::getIsTop, request.getIsTop());
        }
        if (request.getIsEssence() != null) {
            queryWrapper.eq(Article::getIsEssence, request.getIsEssence());
        }
        if (request.getIsPublished() != null) {
            queryWrapper.eq(Article::getIsPublished, request.getIsPublished());
        }
        if (request.getStatus() != null) {
            queryWrapper.eq(Article::getStatus, request.getStatus());
        } else {
            queryWrapper.eq(Article::getStatus, 1);
        }

        // 排序
        if (StringUtils.hasText(request.getSortField())) {
            if ("asc".equalsIgnoreCase(request.getSortOrder())) {
                queryWrapper.orderBy(true, true, Article::getViewCount);
            } else {
                queryWrapper.orderBy(true, false, Article::getViewCount);
            }
        } else {
            queryWrapper.orderByDesc(Article::getIsTop)
                    .orderByDesc(Article::getPublishTime);
        }

        IPage<Article> articlePage = this.page(page, queryWrapper);

        // 转换为DTO
        Page<ArticleListResponseDTO> resultPage = new Page<>(articlePage.getCurrent(), articlePage.getSize(), articlePage.getTotal());
        List<ArticleListResponseDTO> records = articlePage.getRecords().stream()
                .map(this::convertToListResponseDTO)
                .collect(Collectors.toList());
        resultPage.setRecords(records);

        return resultPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean publishArticle(Long articleId) {
        Long currentUserId = ContextHolderUtils.getCurrentUserId();

        Article article = this.getById(articleId);
        if (article == null) {
            throw new ClientException("文章不存在");
        }

        if (!article.getAuthorId().equals(currentUserId)) {
            throw new ClientException("无权发布此文章");
        }

        article.setIsPublished(1);
        article.setPublishTime(new Date());
        this.updateById(article);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean unpublishArticle(Long articleId) {
        Long currentUserId = ContextHolderUtils.getCurrentUserId();

        Article article = this.getById(articleId);
        if (article == null) {
            throw new ClientException("文章不存在");
        }

        if (!article.getAuthorId().equals(currentUserId)) {
            throw new ClientException("无权操作此文章");
        }

        article.setIsPublished(0);
        this.updateById(article);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean incrementViewCount(Long articleId) {
        Article article = this.getById(articleId);
        if (article == null) {
            throw new ClientException("文章不存在");
        }

        article.setViewCount(article.getViewCount() + 1);
        this.updateById(article);

        return true;
    }

    /**
     * 转换为响应DTO
     */
    private ArticleResponseDTO convertToResponseDTO(Article article) {
        ArticleResponseDTO dto = BeanUtil.copyProperties(article, ArticleResponseDTO.class);

        // 设置分类信息
        CategoryResponseDTO category = categoryService.getCategoryById(article.getCategoryId());
        if (category != null) {
            dto.setCategoryName(category.getName());
        }

        // 设置标签信息
        List<TagResponseDTO> tags = tagService.getTagsByArticleId(article.getId());
        dto.setTags(tags);

        // 设置点赞和收藏状态
        try {
            Long currentUserId = ContextHolderUtils.getCurrentUserId();
            dto.setIsLiked(likeService.isLiked(currentUserId, article.getId(), 1));
            // TODO: 实现收藏状态查询
            dto.setIsCollected(false);
        } catch (Exception e) {
            dto.setIsLiked(false);
            dto.setIsCollected(false);
        }

        return dto;
    }

    /**
     * 转换为列表响应DTO
     */
    private ArticleListResponseDTO convertToListResponseDTO(Article article) {
        ArticleListResponseDTO dto = BeanUtil.copyProperties(article, ArticleListResponseDTO.class);

        // 设置分类信息
        CategoryResponseDTO category = categoryService.getCategoryById(article.getCategoryId());
        if (category != null) {
            dto.setCategoryName(category.getName());
        }

        // 设置标签信息
        List<TagResponseDTO> tags = tagService.getTagsByArticleId(article.getId());
        dto.setTags(tags);

        // 设置点赞和收藏状态
        try {
            Long currentUserId = ContextHolderUtils.getCurrentUserId();
            dto.setIsLiked(likeService.isLiked(currentUserId, article.getId(), 1));
            // TODO: 实现收藏状态查询
            dto.setIsCollected(false);
        } catch (Exception e) {
            dto.setIsLiked(false);
            dto.setIsCollected(false);
        }

        return dto;
    }
}
