const fs = require('fs');
const path = require('path');

/**
 * 日志级别枚举
 */
const LogLevel = {
  ERROR: 0,
  WARN: 1,
  INFO: 2,
  DEBUG: 3,
  TRACE: 4
};

/**
 * 日志级别名称映射
 */
const LogLevelNames = {
  [LogLevel.ERROR]: 'ERROR',
  [LogLevel.WARN]: 'WARN',
  [LogLevel.INFO]: 'INFO',
  [LogLevel.DEBUG]: 'DEBUG',
  [LogLevel.TRACE]: 'TRACE'
};

/**
 * 日志级别颜色映射
 */
const LogLevelColors = {
  [LogLevel.ERROR]: '\x1b[31m', // 红色
  [LogLevel.WARN]: '\x1b[33m',  // 黄色
  [LogLevel.INFO]: '\x1b[36m',  // 青色
  [LogLevel.DEBUG]: '\x1b[35m', // 紫色
  [LogLevel.TRACE]: '\x1b[90m'  // 灰色
};

/**
 * 模块颜色映射 - 为不同模块设置不同颜色
 */
const ModuleColors = {
  'Server': '\x1b[32m',      // 绿色
  'API': '\x1b[32m',      // 绿色
  'Start': '\x1b[34m',       // 蓝色
  'PixivCore': '\x1b[35m', // 紫色
  'PixivAuth': '\x1b[36m',   // 青色
  'TaskManager': '\x1b[33m', // 黄色
  'ImageCache': '\x1b[92m',  // 亮绿色
  'HistoryManager': '\x1b[90m', // 灰色
  'ProxyConfig': '\x1b[95m', // 亮紫色
  'Download': '\x1b[93m',    // 亮黄色
  'Artwork': '\x1b[96m',     // 亮青色
  'Artist': '\x1b[92m',      // 亮绿色
  'Repository': '\x1b[94m',  // 亮蓝色
  'ErrorHandler': '\x1b[91m', // 亮红色
  'FileManager': '\x1b[36m', // 青色
  'ProgressManager': '\x1b[35m', // 紫色
  'DownloadRegistry': '\x1b[94m', // 亮蓝色
  'WatchlistManager': '\x1b[94m', // 亮蓝色
  'CacheConfigManager': '\x1b[94m', // 亮蓝色
  'UpdateRoute': '\x1b[93m', // 亮黄色
  'ArtistService': '\x1b[95m', // 亮紫色
  'DownloadService': '\x1b[96m', // 亮青色
  'Default': '\x1b[39m'      // 默认颜色
};

/**
 * 重置颜色
 */
const RESET_COLOR = '\x1b[0m';

/**
 * 日志级别文本映射
 */
const LogLevelTexts = {
  [LogLevel.ERROR]: 'ERROR',
  [LogLevel.WARN]: 'WARN',
  [LogLevel.INFO]: 'INFO',
  [LogLevel.DEBUG]: 'DEBUG',
  [LogLevel.TRACE]: 'TRACE'
};

class Logger {
  constructor(options = {}) {
    this.level = options.level || LogLevel.INFO;
    this.enableConsole = options.enableConsole !== false;
    this.enableFile = options.enableFile || false;
    
    // 动态设置日志目录，避免pkg静态分析问题
    this.logDir = options.logDir || this._getLogDir();
    
    this.maxFileSize = options.maxFileSize || 10 * 1024 * 1024; // 10MB
    this.maxFiles = options.maxFiles || 5;
    this.enableColors = options.enableColors !== false;
    this.module = options.module || 'App';
    
    // 延迟初始化，不在构造函数中创建目录
    this._initialized = false;
  }

  /**
   * 动态获取日志目录路径
   */
  _getLogDir() {
    // 检测是否在pkg打包环境中运行
    const isPkg = process.pkg !== undefined;
    
    if (isPkg) {
      // 在打包环境中，使用可执行文件所在目录
      return path.join(process.cwd(), 'logs');
    } else {
      // 在开发环境中，使用项目根目录的logs文件夹
      // 使用相对路径避免pkg静态分析问题
      return 'logs';
    }
  }

  /**
   * 确保日志目录存在
   */
  ensureLogDir() {
    if (!fs.existsSync(this.logDir)) {
      fs.mkdirSync(this.logDir, { recursive: true });
    }
  }

  /**
   * 获取当前时间字符串
   */
  getTimeString() {
    const now = new Date();
    return now.toLocaleTimeString('zh-CN', {
      hour12: false,
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
    });
  }

  /**
   * 获取日期字符串
   */
  getDateString() {
    const now = new Date();
    return now.toISOString().split('T')[0];
  }

  /**
   * 格式化日志消息
   */
  formatMessage(level, message, data = null) {
    const timeStr = this.getTimeString();
    const levelName = LogLevelTexts[level];
    
    let formattedMessage = `[${timeStr}] [${levelName}] [${this.module}] ${message}`;
    
    if (data !== null && data !== undefined) {
      if (data instanceof Error) {
        // 特殊处理 Error 对象
        formattedMessage += `\n  Error: ${data.message}`;
        if (data.stack) {
          formattedMessage += `\n  Stack: ${data.stack}`;
        }
        // 如果有其他可枚举属性，也包含进来
        const errorProps = Object.getOwnPropertyNames(data).filter(prop => 
          prop !== 'message' && prop !== 'stack' && prop !== 'name'
        );
        if (errorProps.length > 0) {
          const additionalProps = {};
          errorProps.forEach(prop => {
            additionalProps[prop] = data[prop];
          });
          formattedMessage += `\n  Additional: ${JSON.stringify(additionalProps, null, 2)}`;
        }
      } else if (typeof data === 'object') {
        formattedMessage += ` ${JSON.stringify(data, null, 2)}`;
      } else {
        formattedMessage += ` ${data}`;
      }
    }
    
    return formattedMessage;
  }

  /**
   * 写入文件日志
   */
  writeToFile(message) {
    if (!this.enableFile) return;

    // 延迟初始化，只在第一次写入时创建目录
    if (!this._initialized) {
      this.ensureLogDir();
      this._initialized = true;
    }

    const dateStr = this.getDateString();
    const logFile = path.join(this.logDir, `${dateStr}.log`);
    
    try {
      // 检查文件大小
      if (fs.existsSync(logFile)) {
        const stats = fs.statSync(logFile);
        if (stats.size > this.maxFileSize) {
          this.rotateLogFile(logFile);
        }
      }
      
      fs.appendFileSync(logFile, message + '\n', 'utf8');
    } catch (error) {
      // 如果写入文件失败，至少输出到控制台
      if (this.enableConsole) {
        console.error('Failed to write to log file:', error.message);
      }
    }
  }

  /**
   * 轮转日志文件
   */
  rotateLogFile(logFile) {
    try {
      // 删除最旧的文件
      for (let i = this.maxFiles - 1; i >= 1; i--) {
        const oldFile = `${logFile}.${i}`;
        const newFile = `${logFile}.${i + 1}`;
        if (fs.existsSync(oldFile)) {
          if (i === this.maxFiles - 1) {
            fs.unlinkSync(oldFile);
          } else {
            fs.renameSync(oldFile, newFile);
          }
        }
      }
      
      // 重命名当前文件
      fs.renameSync(logFile, `${logFile}.1`);
    } catch (error) {
      // 如果轮转失败，删除当前文件
      try {
        fs.unlinkSync(logFile);
      } catch (e) {
        // 忽略删除错误
      }
    }
  }

  /**
   * 输出到控制台
   */
  writeToConsole(message, level) {
    if (!this.enableConsole) return;

    if (this.enableColors && level !== undefined) {
      const levelColor = LogLevelColors[level];
      const moduleColor = ModuleColors[this.module] || ModuleColors['Default'];
      
      // 解析消息，为模块名添加颜色
      const coloredMessage = message.replace(
        new RegExp(`\\[${this.module}\\]`, 'g'),
        `${moduleColor}[${this.module}]${RESET_COLOR}`
      );
      
      console.log(`${levelColor}${coloredMessage}${RESET_COLOR}`);
    } else {
      console.log(message);
    }
  }

  /**
   * 记录日志
   */
  log(level, message, data = null) {
    if (level > this.level) return;

    const formattedMessage = this.formatMessage(level, message, data);
    
    this.writeToConsole(formattedMessage, level);
    this.writeToFile(formattedMessage);
  }

  /**
   * 错误日志
   */
  error(message, data = null) {
    this.log(LogLevel.ERROR, message, data);
  }

  /**
   * 警告日志
   */
  warn(message, data = null) {
    this.log(LogLevel.WARN, message, data);
  }

  /**
   * 信息日志
   */
  info(message, data = null) {
    this.log(LogLevel.INFO, message, data);
  }

  /**
   * 调试日志
   */
  debug(message, data = null) {
    this.log(LogLevel.DEBUG, message, data);
  }

  /**
   * 跟踪日志
   */
  trace(message, data = null) {
    this.log(LogLevel.TRACE, message, data);
  }

  /**
   * 创建子logger
   */
  child(module) {
    return new Logger({
      level: this.level,
      enableConsole: this.enableConsole,
      enableFile: this.enableFile,
      logDir: this.logDir,
      maxFileSize: this.maxFileSize,
      maxFiles: this.maxFiles,
      enableColors: this.enableColors,
      module: module
    });
  }

  /**
   * 设置日志级别
   */
  setLevel(level) {
    this.level = level;
  }

  /**
   * 启用/禁用控制台输出
   */
  setConsoleOutput(enabled) {
    this.enableConsole = enabled;
  }

  /**
   * 启用/禁用文件输出
   */
  setFileOutput(enabled) {
    this.enableFile = enabled;
    if (enabled) {
      this.ensureLogDir();
    }
  }
}

// 创建默认logger实例
const defaultLogger = new Logger({
  level: process.env.LOG_LEVEL ? LogLevel[process.env.LOG_LEVEL.toUpperCase()] : LogLevel.INFO,
  enableConsole: true,
  enableFile: process.env.LOG_TO_FILE === 'true',
  enableColors: process.env.LOG_COLORS !== 'false'
});

module.exports = {
  Logger,
  LogLevel,
  LogLevelNames,
  defaultLogger
};