import { injectable } from 'inversify';
import { Logger } from '../../interfaces/Logger';

type LogLevel = 'debug' | 'info' | 'warn' | 'error';

@injectable()
export class ConsoleLogger implements Logger {
  private readonly COLORS: Record<LogLevel, string> = {
    debug: '#888888',
    info: '#00aaff',
    warn: '#ffaa00',
    error: '#ff4444',
  };

  private readonly EMOJIS: Record<LogLevel, string> = {
    debug: '🐛',
    info: 'ℹ️',
    warn: '⚠️',
    error: '❌',
  };

  private readonly PREFIXES: Record<LogLevel, string> = {
    debug: 'DEBUG',
    info: 'INFO',
    warn: 'WARN',
    error: 'ERROR',
  };

  private shouldLog(level: LogLevel): boolean {
    if (process.env.NODE_ENV === 'test') return level === 'error';
    if (process.env.NODE_ENV === 'production') return level !== 'debug';
    return true;
  }

  private formatOutput(level: LogLevel, source: string, message: string, context?: unknown, error?: Error): void {
    const color = this.COLORS[level];
    const emoji = this.EMOJIS[level];
    const prefix = this.PREFIXES[level];
    const timestamp = new Date().toISOString();
    
    // Edge runtime doesn't support console.groupCollapsed/groupEnd
    // Fallback to simple logging for compatibility
    const supportsGrouping = typeof console.groupCollapsed === 'function' && typeof console.groupEnd === 'function';
    
    if (supportsGrouping) {
      // Safe to call - we've verified both functions exist
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      (console as any).groupCollapsed(`%c${emoji} [${timestamp}] [${source.toUpperCase()}] ${prefix}: ${message}`, `color: ${color}; font-weight: bold;`);
    } else {
      // Simple format for edge runtime
      console.log(`${emoji} [${timestamp}] [${source.toUpperCase()}] ${prefix}: ${message}`);
    }
    
    console.log(`%cTimestamp:`, 'color: #666; font-weight: bold;', timestamp);
    console.log(`%cSource:`, 'color: #666; font-weight: bold;', source);
    
    if (context) {
      console.log(`%cContext:`, 'color: #666; font-weight: bold;');
      // console.dir may not be available in edge runtime
      if (typeof console.dir === 'function') {
        console.dir(context, { depth: 3, colors: true });
      } else {
        console.log(JSON.stringify(context, null, 2));
      }
    }
    
    if (error) {
      console.log(`%cError Details:`, 'color: #666; font-weight: bold;');
      console.log(`%cType:`, 'color: #ff4444; font-weight: bold;', error.name);
      console.log(`%cMessage:`, 'color: #ff4444; font-weight: bold;', error.message);
      
      if (process.env.NODE_ENV === 'development' && error.stack) {
        console.log(`%cStack Trace:`, 'color: #666; font-weight: bold;');
        console.log(error.stack);
      }
    }
    
    if (supportsGrouping) {
      // Safe to call - we've verified the function exists
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      (console as any).groupEnd();
    }
  }

  debug(message: string, context?: unknown): void {
    if (!this.shouldLog('debug')) return;
    this.formatOutput('debug', 'website', message, context);
  }

  info(message: string, context?: unknown): void {
    if (!this.shouldLog('info')) return;
    this.formatOutput('info', 'website', message, context);
  }

  warn(message: string, context?: unknown): void {
    if (!this.shouldLog('warn')) return;
    this.formatOutput('warn', 'website', message, context);
  }

  error(message: string, error?: Error, context?: unknown): void {
    if (!this.shouldLog('error')) return;
    this.formatOutput('error', 'website', message, context, error);
  }
}