package shop.alien.storeplatform.service.impl;

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.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import shop.alien.entity.store.LifeUser;
import shop.alien.mapper.LifeUserMapper;
import shop.alien.storeplatform.entity.StorePlatformDiscussion;
import shop.alien.storeplatform.entity.StorePlatformDiscussionLike;
import shop.alien.storeplatform.mapper.StorePlatformDiscussionLikeMapper;
import shop.alien.storeplatform.mapper.StorePlatformDiscussionMapper;
import shop.alien.storeplatform.service.StorePlatformDiscussionService;
import shop.alien.storeplatform.util.LoginUserUtil;
import shop.alien.storeplatform.vo.StorePlatformDiscussionReplyVo;
import shop.alien.storeplatform.vo.StorePlatformDiscussionUserVo;
import shop.alien.util.common.safe.DeepseekClient;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 店铺问题讨论服务实现类
 *
 * @author alien
 * @since 2025-12-30
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class StorePlatformDiscussionServiceImpl extends ServiceImpl<StorePlatformDiscussionMapper, StorePlatformDiscussion> implements StorePlatformDiscussionService {

    private final LifeUserMapper lifeUserMapper;
    private final StorePlatformDiscussionLikeMapper discussionLikeMapper;
    private final StoreDiscussionConfig discussionConfig;
    private final DeepseekClient deepseekClient = new DeepseekClient("sk-dd8a6e10972145c9847883791ac9fb41");

    /**
     * 内部配置类
     */
    @Data
    @Component
    @ConfigurationProperties(prefix = "alien.discussion")
    public static class StoreDiscussionConfig {
        /**
         * 删除策略: 1-只删除当前讨论, 2-级联删除所有回复
         * 默认为 2 (级联删除)
         */
        private Integer defaultDeleteStrategy = STRATEGY_CASCADE;

        public static final int STRATEGY_SINGLE = 1;
        public static final int STRATEGY_CASCADE = 2;
    }

    @Override
    public IPage<StorePlatformDiscussionUserVo> pageRootDiscussions(Integer storeId, Integer pageNum, Integer pageSize, String tags, Integer sortMode) {
        LambdaQueryWrapper<StorePlatformDiscussion> wrapper = new LambdaQueryWrapper<StorePlatformDiscussion>()
                .eq(StorePlatformDiscussion::getStoreId, storeId)
                .eq(StorePlatformDiscussion::getParentId, 0);

        applySorting(wrapper, sortMode);

        Page<StorePlatformDiscussion> page = new Page<>(pageNum, pageSize);
        IPage<StorePlatformDiscussion> discussionPage = this.page(page, wrapper);
        
        IPage<StorePlatformDiscussionUserVo> voPage = discussionPage.convert(this::convertToVoWithUserInfo);
        
        if (StringUtils.hasText(tags) || (sortMode != null && sortMode == 1)) {
            rankAndSortVoList(voPage.getRecords(), tags, sortMode);
        }
        
        return voPage;
    }

    @Override
    public StorePlatformDiscussionReplyVo pageRepliesByRootId(Integer rootId, Integer pageNum, Integer pageSize, String tags, Integer sortMode) {
        StorePlatformDiscussion root = this.getById(rootId);
        if (root == null) {
            throw new RuntimeException("主贴讨论不存在");
        }
        StorePlatformDiscussionUserVo topicVo = convertToVoWithUserInfo(root);

        LambdaQueryWrapper<StorePlatformDiscussion> wrapper = new LambdaQueryWrapper<StorePlatformDiscussion>()
                .eq(StorePlatformDiscussion::getRootId, rootId)
                .ne(StorePlatformDiscussion::getId, rootId);

        applySorting(wrapper, sortMode);

        Page<StorePlatformDiscussion> page = new Page<>(pageNum, pageSize);
        IPage<StorePlatformDiscussion> replyPage = this.page(page, wrapper);
        
        IPage<StorePlatformDiscussionUserVo> voPage = replyPage.convert(this::convertToVo);
        fillUserInfoBatch(voPage.getRecords());

        if (StringUtils.hasText(tags) || (sortMode != null && sortMode == 1)) {
            rankAndSortVoList(voPage.getRecords(), tags, sortMode);
        }

        return StorePlatformDiscussionReplyVo.fromPage(topicVo, voPage);
    }

    @Override
    public List<StorePlatformDiscussionUserVo> listByStoreId(Integer storeId, String tags, Integer sortMode) {
        LambdaQueryWrapper<StorePlatformDiscussion> wrapper = new LambdaQueryWrapper<StorePlatformDiscussion>()
                .eq(StorePlatformDiscussion::getStoreId, storeId);

        applySorting(wrapper, sortMode);

        List<StorePlatformDiscussion> list = this.list(wrapper);
        List<StorePlatformDiscussionUserVo> voList = list.stream().map(this::convertToVo).collect(Collectors.toList());
        fillUserInfoBatch(voList);

        if (StringUtils.hasText(tags) || (sortMode != null && sortMode == 1)) {
            rankAndSortVoList(voList, tags, sortMode);
        }

        return voList;
    }

    private void applySorting(LambdaQueryWrapper<StorePlatformDiscussion> wrapper, Integer sortMode) {
        if (sortMode == null) {
            wrapper.orderByDesc(StorePlatformDiscussion::getCreatedTime);
            return;
        }
        switch (sortMode) {
            case 2: // 按点赞数降序
                wrapper.orderByDesc(StorePlatformDiscussion::getLikeCount);
                break;
            case 3: // 按创建时间升序
                wrapper.orderByAsc(StorePlatformDiscussion::getCreatedTime);
                break;
            case 4: // 按创建时间降序
                wrapper.orderByDesc(StorePlatformDiscussion::getCreatedTime);
                break;
            default:
                wrapper.orderByDesc(StorePlatformDiscussion::getCreatedTime);
                break;
        }
    }

    /**
     * 排序
     */
    private void rankAndSortVoList(List<StorePlatformDiscussionUserVo> voList, String tags, Integer sortMode) {
        if (CollectionUtils.isEmpty(voList) || !StringUtils.hasText(tags)) return;

        try {
            // 使用 AI 计算相关性评分
            StringBuilder prompt = new StringBuilder("请根据以下标签：[" + tags + "]，对以下讨论内容进行相关性评分（0-100分，仅返回一个JSON数组，格式如：[{\"id\":1, \"score\":85}, ...])：\n");
            for (StorePlatformDiscussionUserVo vo : voList) {
                prompt.append("ID: ").append(vo.getId()).append(", 内容: ").append(vo.getContent()).append("\n");
            }

            String aiResponse = deepseekClient.generateText(prompt.toString());
            log.info("AI Ranking Response: {}", aiResponse);

            List<Map<String, Object>> scores = com.alibaba.fastjson.JSON.parseObject(aiResponse, new com.alibaba.fastjson.TypeReference<List<Map<String, Object>>>(){});
            Map<Integer, Double> scoreMap = scores.stream().collect(Collectors.toMap(
                    m -> (Integer) m.get("id"),
                    m -> Double.valueOf(m.get("score").toString())
            ));

            for (StorePlatformDiscussionUserVo vo : voList) {
                vo.setRelevanceScore(scoreMap.getOrDefault(vo.getId(), 0.0));
            }

            // 如果排序方式是按相关度降序，则重新排序
            if (sortMode != null && sortMode == 1) {
                voList.sort((a, b) -> Double.compare(b.getRelevanceScore(), a.getRelevanceScore()));
            }

        } catch (Exception e) {
            log.error("AI Ranking Error", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean postTopic(StorePlatformDiscussion discussion) {
        Integer currentUserId = LoginUserUtil.getCurrentUserId();
        if (currentUserId == null) {
            throw new RuntimeException("请先登录再发表讨论");
        }
        discussion.setUserId(currentUserId);
        discussion.setParentId(0);
        discussion.setRootId(0);
        discussion.setLikeCount(0); // 初始化点赞数
        boolean saved = this.save(discussion);
        if (saved) {
            // 一级讨论的 rootId 设置为它自己的 ID
            discussion.setRootId(discussion.getId());
            this.updateById(discussion);
        }
        return saved;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean postReply(StorePlatformDiscussion discussion) {
        Integer currentUserId = LoginUserUtil.getCurrentUserId();
        if (currentUserId == null) {
            throw new RuntimeException("请先登录再发表回复");
        }
        discussion.setUserId(currentUserId);

        if (discussion.getParentId() == null || discussion.getParentId() == 0) {
            throw new RuntimeException("回复必须指定父级讨论 ID");
        }
        
        StorePlatformDiscussion parent = this.getById(discussion.getParentId());
        if (parent == null) {
            throw new RuntimeException("父级讨论不存在");
        }
        
        // 从父级继承 storeId 和 rootId
        discussion.setStoreId(parent.getStoreId());
        discussion.setLikeCount(0); // 初始化点赞数
        if (parent.getParentId() == 0) {
            // 如果父级是根讨论，那么 rootId 就是父级的 id
            discussion.setRootId(parent.getId());
        } else {
            // 如果父级本身也是回复，那么 rootId 沿用父级的 rootId
            discussion.setRootId(parent.getRootId());
        }
        
        return this.save(discussion);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean likeDiscussion(Integer id) {
        Integer currentUserId = LoginUserUtil.getCurrentUserId();
        if (currentUserId == null) {
            throw new RuntimeException("请先登录再进行点赞");
        }

        // 检查是否已点赞
        LambdaQueryWrapper<StorePlatformDiscussionLike> likeWrapper = new LambdaQueryWrapper<>();
        likeWrapper.eq(StorePlatformDiscussionLike::getDiscussionId, id)
                   .eq(StorePlatformDiscussionLike::getUserId, currentUserId);
        
        if (discussionLikeMapper.selectCount(likeWrapper) > 0) {
            throw new RuntimeException("您已点赞过该内容");
        }

        // 插入点赞记录
        StorePlatformDiscussionLike like = new StorePlatformDiscussionLike();
        like.setDiscussionId(id);
        like.setUserId(currentUserId);
        discussionLikeMapper.insert(like);

        // 更新点赞数
        return this.update().setSql("like_count = like_count + 1").eq("id", id).update();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDiscussion(Integer id) {
        StorePlatformDiscussion discussion = this.getById(id);
        if (discussion == null) {
            return false;
        }

        // 权限校验：只能删除自己发表的讨论
        Integer currentUserId = LoginUserUtil.getCurrentUserId();
        if (currentUserId == null || !currentUserId.equals(discussion.getUserId())) {
            throw new RuntimeException("无权删除他人发表的讨论");
        }

        // 使用配置中的默认策略
        int finalStrategy = discussionConfig.getDefaultDeleteStrategy();

        List<Integer> idsToDelete = new ArrayList<>();
        idsToDelete.add(id);

        if (finalStrategy == StoreDiscussionConfig.STRATEGY_CASCADE) {
            // 级联删除策略
            if (discussion.getParentId() == 0) {
                // 如果是一级讨论，直接查找所有 rootId 等于该 id 的讨论（包括子回复）
                List<StorePlatformDiscussion> allInRoot = this.list(new LambdaQueryWrapper<StorePlatformDiscussion>()
                        .eq(StorePlatformDiscussion::getRootId, id));
                idsToDelete.addAll(allInRoot.stream().map(StorePlatformDiscussion::getId).collect(Collectors.toList()));
            } else {
                // 如果是二级回复，需要通过递归找到所有子级回复
                findAllDescendantIds(id, idsToDelete);
            }
        }

        // 去重
        Set<Integer> uniqueIds = new HashSet<>(idsToDelete);

        // 1. 逻辑删除讨论
        boolean removed = this.removeByIds(uniqueIds);

        if (removed) {
            // 2. 物理删除关联的点赞数据 (讨论删除了，点赞记录也应随之清除)
            discussionLikeMapper.delete(new LambdaQueryWrapper<StorePlatformDiscussionLike>()
                    .in(StorePlatformDiscussionLike::getDiscussionId, uniqueIds));
        }

        return removed;
    }

    /**
     * 递归查找所有子级 ID (用于级联删除)
     */
    private void findAllDescendantIds(Integer parentId, List<Integer> resultList) {
        List<StorePlatformDiscussion> children = this.list(new LambdaQueryWrapper<StorePlatformDiscussion>()
                .eq(StorePlatformDiscussion::getParentId, parentId));
        if (!CollectionUtils.isEmpty(children)) {
            for (StorePlatformDiscussion child : children) {
                resultList.add(child.getId());
                findAllDescendantIds(child.getId(), resultList);
            }
        }
    }

    private StorePlatformDiscussionUserVo convertToVo(StorePlatformDiscussion discussion) {
        if (discussion == null) return null;
        StorePlatformDiscussionUserVo vo = new StorePlatformDiscussionUserVo();
        BeanUtils.copyProperties(discussion, vo);
        return vo;
    }

    private StorePlatformDiscussionUserVo convertToVoWithUserInfo(StorePlatformDiscussion discussion) {
        StorePlatformDiscussionUserVo vo = convertToVo(discussion);
        if (vo != null) {
            List<StorePlatformDiscussionUserVo> list = new ArrayList<>();
            list.add(vo);
            fillUserInfoBatch(list);
        }
        return vo;
    }

    /**
     * 批量填充用户信息和点赞状态
     */
    private void fillUserInfoBatch(List<StorePlatformDiscussionUserVo> voList) {
        if (CollectionUtils.isEmpty(voList)) return;

        // 提取所有用户ID和父级ID对应的人
        Set<Integer> userIds = voList.stream().map(StorePlatformDiscussionUserVo::getUserId).collect(Collectors.toSet());
        
        // 提取所有父级讨论，用于获取回复对象的名称
        Set<Integer> parentIds = voList.stream()
                .map(StorePlatformDiscussionUserVo::getParentId)
                .filter(id -> id != null && id != 0)
                .collect(Collectors.toSet());

        // 获取评论人信息
        Map<Integer, LifeUser> userMap = getUserMap(userIds);
        
        // 获取回复对象信息 (如果是回复，需要知道在回复谁)
        Map<Integer, String> parentUserNameMap = getParentUserNameMap(parentIds);

        // 获取当前用户的点赞状态
        Integer currentUserId = LoginUserUtil.getCurrentUserId();
        Set<Integer> likedDiscussionIds = Collections.emptySet();
        if (currentUserId != null) {
            List<Integer> discussionIds = voList.stream().map(StorePlatformDiscussionUserVo::getId).collect(Collectors.toList());
            likedDiscussionIds = discussionLikeMapper.selectList(new LambdaQueryWrapper<StorePlatformDiscussionLike>()
                    .eq(StorePlatformDiscussionLike::getUserId, currentUserId)
                    .in(StorePlatformDiscussionLike::getDiscussionId, discussionIds))
                    .stream()
                    .map(StorePlatformDiscussionLike::getDiscussionId)
                    .collect(Collectors.toSet());
        }

        final Set<Integer> finalLikedIds = likedDiscussionIds;
        voList.forEach(vo -> {
            LifeUser user = userMap.get(vo.getUserId());
            if (user != null) {
                vo.setUserName(user.getUserName());
                vo.setUserImage(user.getUserImage());
            }
            if (vo.getParentId() != null && vo.getParentId() != 0) {
                vo.setParentUserName(parentUserNameMap.get(vo.getParentId()));
            }
            vo.setIsLiked(finalLikedIds.contains(vo.getId()) ? 1 : 0);
        });
    }

    private Map<Integer, LifeUser> getUserMap(Set<Integer> userIds) {
        if (CollectionUtils.isEmpty(userIds)) return Collections.emptyMap();
        List<LifeUser> users = lifeUserMapper.selectBatchIds(userIds);
        return users.stream().collect(Collectors.toMap(LifeUser::getId, u -> u));
    }

    private Map<Integer, String> getParentUserNameMap(Set<Integer> parentIds) {
        if (CollectionUtils.isEmpty(parentIds)) return Collections.emptyMap();
        List<StorePlatformDiscussion> parents = this.baseMapper.selectBatchIds(parentIds);
        if (CollectionUtils.isEmpty(parents)) return Collections.emptyMap();
        
        Set<Integer> parentUserIds = parents.stream().map(StorePlatformDiscussion::getUserId).collect(Collectors.toSet());
        Map<Integer, LifeUser> userMap = getUserMap(parentUserIds);
        
        return parents.stream().collect(Collectors.toMap(
                StorePlatformDiscussion::getId,
                p -> {
                    LifeUser u = userMap.get(p.getUserId());
                    return u != null ? u.getUserName() : "未知用户";
                }
        ));
    }
}
