import { createModuleLogger } from '../../utils/logger.js';
import { config } from '../../utils/config.js';
import { KIEClient, createKIEClient } from './kie-client.js';
import { GeminiClient, createGeminiClient } from './gemini-client.js';
import type { KIECreateTaskRequest } from '../../types/api.js';

const logger = createModuleLogger('image-provider');

export type ImageProvider = 'kie' | 'gemini';

export interface GenerateImageResult {
  imageUrl: string;
  provider: ImageProvider;
}

/**
 * Unified image generation provider.
 * Priority: Gemini (primary) → KIE (fallback).
 */
export class ImageProviderManager {
  private kieClient: KIEClient | null = null;
  private geminiClient: GeminiClient | null = null;

  constructor() {
    this.refresh();
  }

  /** Re-read config and recreate clients (call after API key update). */
  refresh(): void {
    this.kieClient = config.kieApiKey ? createKIEClient() : null;
    this.geminiClient = config.geminiApiKey ? createGeminiClient(config.geminiApiKey) : null;

    const providers: string[] = [];
    if (this.geminiClient) providers.push('Gemini');
    if (this.kieClient) providers.push('KIE');
    logger.info({ providers, primary: this.getPrimaryProvider() }, 'Image providers initialized');
  }

  /** Returns which provider will be used as primary. */
  getPrimaryProvider(): ImageProvider | null {
    if (this.geminiClient) return 'gemini';
    if (this.kieClient) return 'kie';
    return null;
  }

  /** Returns true if at least one image provider is available. */
  isAvailable(): boolean {
    return !!(this.geminiClient || this.kieClient);
  }

  /** Get the raw KIE client. */
  getKIEClient(): KIEClient | null {
    return this.kieClient;
  }

  /** Get the raw Gemini client. */
  getGeminiClient(): GeminiClient | null {
    return this.geminiClient;
  }

  /**
   * Generate an image. Gemini first, KIE fallback.
   * Uses generateAndWait (synchronous polling).
   */
  async generateAndWait(request: KIECreateTaskRequest): Promise<GenerateImageResult> {
    // Try Gemini first (primary)
    if (this.geminiClient) {
      try {
        logger.info({ prompt: request.prompt.slice(0, 60) }, 'Generating with Gemini (primary)');
        return await this.generateWithGemini(request);
      } catch (geminiError: any) {
        logger.warn({ error: geminiError.message }, 'Gemini image generation failed');

        // Fall back to KIE
        if (this.kieClient) {
          logger.info({}, 'Falling back to KIE');
          const imageUrl = await this.kieClient.generateAndWait(request);
          return { imageUrl, provider: 'kie' };
        }

        throw geminiError;
      }
    }

    // Gemini not available, try KIE
    if (this.kieClient) {
      logger.info({}, 'Gemini not configured, using KIE');
      const imageUrl = await this.kieClient.generateAndWait(request);
      return { imageUrl, provider: 'kie' };
    }

    throw new Error('Görsel üretim servisi yapılandırılmamış. Gemini veya KIE API anahtarı gerekli.');
  }

  private async generateWithGemini(request: KIECreateTaskRequest): Promise<GenerateImageResult> {
    if (!this.geminiClient) {
      throw new Error('Gemini API anahtarı yapılandırılmamış');
    }

    // Collect reference image URLs from request fields
    const refUrls = request.imageInput ?? request.referenceImages ?? request.inputUrls ?? [];

    const imageUrl = await this.geminiClient.generateFromKIERequest({
      prompt: request.prompt,
      aspectRatio: request.aspectRatio,
      referenceImageUrls: refUrls.length > 0 ? refUrls : undefined,
    });

    return { imageUrl, provider: 'gemini' };
  }
}

let _instance: ImageProviderManager | null = null;

export function getImageProvider(): ImageProviderManager {
  if (!_instance) {
    _instance = new ImageProviderManager();
  }
  return _instance;
}

export function refreshImageProvider(): void {
  if (_instance) {
    _instance.refresh();
  }
}
