import { Injectable, Inject } from '@nestjs/common';
import { EmbeddingService } from '../../infrastructure/embedding/embedding.service';
import { ChunkingService } from './chunking.service';
import {
  IKnowledgeRepository,
  KNOWLEDGE_REPOSITORY,
} from '../../domain/repositories/knowledge.repository.interface';
import {
  KnowledgeArticleEntity,
  KnowledgeSource,
} from '../../domain/entities/knowledge-article.entity';

/**
 * 知识管理服务
 * 提供知识库的CRUD操作和处理
 */
@Injectable()
export class KnowledgeService {
  constructor(
    private embeddingService: EmbeddingService,
    private chunkingService: ChunkingService,
    @Inject(KNOWLEDGE_REPOSITORY)
    private knowledgeRepo: IKnowledgeRepository,
  ) {}

  /**
   * 创建知识文章
   */
  async createArticle(params: {
    title: string;
    content: string;
    category: string;
    tags?: string[];
    source?: KnowledgeSource;
    sourceUrl?: string;
    createdBy?: string;
    autoPublish?: boolean;
  }): Promise<KnowledgeArticleEntity> {
    // 1. 创建文章实体
    const article = KnowledgeArticleEntity.create({
      title: params.title,
      content: params.content,
      category: params.category,
      tags: params.tags,
      source: params.source || KnowledgeSource.MANUAL,
      sourceUrl: params.sourceUrl,
      createdBy: params.createdBy,
    });

    // 2. 生成文章向量
    const embedding = await this.embeddingService.getEmbedding(
      `${article.title}\n${article.summary}`,
    );
    article.setEmbedding(embedding);

    // 3. 自动发布（可选）
    if (params.autoPublish) {
      article.publish();
    }

    // 4. 保存文章
    await this.knowledgeRepo.saveArticle(article);

    // 5. 分块并保存
    await this.processArticleChunks(article);

    console.log(`[KnowledgeService] Created article: ${article.id} - ${article.title}`);

    return article;
  }

  /**
   * 处理文章分块
   */
  private async processArticleChunks(article: KnowledgeArticleEntity): Promise<void> {
    // 1. 删除旧的块
    await this.knowledgeRepo.deleteChunksByArticleId(article.id);

    // 2. 分块
    const chunks = this.chunkingService.chunkArticle(article);

    // 3. 批量生成向量
    const embeddings = await this.embeddingService.getEmbeddings(
      chunks.map(c => c.content),
    );

    // 4. 设置向量
    chunks.forEach((chunk, index) => {
      chunk.setEmbedding(embeddings[index]);
    });

    // 5. 保存块
    await this.knowledgeRepo.saveChunks(chunks);

    console.log(`[KnowledgeService] Processed ${chunks.length} chunks for article ${article.id}`);
  }

  /**
   * 更新文章
   */
  async updateArticle(
    articleId: string,
    params: {
      title?: string;
      content?: string;
      category?: string;
      tags?: string[];
      updatedBy?: string;
    },
  ): Promise<KnowledgeArticleEntity> {
    const article = await this.knowledgeRepo.findArticleById(articleId);
    if (!article) {
      throw new Error(`Article not found: ${articleId}`);
    }

    // 更新字段
    if (params.title || params.content) {
      article.updateContent(
        params.title || article.title,
        params.content || article.content,
        params.updatedBy,
      );

      // 重新生成向量
      const embedding = await this.embeddingService.getEmbedding(
        `${article.title}\n${article.summary}`,
      );
      article.setEmbedding(embedding);

      // 重新分块
      await this.processArticleChunks(article);
    }

    if (params.category) {
      article.category = params.category;
    }

    if (params.tags) {
      article.tags = params.tags;
    }

    await this.knowledgeRepo.updateArticle(article);

    return article;
  }

  /**
   * 获取文章详情
   */
  async getArticle(articleId: string): Promise<KnowledgeArticleEntity | null> {
    return this.knowledgeRepo.findArticleById(articleId);
  }

  /**
   * 获取文章列表
   */
  async listArticles(params: {
    category?: string;
    publishedOnly?: boolean;
    page?: number;
    pageSize?: number;
  }): Promise<{
    items: KnowledgeArticleEntity[];
    total: number;
    page: number;
    pageSize: number;
  }> {
    const page = params.page || 1;
    const pageSize = params.pageSize || 20;
    const offset = (page - 1) * pageSize;

    const [items, total] = await Promise.all([
      this.knowledgeRepo.findArticlesByCategory(params.category || '', {
        publishedOnly: params.publishedOnly,
        limit: pageSize,
        offset,
      }),
      this.knowledgeRepo.countArticles({
        category: params.category,
        publishedOnly: params.publishedOnly,
      }),
    ]);

    return { items, total, page, pageSize };
  }

  /**
   * 搜索文章
   */
  async searchArticles(params: {
    query: string;
    category?: string;
    useVector?: boolean;
  }): Promise<Array<{
    article: KnowledgeArticleEntity;
    similarity?: number;
  }>> {
    if (params.useVector) {
      // 向量搜索
      const embedding = await this.embeddingService.getEmbedding(params.query);
      const results = await this.knowledgeRepo.searchArticlesByVector(embedding, {
        category: params.category,
        publishedOnly: true,
        limit: 10,
      });
      return results;
    }

    // 关键词搜索
    const articles = await this.knowledgeRepo.searchArticles(params.query, {
      category: params.category,
      publishedOnly: true,
      limit: 10,
    });
    return articles.map(article => ({ article }));
  }

  /**
   * 发布文章
   */
  async publishArticle(articleId: string): Promise<void> {
    const article = await this.knowledgeRepo.findArticleById(articleId);
    if (!article) {
      throw new Error(`Article not found: ${articleId}`);
    }

    article.publish();
    await this.knowledgeRepo.updateArticle(article);
  }

  /**
   * 取消发布
   */
  async unpublishArticle(articleId: string): Promise<void> {
    const article = await this.knowledgeRepo.findArticleById(articleId);
    if (!article) {
      throw new Error(`Article not found: ${articleId}`);
    }

    article.unpublish();
    await this.knowledgeRepo.updateArticle(article);
  }

  /**
   * 删除文章
   */
  async deleteArticle(articleId: string): Promise<void> {
    // 先删除分块
    await this.knowledgeRepo.deleteChunksByArticleId(articleId);
    // 再删除文章
    await this.knowledgeRepo.deleteArticle(articleId);
  }

  /**
   * 记录用户反馈
   */
  async recordFeedback(articleId: string, helpful: boolean): Promise<void> {
    const article = await this.knowledgeRepo.findArticleById(articleId);
    if (!article) {
      throw new Error(`Article not found: ${articleId}`);
    }

    article.recordFeedback(helpful);
    await this.knowledgeRepo.updateArticle(article);
  }

  /**
   * 批量导入文章
   */
  async importArticles(
    articles: Array<{
      title: string;
      content: string;
      category: string;
      tags?: string[];
    }>,
    createdBy?: string,
  ): Promise<{ success: number; failed: number; errors: string[] }> {
    let success = 0;
    let failed = 0;
    const errors: string[] = [];

    for (const articleData of articles) {
      try {
        await this.createArticle({
          ...articleData,
          source: KnowledgeSource.IMPORT,
          createdBy,
          autoPublish: false, // 导入后需要审核
        });
        success++;
      } catch (error) {
        failed++;
        errors.push(`Failed to import "${articleData.title}": ${(error as Error).message}`);
      }
    }

    return { success, failed, errors };
  }

  /**
   * 获取知识库统计
   */
  async getStatistics(): Promise<{
    totalArticles: number;
    publishedArticles: number;
    byCategory: Record<string, number>;
    recentArticles: KnowledgeArticleEntity[];
  }> {
    const categories = ['QMAS', 'GEP', 'IANG', 'TTPS', 'CIES', 'TechTAS', 'GENERAL'];

    const [total, published, byCategoryResults, recent] = await Promise.all([
      this.knowledgeRepo.countArticles(),
      this.knowledgeRepo.countArticles({ publishedOnly: true }),
      Promise.all(
        categories.map(async cat => ({
          category: cat,
          count: await this.knowledgeRepo.countArticles({ category: cat }),
        })),
      ),
      this.knowledgeRepo.findArticlesByCategory('', { limit: 5 }),
    ]);

    const byCategory: Record<string, number> = {};
    byCategoryResults.forEach(r => {
      byCategory[r.category] = r.count;
    });

    return {
      totalArticles: total,
      publishedArticles: published,
      byCategory,
      recentArticles: recent,
    };
  }
}
