/**
 * Logger utility for GBFS pipeline
 * Logs to both console and file with structured format
 */

import * as fs from 'fs'
import * as path from 'path'

export enum LogLevel {
  INFO = 'INFO',
  WARN = 'WARN',
  ERROR = 'ERROR',
  SUCCESS = 'SUCCESS'
}

export interface LogEntry {
  timestamp: string
  level: LogLevel
  script: string
  message: string
  details?: any
}

export class Logger {
  private logDir: string
  private logFile: string
  private scriptName: string

  constructor(scriptName: string) {
    this.scriptName = scriptName
    this.logDir = path.join(__dirname, '..', 'logs')

    // Create logs directory if it doesn't exist
    if (!fs.existsSync(this.logDir)) {
      fs.mkdirSync(this.logDir, { recursive: true })
    }

    // Create daily log file
    const date = new Date().toISOString().split('T')[0]
    this.logFile = path.join(this.logDir, `gbfs-${date}.log`)
  }

  private formatEntry(level: LogLevel, message: string, details?: any): LogEntry {
    return {
      timestamp: new Date().toISOString(),
      level,
      script: this.scriptName,
      message,
      details: details || undefined
    }
  }

  private writeToFile(entry: LogEntry): void {
    try {
      // Format as human-readable log entry in Lisbon timezone
      const timestamp = new Date(entry.timestamp).toLocaleString('en-US', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        hour12: false,
        timeZone: 'Europe/Lisbon'
      })

      let logLine = `[${timestamp}] ${entry.level.padEnd(7)} [${entry.script}] ${entry.message}`

      if (entry.details) {
        logLine += '\n  Details: ' + JSON.stringify(entry.details, null, 2).split('\n').join('\n  ')
      }

      logLine += '\n' + '-'.repeat(80) + '\n'

      fs.appendFileSync(this.logFile, logLine)
    } catch (error) {
      console.error('Failed to write to log file:', error)
    }
  }

  private getIcon(level: LogLevel): string {
    switch (level) {
      case LogLevel.INFO:
        return 'ℹ️'
      case LogLevel.WARN:
        return '⚠️'
      case LogLevel.ERROR:
        return '❌'
      case LogLevel.SUCCESS:
        return '✅'
    }
  }

  info(message: string, details?: any): void {
    console.log(`${this.getIcon(LogLevel.INFO)} ${message}`)
    // Don't write INFO to file
  }

  warn(message: string, details?: any): void {
    const entry = this.formatEntry(LogLevel.WARN, message, details)
    console.warn(`${this.getIcon(LogLevel.WARN)} ${message}`)
    this.writeToFile(entry)
  }

  error(message: string, error?: Error | any): void {
    const details = error instanceof Error ? { message: error.message, stack: error.stack } : error

    const entry = this.formatEntry(LogLevel.ERROR, message, details)
    console.error(`${this.getIcon(LogLevel.ERROR)} ${message}`)
    if (error instanceof Error) {
      console.error('  Error:', error.message)
    }
    this.writeToFile(entry)
  }

  success(message: string, details?: any): void {
    console.log(`${this.getIcon(LogLevel.SUCCESS)} ${message}`)
    // Don't write SUCCESS to file
  }

  separator(): void {
    console.log('='.repeat(60))
  }

  section(title: string): void {
    console.log('\n' + '='.repeat(60))
    console.log(title)
    console.log('='.repeat(60))
  }
}

/**
 * Create a logger instance for a script
 */
export function createLogger(scriptName: string): Logger {
  return new Logger(scriptName)
}
