import { resolve } from 'path';
import { createModuleLogger } from '../../utils/logger.js';
import { DataStore } from '../data-store/index.js';
import { OpenRouterClient, type ChatMessage } from '../openrouter/client.js';
import { atomicWriteJSON, readJSON } from '../data-store/file-ops.js';

const logger = createModuleLogger('translation');

const GLOSSARY_FILENAME = 'glossary.json';

const TRANSLATION_SYSTEM_PROMPT = `You are a specialized translator for AI image generation prompts.
Your task is to translate Turkish image generation prompts into English.

Rules:
- Translate the Turkish prompt into natural, fluent English suitable for AI image generation models.
- Preserve all technical image generation terms (e.g., lighting terms, camera settings, art styles).
- Keep proper nouns, brand names, and model names unchanged.
- Maintain the structure and order of the prompt elements.
- Do NOT add any explanation or commentary. Output ONLY the translated English prompt.
- If the input contains English words or phrases already, keep them as-is.
- Focus on accuracy for visual description terms: colors, poses, clothing, environments, lighting, camera angles.`;

export interface TranslationResult {
  original: string;
  translated: string;
}

export class TranslationModule {
  private readonly dataStore: DataStore;
  private readonly openRouterClient: OpenRouterClient;

  constructor(dataStore: DataStore, openRouterClient: OpenRouterClient) {
    this.dataStore = dataStore;
    this.openRouterClient = openRouterClient;
  }

  /**
   * Translates a Turkish image generation prompt to English.
   * Applies glossary pre-processing, then uses OpenRouter AI for translation.
   * Falls back to returning the original prompt with enableTranslation hint on failure.
   */
  async translatePrompt(turkishPrompt: string): Promise<TranslationResult> {
    const glossary = await this.getGlossary();
    const preprocessed = this.applyGlossary(turkishPrompt, glossary);

    try {
      const messages: ChatMessage[] = [
        { role: 'system', content: TRANSLATION_SYSTEM_PROMPT },
        { role: 'user', content: preprocessed },
      ];

      const response = await this.openRouterClient.chatCompletion(messages, {
        temperature: 0.7,
        max_tokens: 500,
      });

      const translated = response.choices?.[0]?.message?.content?.trim();

      if (!translated) {
        logger.warn('Empty translation response from OpenRouter, using fallback');
        return this.fallbackTranslation(turkishPrompt);
      }

      logger.info({ original: turkishPrompt, translated }, 'Prompt translated successfully');
      return { original: turkishPrompt, translated };
    } catch (error) {
      logger.error({ error, prompt: turkishPrompt }, 'Translation failed, using fallback');
      return this.fallbackTranslation(turkishPrompt);
    }
  }

  /**
   * Returns the current glossary (Turkish → English term mappings).
   */
  async getGlossary(): Promise<Record<string, string>> {
    const glossaryPath = this.getGlossaryPath();
    const glossary = await readJSON<Record<string, string>>(glossaryPath);
    return glossary ?? {};
  }

  /**
   * Replaces the entire glossary with the provided terms.
   */
  async updateGlossary(terms: Record<string, string>): Promise<void> {
    const glossaryPath = this.getGlossaryPath();
    await atomicWriteJSON(glossaryPath, terms);
    logger.info({ termCount: Object.keys(terms).length }, 'Glossary updated');
  }

  /**
   * Adds a single term to the glossary.
   */
  async addGlossaryTerm(turkish: string, english: string): Promise<void> {
    const glossary = await this.getGlossary();
    glossary[turkish] = english;
    await this.updateGlossary(glossary);
    logger.info({ turkish, english }, 'Glossary term added');
  }

  /**
   * Removes a single term from the glossary.
   */
  async removeGlossaryTerm(turkish: string): Promise<void> {
    const glossary = await this.getGlossary();
    delete glossary[turkish];
    await this.updateGlossary(glossary);
    logger.info({ turkish }, 'Glossary term removed');
  }

  /**
   * Applies glossary term replacements to the text before AI translation.
   * Replaces Turkish terms with their English equivalents.
   * Longer terms are replaced first to avoid partial matches.
   */
  applyGlossary(text: string, glossary: Record<string, string>): string {
    if (!glossary || Object.keys(glossary).length === 0) return text;

    let result = text;
    // Sort by length descending so longer terms are replaced first
    const sortedTerms = Object.keys(glossary).sort((a, b) => b.length - a.length);

    for (const turkish of sortedTerms) {
      const english = glossary[turkish];
      // Case-insensitive replacement
      const regex = new RegExp(escapeRegex(turkish), 'gi');
      result = result.replace(regex, english);
    }

    return result;
  }

  /**
   * Fallback when OpenRouter translation fails.
   * Returns the original prompt as-is — the caller can use KIE API's enableTranslation flag.
   */
  private fallbackTranslation(turkishPrompt: string): TranslationResult {
    logger.warn('Using fallback translation (KIE enableTranslation recommended)');
    return { original: turkishPrompt, translated: turkishPrompt };
  }

  private getGlossaryPath(): string {
    return resolve((this.dataStore as any).dataDir, 'translations', GLOSSARY_FILENAME);
  }
}

function escapeRegex(str: string): string {
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
