package com.luojia_channel.modules.post.service.impl;

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.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.luojia_channel.common.domain.page.PageResponse;
import com.luojia_channel.common.exception.PostException;
import com.luojia_channel.common.utils.PageUtil;
import com.luojia_channel.common.utils.RedisUtil;
import com.luojia_channel.common.utils.UserContext;
import com.luojia_channel.modules.file.service.impl.FileServiceImpl;
import com.luojia_channel.modules.post.dto.req.PostSaveDTO;
import com.luojia_channel.modules.post.dto.req.PostPageQueryDTO;
import com.luojia_channel.modules.post.dto.resp.PostBasicInfoDTO;
import com.luojia_channel.modules.post.entity.Post;
import com.luojia_channel.modules.post.mapper.PostMapper;
import com.luojia_channel.modules.post.service.PostService;
import com.luojia_channel.modules.post.utils.ValidatePostUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements PostService {

    private final PostMapper postMapper;
    private final FileServiceImpl fileService;
    private final ValidatePostUtil validatePostUtil;
    private final RedisUtil redisUtil;

    @Override
    public void createPost(PostSaveDTO postSaveDTO) {
        validatePostUtil.validatePost(postSaveDTO);
        Long userId = UserContext.getUserId();
        Post post = BeanUtil.copyProperties(postSaveDTO, Post.class);
        post.setUserId(userId);
        if(!save(post)){
            throw new PostException("创建帖子失败");
        }
    }

    @Override
    public String setCover(MultipartFile file) {
        return fileService.uploadFile(file);
    }

    @Override
    public void updatePost(PostSaveDTO postSaveDTO) {
        validatePostUtil.validatePost(postSaveDTO);
        Post post = BeanUtil.copyProperties(postSaveDTO, Post.class);
        post.setUpdateTime(LocalDateTime.now());
        if(!updateById(post)){
            throw new PostException("更新帖子失败");
        }
    }

    @Override
    public void deletePost(Long id) {
        validatePostUtil.validatePostOwnership(id);
        int delete = postMapper.deleteById(id);
        if(delete <= 0){
            throw new PostException("删除帖子失败");
        }
    }

    @Override
    public Post getPostDetail(Long id) {
        return redisUtil.safeGet("post:detail" + id.toString(), Post.class,
                () -> {
                    Post post = getById(id);
                    if(post == null){
                        throw new PostException("帖子不存在或被删除");
                    }
                    return post;
                }, 10, TimeUnit.MINUTES);
    }

    @Override
    public PageResponse<PostBasicInfoDTO> pagePost(PostPageQueryDTO postPageQueryDTO) {
        // TODO 目前分页查询直接按照创建时间顺序排序了，未来考虑加入多种规则
        LambdaQueryWrapper<Post> queryWrapper = Wrappers.lambdaQuery(Post.class)
                .orderByDesc(Post::getCreateTime);
        IPage<Post> postPage = postMapper.selectPage(PageUtil.convert(postPageQueryDTO), queryWrapper);
        return PageUtil.convert(postPage, PostBasicInfoDTO.class);
    }


    @Override
    public PageResponse<PostBasicInfoDTO> pagePostOfMe(PostPageQueryDTO postPageQueryDTO) {
        Long userId = UserContext.getUserId();
        LambdaQueryWrapper<Post> queryWrapper = Wrappers.lambdaQuery(Post.class)
                .eq(Post::getUserId, userId)
                .orderByDesc(Post::getCreateTime);
        IPage<Post> postPage = postMapper.selectPage(PageUtil.convert(postPageQueryDTO), queryWrapper);
        return PageUtil.convert(postPage, PostBasicInfoDTO.class);
    }
}
