package org.dromara.knowledge.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.knowledge.domain.KnowledgeHitLog;
import org.dromara.knowledge.domain.bo.KnowledgeHitLogBo;
import org.dromara.knowledge.domain.vo.KnowledgeHitLogVo;
import org.dromara.knowledge.mapper.KnowledgeHitLogMapper;
import org.dromara.knowledge.service.KnowledgeHitLogService;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 知识库命中日志Service业务层处理
 *
 * @author pengles
 */
@RequiredArgsConstructor
@Service
public class KnowledgeHitLogServiceImpl extends ServiceImpl<KnowledgeHitLogMapper, KnowledgeHitLog> implements KnowledgeHitLogService {

    private final KnowledgeHitLogMapper baseMapper;

    /**
     * 查询知识库命中日志
     */
    @Override
    public KnowledgeHitLogVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询知识库命中日志列表
     */
    @Override
    public TableDataInfo<KnowledgeHitLogVo> queryPageList(KnowledgeHitLogBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = buildQueryWrapper(bo);
        Page<KnowledgeHitLogVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询知识库命中日志列表
     */
    @Override
    public List<KnowledgeHitLogVo> queryList(KnowledgeHitLogBo bo) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<KnowledgeHitLog> buildQueryWrapper(KnowledgeHitLogBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getSessionId()), KnowledgeHitLog::getSessionId, bo.getSessionId());
        lqw.eq(StringUtils.isNotBlank(bo.getKnowledgeId()), KnowledgeHitLog::getKnowledgeId, bo.getKnowledgeId());
        lqw.eq(StringUtils.isNotBlank(bo.getDocId()), KnowledgeHitLog::getDocId, bo.getDocId());
        lqw.eq(StringUtils.isNotBlank(bo.getFragmentId()), KnowledgeHitLog::getFragmentId, bo.getFragmentId());
        lqw.like(StringUtils.isNotBlank(bo.getQueryText()), KnowledgeHitLog::getQueryText, bo.getQueryText());
        lqw.ge(bo.getSimilarityScore() != null, KnowledgeHitLog::getSimilarityScore, bo.getSimilarityScore());
        lqw.eq(bo.getRanking() != null, KnowledgeHitLog::getRanking, bo.getRanking());
        lqw.like(StringUtils.isNotBlank(bo.getModelName()), KnowledgeHitLog::getModelName, bo.getModelName());
        lqw.ge(bo.getResponseTime() != null, KnowledgeHitLog::getResponseTime, bo.getResponseTime());
        lqw.ge(bo.getHitCount() != null, KnowledgeHitLog::getHitCount, bo.getHitCount());
        return lqw;
    }

    /**
     * 新增知识库命中日志
     */
    @Override
    public Boolean insertByBo(KnowledgeHitLogBo bo) {
        KnowledgeHitLog add = MapstructUtils.convert(bo, KnowledgeHitLog.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改知识库命中日志
     */
    @Override
    public Boolean updateByBo(KnowledgeHitLogBo bo) {
        KnowledgeHitLog update = MapstructUtils.convert(bo, KnowledgeHitLog.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(KnowledgeHitLog entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除知识库命中日志
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 根据会话ID查询知识库命中日志列表
     */
    @Override
    public List<KnowledgeHitLogVo> queryBySessionId(String sessionId) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeHitLog::getSessionId, sessionId);
        lqw.orderByAsc(KnowledgeHitLog::getRanking);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 根据知识库ID查询知识库命中日志列表
     */
    @Override
    public List<KnowledgeHitLogVo> queryByKnowledgeId(String knowledgeId) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeHitLog::getKnowledgeId, knowledgeId);
        lqw.orderByDesc(KnowledgeHitLog::getCreateTime);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 根据文档ID查询知识库命中日志列表
     */
    @Override
    public List<KnowledgeHitLogVo> queryByDocId(String docId) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeHitLog::getDocId, docId);
        lqw.orderByDesc(KnowledgeHitLog::getCreateTime);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 根据知识片段ID查询知识库命中日志列表
     */
    @Override
    public List<KnowledgeHitLogVo> queryByFragmentId(String fragmentId) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeHitLog::getFragmentId, fragmentId);
        lqw.orderByDesc(KnowledgeHitLog::getCreateTime);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 根据模型名称查询知识库命中日志列表
     */
    @Override
    public List<KnowledgeHitLogVo> queryByModelName(String modelName) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeHitLog::getModelName, modelName);
        lqw.orderByDesc(KnowledgeHitLog::getCreateTime);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 根据相似度分数范围查询知识库命中日志列表
     */
    @Override
    public List<KnowledgeHitLogVo> queryBySimilarityRange(Double minScore, Double maxScore) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.between(KnowledgeHitLog::getSimilarityScore, minScore, maxScore);
        lqw.orderByDesc(KnowledgeHitLog::getSimilarityScore);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 根据查询文本查询知识库命中日志列表
     */
    @Override
    public List<KnowledgeHitLogVo> queryByQueryText(String queryText) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.like(KnowledgeHitLog::getQueryText, queryText);
        lqw.orderByDesc(KnowledgeHitLog::getCreateTime);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 统计知识库命中次数
     */
    @Override
    public Long countHitsByKnowledgeId(String knowledgeId) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeHitLog::getKnowledgeId, knowledgeId);
        return baseMapper.selectCount(lqw);
    }

    /**
     * 统计文档命中次数
     */
    @Override
    public Long countHitsByDocId(String docId) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeHitLog::getDocId, docId);
        return baseMapper.selectCount(lqw);
    }

    /**
     * 统计知识片段命中次数
     */
    @Override
    public Long countHitsByFragmentId(String fragmentId) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeHitLog::getFragmentId, fragmentId);
        return baseMapper.selectCount(lqw);
    }

    /**
     * 获取热门查询列表
     */
    @Override
    public List<Map<String, Object>> getPopularQueries(String knowledgeId, Integer limit) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(knowledgeId), KnowledgeHitLog::getKnowledgeId, knowledgeId);
        lqw.isNotNull(KnowledgeHitLog::getQueryText);
        lqw.ne(KnowledgeHitLog::getQueryText, "");
        lqw.orderByDesc(KnowledgeHitLog::getCreateTime);

        List<KnowledgeHitLog> logs = baseMapper.selectList(lqw);

        // 按查询文本分组统计
        Map<String, Long> queryCountMap = logs.stream()
                .filter(log -> StringUtils.isNotBlank(log.getQueryText()))
                .collect(Collectors.groupingBy(KnowledgeHitLog::getQueryText, Collectors.counting()));

        // 转换为Map列表并按数量排序
        List<Map<String, Object>> result = queryCountMap.entrySet().stream()
                .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
                .limit(limit != null && limit > 0 ? limit : 10)
                .map(entry -> {
                    Map<String, Object> map = new java.util.HashMap<>();
                    map.put("queryText", entry.getKey());
                    map.put("count", entry.getValue());
                    return map;
                })
                .collect(Collectors.toList());

        return result;
    }

    /**
     * 获取平均响应时间
     */
    @Override
    public Double getAverageResponseTime(String knowledgeId) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(knowledgeId), KnowledgeHitLog::getKnowledgeId, knowledgeId);
        lqw.isNotNull(KnowledgeHitLog::getResponseTime);
        lqw.gt(KnowledgeHitLog::getResponseTime, 0L);

        List<KnowledgeHitLog> logs = baseMapper.selectList(lqw);

        if (logs.isEmpty()) {
            return 0.0;
        }

        // 计算平均响应时间
        return logs.stream()
                .filter(log -> log.getResponseTime() != null && log.getResponseTime() > 0)
                .mapToLong(KnowledgeHitLog::getResponseTime)
                .average()
                .orElse(0.0);
    }

    /**
     * 根据排名查询知识库命中日志列表
     */
    @Override
    public List<KnowledgeHitLogVo> queryByRanking(Integer ranking) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeHitLog::getRanking, ranking);
        lqw.orderByDesc(KnowledgeHitLog::getCreateTime);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 根据响应时间范围查询知识库命中日志列表
     */
    @Override
    public List<KnowledgeHitLogVo> queryByResponseTimeRange(Long minTime, Long maxTime) {
        LambdaQueryWrapper<KnowledgeHitLog> lqw = Wrappers.lambdaQuery();
        lqw.between(KnowledgeHitLog::getResponseTime, minTime, maxTime);
        lqw.orderByAsc(KnowledgeHitLog::getResponseTime);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 批量插入知识库命中日志
     */
    @Override
    public Boolean batchInsert(List<KnowledgeHitLogBo> boList) {
        List<KnowledgeHitLog> entityList = boList.stream()
                .map(bo -> MapstructUtils.convert(bo, KnowledgeHitLog.class))
                .collect(Collectors.toList());
        return saveBatch(entityList);
    }

}