import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Logger } from '@nestjs/common';
import { Job } from 'bullmq';
import { QUEUE_DOCUMENT_IMPORT } from '../infrastructure/queue/queue.service';
import { workerOptionsFor } from '../infrastructure/queue/queue-definitions';
import { DocumentImportRepository } from '../modules/document-import/document-import.repository';
import { KnowledgeItemsRepository } from '../modules/knowledge-items/knowledge-items.repository';
import { KnowledgeImportWorkflow } from '../modules/ai/workflows/knowledge-import.workflow';
import { RedisService } from '../infrastructure/redis/redis.service';

@Processor(QUEUE_DOCUMENT_IMPORT, workerOptionsFor(QUEUE_DOCUMENT_IMPORT))
export class DocumentImportWorker extends WorkerHost {
  private readonly logger = new Logger(DocumentImportWorker.name);

  constructor(
    private readonly repository: DocumentImportRepository,
    private readonly knowledgeItemsRepo: KnowledgeItemsRepository,
    private readonly workflow: KnowledgeImportWorkflow,
    private readonly redis: RedisService,
  ) {
    super();
  }

  async process(job: Job<{
    importId: string;
    userId: string;
    knowledgeBaseId?: string;
    sourceId?: string;
    rawText?: string;
    fileName?: string;
  }>) {
    const { importId, userId, knowledgeBaseId, rawText, fileName } = job.data;
    // Resolve sourceId: from job data first, then fallback to DocumentImport record
    let sourceId = job.data.sourceId;
    if (!sourceId) {
      const importRecord = await this.repository.findById(importId);
      sourceId = importRecord?.sourceId ?? undefined;
    }
    this.logger.log(`Processing document import job ${job.id}, importId=${importId}, sourceId=${sourceId ?? 'none'}`);

    try {
      if (!rawText) {
        await this.repository.updateStatus(importId, 'completed');
        await this.redis.set(`job:document-import:${importId}:status`, 'completed', 86400);
        await this.redis.set(`job:document-import:${importId}:progress`, '100', 86400);
        await this.redis.set(`job:document-import:${importId}:message`, '无需解析的空文件', 86400);
        return;
      }

      await this.repository.updateStatus(importId, 'processing');
      await this.redis.set(`job:document-import:${importId}:status`, 'parsing', 86400);
      await this.redis.set(`job:document-import:${importId}:progress`, '25', 86400);
      await this.redis.set(`job:document-import:${importId}:message`, 'AI 正在分析文本，提取知识点...', 86400);

      const result = await this.workflow.execute({
        userId,
        rawText,
        sourceName: fileName,
      });

      await this.redis.set(`job:document-import:${importId}:status`, 'saving', 86400);
      await this.redis.set(`job:document-import:${importId}:progress`, '80', 86400);
      await this.redis.set(`job:document-import:${importId}:message`, `正在保存 ${result.knowledgePoints.length} 个知识点...`, 86400);

      if (knowledgeBaseId && result.knowledgePoints.length > 0) {
        for (let i = 0; i < result.knowledgePoints.length; i++) {
          const kp = result.knowledgePoints[i];
          await this.knowledgeItemsRepo.create(userId, knowledgeBaseId, {
            title: kp.title,
            content: kp.content,
            itemType: 'lesson',
            orderIndex: kp.suggestedOrder ?? i + 1,
            sourceId: sourceId,
            sourceRef: sourceId,
          });
        }
      }

      await this.repository.updateStatus(importId, 'completed');
      await this.redis.set(`job:document-import:${importId}:status`, 'completed', 86400);
      await this.redis.set(`job:document-import:${importId}:progress`, '100', 86400);
      await this.redis.set(`job:document-import:${importId}:message`, `成功提取 ${result.knowledgePoints.length} 个知识点`, 86400);
      this.logger.log(`Document import job ${job.id} completed: ${result.knowledgePoints.length} knowledge points`);
    } catch (err: any) {
      this.logger.error(`Document import job ${job.id} failed: ${err.message}`);
      await this.repository.updateStatus(importId, 'failed');
      await this.redis.set(`job:document-import:${importId}:status`, 'failed', 86400);
      await this.redis.set(`job:document-import:${importId}:message`, `导入失败: ${err.message}`, 86400);
      throw err;
    }
  }
}
