package com.emotion.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.PageResult;
import com.emotion.dto.request.community.CommunityPostCreateRequest;
import com.emotion.dto.request.community.CommunityPostUpdateRequest;
import com.emotion.dto.request.community.CommunityPostPageRequest;
import com.emotion.dto.response.community.CommunityPostResponse;
import com.emotion.entity.CommunityPost;
import com.emotion.mapper.CommunityPostMapper;
import com.emotion.service.CommunityPostService;
import com.emotion.util.SnowflakeIdGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 社区帖子服务实现类
 * 
 * @author huazhongmin
 * @date 2025-07-24
 */
@Service
public class CommunityPostServiceImpl extends ServiceImpl<CommunityPostMapper, CommunityPost> implements CommunityPostService {

    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    public PageResult<CommunityPostResponse> getPage(CommunityPostPageRequest request) {
        Page<CommunityPost> page = new Page<>(request.getCurrent(), request.getSize());
        LambdaQueryWrapper<CommunityPost> wrapper = new LambdaQueryWrapper<>();
        
        // 根据请求参数构建查询条件
        if (StringUtils.hasText(request.getUserId())) {
            wrapper.eq(CommunityPost::getUserId, request.getUserId());
        }
        
        if (StringUtils.hasText(request.getType())) {
            wrapper.eq(CommunityPost::getType, request.getType());
        }

        if (StringUtils.hasText(request.getLocationId())) {
            wrapper.eq(CommunityPost::getLocationId, request.getLocationId());
        }

        if (request.getPublicOnly() != null && request.getPublicOnly()) {
            wrapper.eq(CommunityPost::getIsPrivate, 0);
        }

        if (StringUtils.hasText(request.getKeyword())) {
            wrapper.and(w -> w.like(CommunityPost::getTitle, request.getKeyword())
                    .or().like(CommunityPost::getContent, request.getKeyword()));
        }

        wrapper.eq(CommunityPost::getIsDeleted, 0).orderByDesc(CommunityPost::getCreateTime);
        page = this.page(page, wrapper);

        return convertPageToResponse(page);
    }

    @Override
    public CommunityPostResponse getById(String id) {
        CommunityPost post = this.getBaseMapper().selectById(id);
        if (post == null) {
            return null;
        }
        // 增加浏览数
        Integer viewCount = post.getViewCount() == null ? 1 : post.getViewCount() + 1;
        post.setViewCount(viewCount);
        this.updateById(post);

        return convertToResponse(post);
    }

    @Override
    public CommunityPostResponse create(CommunityPostCreateRequest request) {
        CommunityPost post = new CommunityPost();
        post.setId(snowflakeIdGenerator.nextIdAsString()); // 使用雪花算法生成ID
        post.setUserId(request.getUserId());
        post.setTitle(request.getTitle());
        post.setContent(request.getContent());
        post.setType(request.getType());
        post.setLocationId(request.getLocationId());
        post.setTags(request.getTags());
        post.setIsPrivate(request.getIsPrivate() != null ? request.getIsPrivate() : 0); // 默认公开
        post.setLikes(0);
        post.setViewCount(0);
        post.setCommentCount(0);

        this.save(post);
        return convertToResponse(post);
    }

    @Override
    public CommunityPostResponse update(CommunityPostUpdateRequest request) {
        CommunityPost post = this.getBaseMapper().selectById(request.getId());
        if (post == null) {
            return null;
        }

        // 只更新非空字段
        if (request.getTitle() != null) {
            post.setTitle(request.getTitle());
        }
        if (request.getContent() != null) {
            post.setContent(request.getContent());
        }
        if (request.getType() != null) {
            post.setType(request.getType());
        }
        if (request.getLocationId() != null) {
            post.setLocationId(request.getLocationId());
        }
        if (request.getTags() != null) {
            post.setTags(request.getTags());
        }
        if (request.getIsPrivate() != null) {
            post.setIsPrivate(request.getIsPrivate());
        }

        this.updateById(post);
        return convertToResponse(post);
    }

    @Override
    public boolean delete(String id) {
        CommunityPost post = this.getBaseMapper().selectById(id);
        if (post == null) {
            return false;
        }

        // 使用 MyBatis-Plus 的 removeById 方法，自动处理逻辑删除
        return this.removeById(id);
    }

    /**
     * 转换为响应对象
     */
    private CommunityPostResponse convertToResponse(CommunityPost post) {
        CommunityPostResponse response = new CommunityPostResponse();
        BeanUtils.copyProperties(post, response);
        response.setId(post.getId());
        if (post.getCreateTime() != null) {
            response.setCreateTime(post.getCreateTime().format(DATE_TIME_FORMATTER));
        }
        if (post.getUpdateTime() != null) {
            response.setUpdateTime(post.getUpdateTime().format(DATE_TIME_FORMATTER));
        }
        return response;
    }

    /**
     * 转换分页对象为响应对象
     */
    private PageResult<CommunityPostResponse> convertPageToResponse(Page<CommunityPost> page) {
        PageResult<CommunityPostResponse> responsePage = new PageResult<>();
        responsePage.setCurrent(page.getCurrent());
        responsePage.setSize(page.getSize());
        responsePage.setTotal(page.getTotal());
        responsePage.setPages(page.getPages());
        responsePage.setRecords(
                page.getRecords().stream()
                        .map(this::convertToResponse)
                        .collect(Collectors.toList()));
        return responsePage;
    }
}