import { Injectable, Logger } from '@nestjs/common';
import { InjectQueue } from '@nestjs/bullmq';
import { Queue } from 'bullmq';
import { ConfigService } from '@nestjs/config';
import Redis from 'ioredis';

export interface VideoGenerationJobPayload {
  projectId: string;
  renderJobId: string;
  scriptJson: unknown;
  language: string;
  aspectRatio: string;
  videoStyle: string;
  targetDuration: number;
  scenes: Array<{
    id: string;
    order: number;
    narrationText: string;
    visualPrompt: string;
    subtitleText: string;
    duration: number;
    transitionType: string;
    ambientSoundPrompt?: string; // AudioGen: sahne bazlı ortam sesi
    imagePath?: string; // Gemini'den üretilen görselin yerel yolu
    ttsProvider?: string; // openai veya elevenlabs
  }>;
}

@Injectable()
export class VideoGenerationProducer {
  private readonly logger = new Logger(VideoGenerationProducer.name);
  private readonly redisClient: Redis;
  private readonly workerQueueKey: string;

  constructor(
    @InjectQueue('video-generation')
    private readonly videoQueue: Queue,
    private readonly configService: ConfigService,
  ) {
    this.redisClient = new Redis({
      host: this.configService.get<string>('redis.host', 'localhost'),
      port: this.configService.get<number>('redis.port', 6379),
      password: this.configService.get<string>('redis.password') || undefined,
    });

    this.workerQueueKey = 'contgen:queue:video-generation';
  }

  /**
   * Job'ı hem BullMQ'ya hem de Redis List'e ekler.
   * BullMQ: NestJS tarafında lifecycle tracking
   * Redis List: C# Worker BRPOP ile consume eder
   */
  async addVideoGenerationJob(payload: VideoGenerationJobPayload): Promise<string> {
    const bullJob = await this.videoQueue.add(
      'generate-video',
      payload,
      {
        attempts: 3,
        backoff: { type: 'exponential', delay: 5000 },
        removeOnComplete: { count: 100, age: 7 * 24 * 3600 },
        removeOnFail: { count: 50 },
        priority: 1,
      },
    );

    const workerPayload = JSON.stringify({
      jobId: bullJob.id,
      ...payload,
      timestamp: new Date().toISOString(),
    });

    await this.redisClient.lpush(this.workerQueueKey, workerPayload);

    this.logger.log(
      `Job kuyruğa eklendi — BullMQ: ${bullJob.id}, Redis Key: ${this.workerQueueKey}`,
    );

    return bullJob.id || '';
  }

  async getQueueStats() {
    const [waiting, active, completed, failed] = await Promise.all([
      this.videoQueue.getWaitingCount(),
      this.videoQueue.getActiveCount(),
      this.videoQueue.getCompletedCount(),
      this.videoQueue.getFailedCount(),
    ]);

    const workerQueueLength = await this.redisClient.llen(this.workerQueueKey);

    return {
      bullmq: { waiting, active, completed, failed },
      workerQueue: { pending: workerQueueLength },
    };
  }
}
