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

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.ArticleTagMapper;
import cn.meowrain.aioj.backend.blogservice.dao.mapper.TagMapper;
import cn.meowrain.aioj.backend.blogservice.dto.req.TagCreateRequestDTO;
import cn.meowrain.aioj.backend.blogservice.dto.req.TagUpdateRequestDTO;
import cn.meowrain.aioj.backend.blogservice.dto.resp.TagResponseDTO;
import cn.meowrain.aioj.backend.blogservice.service.TagService;
import cn.meowrain.aioj.backend.framework.core.exception.ClientException;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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 java.util.List;
import java.util.stream.Collectors;

/**
 * 文章标签服务实现类
 *
 * @author AIOJ
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class TagServiceImpl extends ServiceImpl<TagMapper, Tag> implements TagService {

    private final ArticleTagMapper articleTagMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createTag(TagCreateRequestDTO request) {
        Tag tag = BeanUtil.copyProperties(request, Tag.class);
        this.save(tag);
        return tag.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateTag(TagUpdateRequestDTO request) {
        Tag tag = this.getById(request.getId());
        if (tag == null) {
            throw new ClientException("标签不存在");
        }

        Tag updateTag = BeanUtil.copyProperties(request, Tag.class);
        this.updateById(updateTag);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteTag(Long tagId) {
        Tag tag = this.getById(tagId);
        if (tag == null) {
            throw new ClientException("标签不存在");
        }

        this.removeById(tagId);
        return true;
    }

    @Override
    public TagResponseDTO getTagById(Long tagId) {
        Tag tag = this.getById(tagId);
        if (tag == null) {
            return null;
        }
        return BeanUtil.copyProperties(tag, TagResponseDTO.class);
    }

    @Override
    public TagResponseDTO getTagBySlug(String slug) {
        Tag tag = this.lambdaQuery()
                .eq(Tag::getSlug, slug)
                .one();
        if (tag == null) {
            return null;
        }
        return BeanUtil.copyProperties(tag, TagResponseDTO.class);
    }

    @Override
    public List<TagResponseDTO> getAllTags() {
        List<Tag> tags = this.lambdaQuery()
                .list();
        return tags.stream()
                .map(tag -> BeanUtil.copyProperties(tag, TagResponseDTO.class))
                .collect(Collectors.toList());
    }

    @Override
    public List<TagResponseDTO> getEnabledTags() {
        List<Tag> tags = this.lambdaQuery()
                .eq(Tag::getIsEnabled, 1)
                .list();
        return tags.stream()
                .map(tag -> BeanUtil.copyProperties(tag, TagResponseDTO.class))
                .collect(Collectors.toList());
    }

    @Override
    public List<TagResponseDTO> getTagsByArticleId(Long articleId) {
        List<ArticleTag> articleTags = articleTagMapper.selectList(
                new LambdaQueryWrapper<ArticleTag>()
                        .eq(ArticleTag::getArticleId, articleId)
        );

        return articleTags.stream()
                .map(articleTag -> this.getById(articleTag.getTagId()))
                .filter(tag -> tag != null)
                .map(tag -> BeanUtil.copyProperties(tag, TagResponseDTO.class))
                .collect(Collectors.toList());
    }
}
