import { prisma } from '../../config/database.js';
import { difyClient } from '../../common/rag/DifyClient.js';
import { calculateDocumentTokens, selectDocumentsForFullText, TOKEN_LIMITS } from './tokenService.js';

/**
 * 知识库服务
 */

/**
 * 创建知识库
 */
export async function createKnowledgeBase(
  userId: string,
  name: string,
  description?: string
) {
  // 1. 检查用户知识库配额
  const user = await prisma.user.findUnique({
    where: { id: userId },
    select: { kbQuota: true, kbUsed: true }
  });

  if (!user) {
    throw new Error('User not found');
  }

  if (user.kbUsed >= user.kbQuota) {
    throw new Error(`Knowledge base quota exceeded. Maximum: ${user.kbQuota}`);
  }

  // 2. 在Dify中创建Dataset
  const difyDataset = await difyClient.createDataset({
    name: `${userId}_${name}_${Date.now()}`,
    description: description || `Knowledge base for user ${userId}`,
    indexing_technique: 'high_quality',
  });

  // 3. 在数据库中创建记录
  const knowledgeBase = await prisma.knowledgeBase.create({
    data: {
      userId,
      name,
      description,
      difyDatasetId: difyDataset.id,
    },
  });

  // 4. 更新用户的知识库使用计数
  await prisma.user.update({
    where: { id: userId },
    data: {
      kbUsed: { increment: 1 },
    },
  });

  // 5. 转换BigInt为Number
  return {
    ...knowledgeBase,
    totalSizeBytes: Number(knowledgeBase.totalSizeBytes),
  };
}

/**
 * 获取用户的知识库列表
 */
export async function getKnowledgeBases(userId: string) {
  const knowledgeBases = await prisma.knowledgeBase.findMany({
    where: { userId },
    orderBy: { createdAt: 'desc' },
    include: {
      _count: {
        select: { documents: true },
      },
    },
  });

  // 转换BigInt为Number
  return knowledgeBases.map(kb => ({
    ...kb,
    totalSizeBytes: Number(kb.totalSizeBytes),
  }));
}

/**
 * 获取知识库详情
 */
export async function getKnowledgeBaseById(userId: string, kbId: string) {
  const knowledgeBase = await prisma.knowledgeBase.findFirst({
    where: {
      id: kbId,
      userId,  // 确保只能访问自己的知识库
    },
    include: {
      documents: {
        orderBy: { uploadedAt: 'desc' },
      },
      _count: {
        select: { documents: true },
      },
    },
  });

  if (!knowledgeBase) {
    throw new Error('Knowledge base not found or access denied');
  }

  // 转换BigInt为Number
  const result = {
    ...knowledgeBase,
    totalSizeBytes: Number(knowledgeBase.totalSizeBytes),
    documents: knowledgeBase.documents.map(doc => ({
      ...doc,
      fileSizeBytes: Number(doc.fileSizeBytes),
    })),
  };

  return result;
}

/**
 * 更新知识库
 */
export async function updateKnowledgeBase(
  userId: string,
  kbId: string,
  data: { name?: string; description?: string }
) {
  // 1. 验证权限
  const existingKb = await prisma.knowledgeBase.findFirst({
    where: {
      id: kbId,
      userId,
    },
  });

  if (!existingKb) {
    throw new Error('Knowledge base not found or access denied');
  }

  // 2. 更新数据库
  const knowledgeBase = await prisma.knowledgeBase.update({
    where: { id: kbId },
    data,
  });

  // 3. 转换BigInt为Number
  return {
    ...knowledgeBase,
    totalSizeBytes: Number(knowledgeBase.totalSizeBytes),
  };
}

/**
 * 删除知识库
 */
export async function deleteKnowledgeBase(userId: string, kbId: string) {
  // 1. 验证权限
  const knowledgeBase = await prisma.knowledgeBase.findFirst({
    where: {
      id: kbId,
      userId,
    },
  });

  if (!knowledgeBase) {
    throw new Error('Knowledge base not found or access denied');
  }

  // 2. 删除Dify中的Dataset
  try {
    await difyClient.deleteDataset(knowledgeBase.difyDatasetId);
  } catch (error) {
    console.error('Failed to delete Dify dataset:', error);
    // 继续删除本地记录，即使Dify删除失败
  }

  // 3. 删除数据库记录（会级联删除documents）
  await prisma.knowledgeBase.delete({
    where: { id: kbId },
  });

  // 4. 更新用户的知识库使用计数
  await prisma.user.update({
    where: { id: userId },
    data: {
      kbUsed: { decrement: 1 },
    },
  });
}

/**
 * 检索知识库
 */
export async function searchKnowledgeBase(
  userId: string,
  kbId: string,
  query: string,
  topK: number = 15  // Phase 1优化：默认从3增加到15
) {
  console.log('🔍 [searchKnowledgeBase] 开始检索', { kbId, query, topK });
  
  // 1. 验证权限
  const knowledgeBase = await prisma.knowledgeBase.findFirst({
    where: {
      id: kbId,
      userId,
    },
  });

  if (!knowledgeBase) {
    console.error('❌ [searchKnowledgeBase] 知识库不存在', { kbId, userId });
    throw new Error('Knowledge base not found or access denied');
  }

  console.log('📚 [searchKnowledgeBase] 找到知识库', { 
    id: knowledgeBase.id,
    name: knowledgeBase.name,
    difyDatasetId: knowledgeBase.difyDatasetId 
  });

  // 2. 调用Dify检索API
  console.log('🌐 [searchKnowledgeBase] 调用Dify检索API', {
    difyDatasetId: knowledgeBase.difyDatasetId,
    query,
    topK
  });
  
  const results = await difyClient.retrieveKnowledge(
    knowledgeBase.difyDatasetId,
    query,
    {
      retrieval_model: {
        search_method: 'semantic_search',
        top_k: topK,
      },
    }
  );

  console.log('✅ [searchKnowledgeBase] Dify返回结果', {
    recordCount: results.records?.length || 0,
    hasRecords: results.records && results.records.length > 0
  });

  if (results.records && results.records.length > 0) {
    console.log('📄 [searchKnowledgeBase] 检索到的记录:', 
      results.records.map((r: any) => ({
        score: r.score,
        contentPreview: r.segment?.content?.substring(0, 100)
      }))
    );
  } else {
    console.warn('⚠️ [searchKnowledgeBase] 没有检索到任何记录');
  }

  return results;
}

/**
 * 获取知识库统计信息
 */
export async function getKnowledgeBaseStats(userId: string, kbId: string) {
  // 1. 验证权限
  const knowledgeBase = await prisma.knowledgeBase.findFirst({
    where: {
      id: kbId,
      userId,
    },
    include: {
      documents: true,
    },
  });

  if (!knowledgeBase) {
    throw new Error('Knowledge base not found or access denied');
  }

  // 2. 统计信息
  const stats = {
    totalDocuments: knowledgeBase.documents.length,
    completedDocuments: knowledgeBase.documents.filter(d => d.status === 'completed').length,
    processingDocuments: knowledgeBase.documents.filter(d => 
      ['uploading', 'parsing', 'indexing'].includes(d.status)
    ).length,
    errorDocuments: knowledgeBase.documents.filter(d => d.status === 'error').length,
    totalSizeBytes: knowledgeBase.totalSizeBytes,
    totalTokens: knowledgeBase.documents.reduce((sum, d) => sum + (d.tokensCount || 0), 0),
  };

  return stats;
}

/**
 * 获取知识库文档选择（用于全文阅读模式）
 * Phase 2新增：根据Token限制选择文档
 */
export async function getDocumentSelection(
  userId: string,
  kbId: string,
  maxFiles?: number,
  maxTokens?: number
) {
  // 1. 验证权限
  const knowledgeBase = await prisma.knowledgeBase.findFirst({
    where: { id: kbId, userId },
    include: {
      documents: {
        where: {
          status: 'completed',  // 只选择已完成的文档
        },
        select: {
          id: true,
          filename: true,
          extractedText: true,
          charCount: true,
          extractionMethod: true,
          tokensCount: true,
          fileSizeBytes: true,
        },
        orderBy: { uploadedAt: 'desc' },
      },
    },
  });

  if (!knowledgeBase) {
    throw new Error('Knowledge base not found or access denied');
  }

  // 2. 计算每个文档的Token数
  const documentTokens = calculateDocumentTokens(knowledgeBase.documents);

  // 3. 选择文档（根据Token限制）
  const selection = selectDocumentsForFullText(
    documentTokens,
    maxFiles || TOKEN_LIMITS.MAX_FILES,
    maxTokens || TOKEN_LIMITS.MAX_TOTAL_TOKENS
  );

  // 4. 返回结果
  return {
    knowledgeBaseId: kbId,
    knowledgeBaseName: knowledgeBase.name,
    limits: {
      maxFiles: maxFiles || TOKEN_LIMITS.MAX_FILES,
      maxTokens: maxTokens || TOKEN_LIMITS.MAX_TOTAL_TOKENS,
    },
    selection: {
      selectedCount: selection.totalFiles,
      selectedTokens: selection.totalTokens,
      excludedCount: selection.excludedDocuments.length,
      availableTokens: selection.availableTokens,
      reason: selection.reason,
    },
    selectedDocuments: selection.selectedDocuments.map(doc => ({
      ...doc,
      // 查找原始文档信息
      ...knowledgeBase.documents.find(d => d.id === doc.documentId),
    })),
    excludedDocuments: selection.excludedDocuments.map(doc => ({
      ...doc,
      // 查找原始文档信息
      ...knowledgeBase.documents.find(d => d.id === doc.documentId),
    })),
  };
}
