package com.emotion.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
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.DiaryPostCreateRequest;
import com.emotion.dto.request.DiaryPostPageRequest;
import com.emotion.dto.request.DiaryPostUpdateRequest;
import com.emotion.dto.response.DiaryPostResponse;
import com.emotion.entity.DiaryPost;
import com.emotion.mapper.DiaryPostMapper;
import com.emotion.service.DiaryPostService;
import com.emotion.service.DiaryCommentService;
import com.emotion.service.AiChatService;
import com.emotion.util.SnowflakeIdGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

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

/**
 * 用户日记服务实现类
 * 
 * @author huazhongmin
 * @date 2025-07-23
 */
@Service
public class DiaryPostServiceImpl extends ServiceImpl<DiaryPostMapper, DiaryPost> implements DiaryPostService {

    @Autowired
    private AiChatService aiChatService;
    @Autowired
    private DiaryCommentService diaryCommentService;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;

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

    @Override
    public PageResult<DiaryPostResponse> getPageWithResponse(DiaryPostPageRequest request) {
        Page<DiaryPost> page = new Page<>(request.getCurrent(), request.getSize());
        LambdaQueryWrapper<DiaryPost> wrapper = new LambdaQueryWrapper<>();

        // 基础查询条件
        wrapper.eq(DiaryPost::getIsDeleted, 0);

        // 根据请求参数添加查询条件
        if (StringUtils.hasText(request.getUserId())) {
            wrapper.eq(DiaryPost::getUserId, request.getUserId());
        }
        if (Boolean.TRUE.equals(request.getPublicOnly())) {
            wrapper.eq(DiaryPost::getIsPublic, 1)
                    .eq(DiaryPost::getStatus, "published");
        }
        if (Boolean.TRUE.equals(request.getFeaturedOnly())) {
            wrapper.eq(DiaryPost::getFeatured, 1)
                    .eq(DiaryPost::getIsPublic, 1)
                    .eq(DiaryPost::getStatus, "published");
        }
        if (StringUtils.hasText(request.getMood())) {
            wrapper.eq(DiaryPost::getMood, request.getMood());
        }
        if (StringUtils.hasText(request.getTag())) {
            // 标签查询可能需要特殊处理，因为tags字段是JSON格式
            wrapper.like(DiaryPost::getTags, request.getTag());
        }

        // 排序
        wrapper.orderByDesc(DiaryPost::getPriority)
               .orderByDesc(DiaryPost::getPublishTime);

        IPage<DiaryPost> resultPage = this.page(page, wrapper);
        List<DiaryPostResponse> responses = resultPage.getRecords().stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
        return createPageResult(resultPage, responses);
    }

    @Override
    public DiaryPostResponse getDiaryPostResponseById(String id) {
        DiaryPost diaryPost = this.getById(id);
        if (diaryPost == null) {
            return null;
        }
        // 增加浏览数
        incrementViewCount(id);
        return convertToResponse(diaryPost);
    }

    @Override
    public DiaryPostResponse createDiaryPostWithResponse(DiaryPostCreateRequest request) {
        // 处理标题：如果为空，则设置为null或生成默认标题
        String title = request.getTitle();
        if (title == null || title.trim().isEmpty()) {
            // 可以选择设置为null，或者生成一个默认标题
            // 这里我们设置为null，让数据库使用默认值
            title = null;
        }

        DiaryPost diaryPost = DiaryPost.builder()
                .id(snowflakeIdGenerator.nextIdAsString()) // 使用雪花算法生成ID
                .userId(request.getUserId())
                .title(title)
                .content(request.getContent())
                .images(convertListToJson(request.getImages()))
                .videos(convertListToJson(request.getVideos()))
                .location(request.getLocation())
                .weather(request.getWeather())
                .mood(request.getMood())
                .tags(convertListToJson(request.getTags()))
                .isPublic(request.getIsPublic())
                .isAnonymous(request.getIsAnonymous())
                .viewCount(0)
                .likeCount(0)
                .commentCount(0)
                .shareCount(0)
                .publishTime(LocalDateTime.now())
                .status("published")
                .priority(0)
                .featured(0)
                .build();

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

    @Override
    public DiaryPostResponse updateDiaryPostWithResponse(DiaryPostUpdateRequest request) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, request.getId())
                .set(StringUtils.hasText(request.getTitle()), DiaryPost::getTitle, request.getTitle())
                .set(StringUtils.hasText(request.getContent()), DiaryPost::getContent, request.getContent())
                .set(request.getImages() != null, DiaryPost::getImages, convertListToJson(request.getImages()))
                .set(request.getVideos() != null, DiaryPost::getVideos, convertListToJson(request.getVideos()))
                .set(StringUtils.hasText(request.getLocation()), DiaryPost::getLocation, request.getLocation())
                .set(StringUtils.hasText(request.getWeather()), DiaryPost::getWeather, request.getWeather())
                .set(StringUtils.hasText(request.getMood()), DiaryPost::getMood, request.getMood())
                .set(request.getTags() != null, DiaryPost::getTags, convertListToJson(request.getTags()))
                .set(request.getIsPublic() != null, DiaryPost::getIsPublic, request.getIsPublic())
                .set(request.getIsAnonymous() != null, DiaryPost::getIsAnonymous, request.getIsAnonymous())
                .set(StringUtils.hasText(request.getStatus()), DiaryPost::getStatus, request.getStatus())
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());

        boolean updated = this.update(wrapper);
        if (!updated) {
            return null;
        }
        DiaryPost updatedDiaryPost = this.getById(request.getId());
        return convertToResponse(updatedDiaryPost);
    }

    @Override
    public boolean deleteDiaryPost(String diaryId) {
        return this.removeById(diaryId);
    }

    @Override
    public boolean softDeleteDiaryPost(String diaryId) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, diaryId)
                .set(DiaryPost::getIsDeleted, 1)
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());
        return this.update(wrapper);
    }

    @Override
    public boolean restoreDiaryPost(String diaryId) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, diaryId)
                .set(DiaryPost::getIsDeleted, 0)
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());
        return this.update(wrapper);
    }

    @Override
    public boolean incrementViewCount(String diaryId) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, diaryId)
                .setSql("view_count = view_count + 1")
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());
        return this.update(wrapper);
    }

    @Override
    public boolean incrementLikeCount(String diaryId) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, diaryId)
                .setSql("like_count = like_count + 1")
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());
        return this.update(wrapper);
    }

    @Override
    public boolean decrementLikeCount(String diaryId) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, diaryId)
                .setSql("like_count = GREATEST(like_count - 1, 0)")
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());
        return this.update(wrapper);
    }

    @Override
    public boolean incrementCommentCount(String diaryId) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, diaryId)
                .setSql("comment_count = comment_count + 1")
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());
        return this.update(wrapper);
    }

    @Override
    public boolean decrementCommentCount(String diaryId) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, diaryId)
                .setSql("comment_count = GREATEST(comment_count - 1, 0)")
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());
        return this.update(wrapper);
    }

    @Override
    public boolean incrementShareCount(String diaryId) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, diaryId)
                .setSql("share_count = share_count + 1")
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());
        return this.update(wrapper);
    }

    @Override
    public boolean updateLastCommentTime(String diaryId) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, diaryId)
                .set(DiaryPost::getLastCommentTime, LocalDateTime.now())
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());
        return this.update(wrapper);
    }

    @Override
    public boolean setFeatured(String diaryId, Integer featured) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, diaryId)
                .set(DiaryPost::getFeatured, featured)
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());
        return this.update(wrapper);
    }

    @Override
    public boolean setPriority(String diaryId, Integer priority) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, diaryId)
                .set(DiaryPost::getPriority, priority)
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());
        return this.update(wrapper);
    }

    @Override
    public Long countByUserId(String userId) {
        LambdaQueryWrapper<DiaryPost> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DiaryPost::getUserId, userId)
               .eq(DiaryPost::getIsDeleted, 0);
        return this.count(wrapper);
    }

    @Override
    public Long countPublicByUserId(String userId) {
        LambdaQueryWrapper<DiaryPost> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DiaryPost::getUserId, userId)
               .eq(DiaryPost::getIsPublic, 1)
               .eq(DiaryPost::getStatus, "published")
               .eq(DiaryPost::getIsDeleted, 0);
        return this.count(wrapper);
    }

    @Override
    public Long countFeatured() {
        LambdaQueryWrapper<DiaryPost> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DiaryPost::getFeatured, 1)
               .eq(DiaryPost::getIsDeleted, 0);
        return this.count(wrapper);
    }

    @Override
    public DiaryPostResponse publishDiaryWithAiComment(DiaryPostCreateRequest request) {
        // 1. 保存日记
        DiaryPost diaryPost = DiaryPost.builder()
                .id(snowflakeIdGenerator.nextIdAsString()) // 使用雪花算法生成ID
                .userId(request.getUserId())
                .title(request.getTitle())
                .content(request.getContent())
                .images(convertListToJson(request.getImages()))
                .videos(convertListToJson(request.getVideos()))
                .location(request.getLocation())
                .weather(request.getWeather())
                .mood(request.getMood())
                .tags(convertListToJson(request.getTags()))
                .isPublic(request.getIsPublic())
                .isAnonymous(request.getIsAnonymous())
                .viewCount(0)
                .likeCount(0)
                .commentCount(0)
                .shareCount(0)
                .publishTime(LocalDateTime.now())
                .status("published")
                .priority(0)
                .featured(0)
                .build();
        this.save(diaryPost);
        
        // 2. 生成AI评论
        String aiComment = null;
        try {
            String conversationId = "diary-" + diaryPost.getId();
            aiComment = aiChatService.sendSummaryMessage(conversationId, diaryPost.getContent(), request.getUserId());
        } catch (Exception e) {
            aiComment = "开开：AI评论生成失败";
        }
        // 3. 写入AI评论到diary_comment表
        if (aiComment != null) {
            // 使用createCommentWithResponse方法创建AI评论
            com.emotion.dto.request.DiaryCommentCreateRequest commentRequest = new com.emotion.dto.request.DiaryCommentCreateRequest();
            commentRequest.setDiaryId(diaryPost.getId());
            commentRequest.setUserId("system"); // AI评论使用system用户ID
            commentRequest.setContent(aiComment);
            commentRequest.setIsAnonymous(0);
            diaryCommentService.createCommentWithResponse(commentRequest);
            
            addAiComment(
                    diaryPost.getId(),
                    aiComment,
                    null,
                    null,
                    null,
                    null
            );
        }
        // 4. 返回日记详情（含AI评论）
        return convertToResponse(diaryPost);
    }

    /**
     * 添加AI评论
     */
    private boolean addAiComment(String diaryId, String aiComment, Object aiEmotionAnalysis,
            BigDecimal aiSentimentScore, List<String> aiKeywords, String aiSuggestions) {
        LambdaUpdateWrapper<DiaryPost> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(DiaryPost::getId, diaryId)
                .set(DiaryPost::getAiComment, aiComment)
                .set(DiaryPost::getAiCommentTime, LocalDateTime.now())
                .set(DiaryPost::getAiEmotionAnalysis, convertObjectToJson(aiEmotionAnalysis))
                .set(DiaryPost::getAiSentimentScore, aiSentimentScore)
                .set(DiaryPost::getAiKeywords, convertListToJson(aiKeywords))
                .set(DiaryPost::getAiSuggestions, aiSuggestions)
                .set(DiaryPost::getUpdateTime, LocalDateTime.now());
        return this.update(wrapper);
    }

    /**
     * 创建PageResult对象
     */
    private <T> PageResult<T> createPageResult(IPage<?> page, List<T> records) {
        PageResult<T> pageResult = new PageResult<>();
        pageResult.setCurrent(page.getCurrent());
        pageResult.setSize(page.getSize());
        pageResult.setTotal(page.getTotal());
        pageResult.setPages(page.getPages());
        pageResult.setRecords(records);
        return pageResult;
    }

    /**
     * 将List转换为JSON字符串
     */
    private String convertListToJson(List<?> list) {
        if (list == null || list.isEmpty()) {
            return null;
        }
        try {
            return objectMapper.writeValueAsString(list);
        } catch (JsonProcessingException e) {
            return null;
        }
    }

    /**
     * 将Object转换为JSON字符串
     */
    private String convertObjectToJson(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            return null;
        }
    }

    /**
     * 转换实体为响应DTO
     */
    private DiaryPostResponse convertToResponse(DiaryPost diaryPost) {
        DiaryPostResponse response = new DiaryPostResponse();
        BeanUtils.copyProperties(diaryPost, response);

        // 转换时间格式
        if (diaryPost.getPublishTime() != null) {
            response.setPublishTime(diaryPost.getPublishTime().format(DATE_TIME_FORMATTER));
        }
        if (diaryPost.getLastCommentTime() != null) {
            response.setLastCommentTime(diaryPost.getLastCommentTime().format(DATE_TIME_FORMATTER));
        }
        if (diaryPost.getAiCommentTime() != null) {
            response.setAiCommentTime(diaryPost.getAiCommentTime().format(DATE_TIME_FORMATTER));
        }
        if (diaryPost.getCreateTime() != null) {
            response.setCreateTime(diaryPost.getCreateTime().format(DATE_TIME_FORMATTER));
        }
        if (diaryPost.getUpdateTime() != null) {
            response.setUpdateTime(diaryPost.getUpdateTime().format(DATE_TIME_FORMATTER));
        }

        // 转换JSON字段
        try {
            if (diaryPost.getImages() != null) {
                response.setImages(objectMapper.readValue(diaryPost.getImages(), new TypeReference<List<String>>() {
                }));
            }
            if (diaryPost.getVideos() != null) {
                response.setVideos(objectMapper.readValue(diaryPost.getVideos(), new TypeReference<List<String>>() {
                }));
            }
            if (diaryPost.getTags() != null) {
                response.setTags(objectMapper.readValue(diaryPost.getTags(), new TypeReference<List<String>>() {
                }));
            }
            if (diaryPost.getAiKeywords() != null) {
                response.setAiKeywords(
                        objectMapper.readValue(diaryPost.getAiKeywords(), new TypeReference<List<String>>() {
                        }));
            }
            if (diaryPost.getAiEmotionAnalysis() != null) {
                response.setAiEmotionAnalysis(objectMapper.readValue(diaryPost.getAiEmotionAnalysis(), Object.class));
            }
            if (diaryPost.getMetadata() != null) {
                response.setMetadata(objectMapper.readValue(diaryPost.getMetadata(), Object.class));
            }
        } catch (JsonProcessingException e) {
            // 忽略JSON解析错误
        }

        return response;
    }
}