import { writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';
import { dirname } from 'path';

export interface TTILogEntry {
  timestamp: string;
  orgId: string;
  projectId: string;
  prompt: string;
  meta?: {
    tags?: string[];
  };
  referenceImages?: Array<{
    mimetype: string;
    size: number;
    originalname: string;
  }>;
  model: string;
  config: any;
}

export class TTILogger {
  private static instance: TTILogger | null = null;
  private logFilePath: string | null = null;
  private isEnabled: boolean = false;

  private constructor() {
    const ttiLogPath = process.env['TTI_LOG'];

    if (ttiLogPath) {
      this.logFilePath = ttiLogPath;
      this.isEnabled = true;
      this.initializeLogFile();
    }
  }

  static getInstance(): TTILogger {
    if (!TTILogger.instance) {
      TTILogger.instance = new TTILogger();
    }
    return TTILogger.instance;
  }

  private initializeLogFile(): void {
    if (!this.logFilePath) return;

    try {
      // Ensure directory exists
      const dir = dirname(this.logFilePath);
      if (!existsSync(dir)) {
        mkdirSync(dir, { recursive: true });
      }

      // Reset/clear the log file on service start
      writeFileSync(this.logFilePath, '# Text-to-Image Generation Log\n\n', {
        encoding: 'utf-8',
      });

      console.log(`[TTILogger] Log file initialized: ${this.logFilePath}`);
    } catch (error) {
      console.error(`[TTILogger] Failed to initialize log file:`, error);
      this.isEnabled = false;
    }
  }

  log(entry: TTILogEntry): void {
    if (!this.isEnabled || !this.logFilePath) {
      return;
    }

    try {
      const newLogEntry = this.formatLogEntry(entry);

      // Read existing content
      const existingContent = existsSync(this.logFilePath)
        ? readFileSync(this.logFilePath, 'utf-8')
        : '# Text-to-Image Generation Log\n\n';

      // Insert new entry AFTER header but BEFORE old entries
      const headerEnd = existingContent.indexOf('\n\n') + 2;
      const header = existingContent.slice(0, headerEnd);
      const oldEntries = existingContent.slice(headerEnd);

      writeFileSync(this.logFilePath, header + newLogEntry + oldEntries, 'utf-8');
    } catch (error) {
      console.error(`[TTILogger] Failed to write log entry:`, error);
    }
  }

  private formatLogEntry(entry: TTILogEntry): string {
    const { timestamp, orgId, projectId, prompt, meta, referenceImages, model, config } = entry;

    // Format date from ISO timestamp
    const date = new Date(timestamp);
    const formattedDate = date.toISOString().replace('T', ' ').slice(0, 19);

    let logText = `## ${formattedDate}\n`;
    logText += `${orgId}/${projectId}\n\n`;
    logText += `**Prompt:** ${prompt}\n\n`;

    // Add tags if present
    if (meta?.tags && meta.tags.length > 0) {
      logText += `**Tags:** ${meta.tags.join(', ')}\n\n`;
    }

    if (referenceImages && referenceImages.length > 0) {
      logText += `**Reference Images:** ${referenceImages.length} image${referenceImages.length > 1 ? 's' : ''}\n`;
      for (const img of referenceImages) {
        const sizeMB = (img.size / (1024 * 1024)).toFixed(2);
        logText += `- ${img.originalname} (${img.mimetype}, ${sizeMB} MB)\n`;
      }
      logText += '\n';
    }

    logText += `**Model:** ${model}\n`;
    logText += `**Config:** ${JSON.stringify(config)}\n\n`;
    logText += `---\n\n`;

    return logText;
  }
}
