package org.dromara.knowledge.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
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.exception.ServiceException;
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.KnowledgeInfo;
import org.dromara.knowledge.domain.bo.KnowledgeInfoBo;
import org.dromara.knowledge.domain.vo.KnowledgeInfoVo;
import org.dromara.knowledge.domain.vo.KnowledgeSearchResultVo;
import org.dromara.knowledge.domain.vo.KnowledgeStatusVo;
import org.dromara.knowledge.mapper.KnowledgeInfoMapper;
import org.dromara.knowledge.service.*;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 知识库信息Service业务层处理
 *
 * @author pengles
 */
@RequiredArgsConstructor
@Service
public class KnowledgeInfoServiceImpl extends ServiceImpl<KnowledgeInfoMapper, KnowledgeInfo> implements KnowledgeInfoService {

    private final KnowledgeInfoMapper baseMapper;
    private final KnowledgeAttachService knowledgeAttachService;
    private final KnowledgeFragmentService knowledgeFragmentService;
    private final KnowledgeVectorService knowledgeVectorService;
    private final KnowledgeJobService knowledgeJobService;
    private final KnowledgeHitLogService knowledgeHitLogService;
    private final KnowledgeDocumentService knowledgeDocumentService;

    /**
     * 查询知识库信息
     */
    @Override
    public KnowledgeInfoVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询知识库信息列表
     */
    @Override
    public TableDataInfo<KnowledgeInfoVo> queryPageList(KnowledgeInfoBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<KnowledgeInfo> lqw = buildQueryWrapper(bo);
        Page<KnowledgeInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询知识库信息列表
     */
    @Override
    public List<KnowledgeInfoVo> queryList(KnowledgeInfoBo bo) {
        LambdaQueryWrapper<KnowledgeInfo> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<KnowledgeInfo> buildQueryWrapper(KnowledgeInfoBo bo) {
        LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(ObjectUtil.isNotNull(bo.getUserId()), KnowledgeInfo::getUserId, bo.getUserId());
        lqw.eq(StringUtils.isNotBlank(bo.getKnowledgeId()), KnowledgeInfo::getKnowledgeId, bo.getKnowledgeId());
        lqw.like(StringUtils.isNotBlank(bo.getKnowledgeName()), KnowledgeInfo::getKnowledgeName, bo.getKnowledgeName());
        lqw.eq(ObjectUtil.isNotNull(bo.getShare()), KnowledgeInfo::getShare, bo.getShare());
        lqw.like(StringUtils.isNotBlank(bo.getDescription()), KnowledgeInfo::getDescription, bo.getDescription());
        lqw.eq(StringUtils.isNotBlank(bo.getVectorModelName()), KnowledgeInfo::getVectorModelName, bo.getVectorModelName());
        lqw.eq(StringUtils.isNotBlank(bo.getEmbeddingModelName()), KnowledgeInfo::getEmbeddingModelName, bo.getEmbeddingModelName());
        return lqw;
    }

    /**
     * 新增知识库信息
     */
    @Override
    public Boolean insertByBo(KnowledgeInfoBo bo) {
        KnowledgeInfo add = BeanUtil.toBean(bo, KnowledgeInfo.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改知识库信息
     */
    @Override
    public Boolean updateByBo(KnowledgeInfoBo bo) {
        KnowledgeInfo update = BeanUtil.toBean(bo, KnowledgeInfo.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

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

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

    /**
     * 根据用户ID查询知识库列表
     */
    @Override
    public List<KnowledgeInfoVo> queryListByUserId(Long userId) {
        LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeInfo::getUserId, userId);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 根据知识库ID查询知识库信息
     */
    @Override
    public KnowledgeInfoVo queryByKnowledgeId(Long knowledgeId) {
        LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeInfo::getId, knowledgeId);
        return baseMapper.selectVoOne(lqw);
    }

    @Override
    public String uploadDocument(String knowledgeId, MultipartFile file) {
        if (file.isEmpty()) {
            throw new ServiceException("上传文件不能为空");
        }

        // 验证知识库是否存在
        LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeInfo::getKnowledgeId, knowledgeId);
        KnowledgeInfo knowledgeInfo = baseMapper.selectOne(lqw);
        if (knowledgeInfo == null) {
            throw new ServiceException("知识库不存在");
        }

        // 验证文件大小（限制为50MB）
        if (file.getSize() > 50 * 1024 * 1024) {
            throw new ServiceException("文件大小不能超过50MB");
        }

        // 使用文档处理服务上传文档
        return knowledgeDocumentService.processUploadedDocument(knowledgeId, file);
    }

    @Override
    public List<String> batchUploadDocuments(String knowledgeId, MultipartFile[] files) {
        List<String> docIds = new ArrayList<>();
        List<String> failedFiles = new ArrayList<>();

        for (MultipartFile file : files) {
            try {
                String docId = uploadDocument(knowledgeId, file);
                docIds.add(docId);
            } catch (Exception e) {
                failedFiles.add(file.getOriginalFilename() + ": " + e.getMessage());
            }
        }

        if (!failedFiles.isEmpty()) {
            throw new ServiceException("部分文件上传失败: " + String.join(", ", failedFiles));
        }

        return docIds;
    }

    @Override
    public List<KnowledgeSearchResultVo> searchKnowledge(String knowledgeId, String query, Integer limit) {
        // 验证知识库是否存在
        LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeInfo::getKnowledgeId, knowledgeId);
        KnowledgeInfo knowledgeInfo = baseMapper.selectOne(lqw);
        if (knowledgeInfo == null) {
            throw new ServiceException("知识库不存在");
        }

        // 获取知识库的向量模型
        String vectorModel = knowledgeInfo.getVectorModelName();
        if (vectorModel == null) {
            vectorModel = "bge-base-zh"; // 默认模型
        }

        // 设置默认值
        if (limit == null) {
            limit = 10;
        }
        Double threshold = 0.7; // 默认相似度阈值

        // 使用向量服务进行搜索
        return knowledgeVectorService.vectorSimilaritySearch(knowledgeId, query, vectorModel, limit, threshold);
    }

    @Override
    public KnowledgeStatusVo getKnowledgeStatus(String knowledgeId) {
        // 验证知识库是否存在
        LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeInfo::getKnowledgeId, knowledgeId);
        KnowledgeInfo knowledgeInfo = baseMapper.selectOne(lqw);
        if (knowledgeInfo == null) {
            throw new ServiceException("知识库不存在");
        }

        // 转换为VO对象
        KnowledgeInfoVo knowledgeInfoVo = baseMapper.selectVoById(knowledgeInfo.getId());

        // 使用文档处理服务获取状态信息
        return knowledgeDocumentService.getKnowledgeProcessingStatus(Long.valueOf(knowledgeId), knowledgeInfoVo);
    }

    @Override
    public String processDocument(String knowledgeId, String docId, String content) {
        // 验证知识库是否存在
        LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeInfo::getKnowledgeId, knowledgeId);
        KnowledgeInfo knowledgeInfo = baseMapper.selectOne(lqw);
        if (knowledgeInfo == null) {
            throw new ServiceException("知识库不存在");
        }

        // 使用文档处理服务处理文档
        return knowledgeDocumentService.processDocumentContent(knowledgeId, docId, content, knowledgeInfo);
    }

    @Override
    public String vectorizeFragment(String knowledgeId, String fragmentId) {
        // 验证知识库是否存在
        LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(KnowledgeInfo::getKnowledgeId, knowledgeId);
        KnowledgeInfo knowledgeInfo = baseMapper.selectOne(lqw);
        if (knowledgeInfo == null) {
            throw new ServiceException("知识库不存在");
        }

        // 使用文档处理服务进行向量化
        return knowledgeDocumentService.vectorizeKnowledgeFragment(knowledgeId, fragmentId, knowledgeInfo);
    }
}