import { Injectable, Logger } from '@nestjs/common';
import { DocumentImportRepository } from './document-import.repository';
import { RedisService } from '../../infrastructure/redis/redis.service';
import { QueueService } from '../../infrastructure/queue/queue.service';

@Injectable()
export class DocumentImportService {
  private readonly logger = new Logger(DocumentImportService.name);

  constructor(
    private readonly repository: DocumentImportRepository,
    private readonly redis: RedisService,
    private readonly queue: QueueService,
  ) {}

  async createImport(dto: {
    userId?: string;
    knowledgeBaseId?: string;
    fileName?: string;
    sourceType?: string;
    rawText?: string;
  }) {
    this.logger.log(`createImport called: userId=${dto.userId}, kbId=${dto.knowledgeBaseId}, fileName=${dto.fileName}, sourceType=${dto.sourceType}`);
    try {
      // Use unique lock key per upload attempt to avoid blocking retries
      const lockKey = `lock:document-import:${dto.fileName || 'file'}:${Date.now()}`;
      this.logger.log(`Acquiring lock: ${lockKey}`);
      const lockToken = await this.redis.lock(lockKey, 300); // 5 min TTL, enough for one upload
      if (!lockToken) {
        throw new Error('相同文件正在导入中，请稍候');
      }

      try {
        this.logger.log(`Creating DB record...`);
        const job = await this.repository.create(dto);
        this.logger.log(`DB record created: ${job.id}`);

        await this.redis.set(`job:document-import:${job.id}:status`, 'pending', 86400);
        await this.redis.set(`job:document-import:${job.id}:progress`, '0', 86400);
        await this.redis.set(`job:document-import:${job.id}:message`, '任务已加入队列', 86400);

        this.logger.log(`Enqueuing job...`);
        await this.queue.add('document-import', {
          importId: job.id,
          userId: dto.userId || 'anonymous',
          knowledgeBaseId: dto.knowledgeBaseId,
          rawText: dto.rawText,
          fileName: dto.fileName,
        });
        this.logger.log(`Job enqueued: ${job.id}`);

        return { id: job.id, status: 'queued' };
      } finally {
        await this.redis.unlock(lockKey, lockToken);
      }
    } catch (err: any) {
      this.logger.error(`createImport failed: ${err.message}`, err.stack);
      throw err;
    }
  }

  async getStatus(id: string) {
    const redisStatus = await this.redis.get(`job:document-import:${id}:status`);
    const redisProgress = await this.redis.get(`job:document-import:${id}:progress`);
    const redisMessage = await this.redis.get(`job:document-import:${id}:message`);
    const dbJob = await this.repository.findById(id);

    return {
      id,
      fileName: dbJob?.sourceName,
      status: redisStatus || dbJob?.status || 'unknown',
      progress: redisProgress ? parseInt(redisProgress, 10) : 0,
      message: redisMessage || null,
    };
  }
}
