/**
 * 日志工具类
 * 提供统一的日志记录功能，支持不同级别的日志输出
 */

import { LOG_CONFIG, CONFIG } from '@/common/config/app.config.js'

// 日志级别枚举
export const LOG_LEVELS = {
  ERROR: 0,
  WARN: 1,
  INFO: 2,
  DEBUG: 3
}

// 日志级别名称映射
const LEVEL_NAMES = {
  [LOG_LEVELS.ERROR]: 'ERROR',
  [LOG_LEVELS.WARN]: 'WARN',
  [LOG_LEVELS.INFO]: 'INFO',
  [LOG_LEVELS.DEBUG]: 'DEBUG'
}

// 日志级别颜色映射
const LEVEL_COLORS = {
  [LOG_LEVELS.ERROR]: '#ff4757',
  [LOG_LEVELS.WARN]: '#faad14',
  [LOG_LEVELS.INFO]: '#1890ff',
  [LOG_LEVELS.DEBUG]: '#52c41a'
}

// 当前日志级别
const CURRENT_LEVEL = LOG_LEVELS[LOG_CONFIG.CURRENT_LEVEL.toUpperCase()] || LOG_LEVELS.INFO

// 日志缓存队列
let logQueue = []
let flushTimer = null

/**
 * 日志记录器类
 */
class Logger {
  constructor(module = 'APP') {
    this.module = module
    this.startTime = Date.now()
  }

  /**
   * 记录错误日志
   * @param {string} message - 日志消息
   * @param {any} data - 附加数据
   * @param {Error} error - 错误对象
   */
  error(message, data = null, error = null) {
    this._log(LOG_LEVELS.ERROR, message, data, error)
  }

  /**
   * 记录警告日志
   * @param {string} message - 日志消息
   * @param {any} data - 附加数据
   */
  warn(message, data = null) {
    this._log(LOG_LEVELS.WARN, message, data)
  }

  /**
   * 记录信息日志
   * @param {string} message - 日志消息
   * @param {any} data - 附加数据
   */
  info(message, data = null) {
    this._log(LOG_LEVELS.INFO, message, data)
  }

  /**
   * 记录调试日志
   * @param {string} message - 日志消息
   * @param {any} data - 附加数据
   */
  debug(message, data = null) {
    this._log(LOG_LEVELS.DEBUG, message, data)
  }

  /**
   * 记录性能日志
   * @param {string} operation - 操作名称
   * @param {number} duration - 耗时（毫秒）
   * @param {any} data - 附加数据
   */
  performance(operation, duration, data = null) {
    this._log(LOG_LEVELS.INFO, `Performance: ${operation}`, {
      duration: `${duration}ms`,
      ...data
    })
  }

  /**
   * 记录API请求日志
   * @param {string} method - 请求方法
   * @param {string} url - 请求URL
   * @param {any} params - 请求参数
   * @param {number} status - 响应状态码
   * @param {number} duration - 请求耗时
   */
  api(method, url, params, status, duration) {
    const level = status >= 400 ? LOG_LEVELS.ERROR : LOG_LEVELS.INFO
    this._log(level, `API Request: ${method} ${url}`, {
      params,
      status,
      duration: `${duration}ms`
    })
  }

  /**
   * 记录用户行为日志
   * @param {string} action - 用户行为
   * @param {any} data - 行为数据
   */
  userAction(action, data = null) {
    this._log(LOG_LEVELS.INFO, `User Action: ${action}`, data)
  }

  /**
   * 记录页面访问日志
   * @param {string} page - 页面路径
   * @param {any} params - 页面参数
   */
  pageView(page, params = null) {
    this._log(LOG_LEVELS.INFO, `Page View: ${page}`, params)
  }

  /**
   * 创建子模块日志记录器
   * @param {string} subModule - 子模块名称
   * @returns {Logger} 子模块日志记录器
   */
  createChild(subModule) {
    return new Logger(`${this.module}:${subModule}`)
  }

  /**
   * 内部日志记录方法
   * @private
   */
  _log(level, message, data = null, error = null) {
    // 检查日志级别
    if (level > CURRENT_LEVEL) {
      return
    }

    const timestamp = new Date().toISOString()
    const levelName = LEVEL_NAMES[level]
    const logEntry = {
      timestamp,
      level: levelName,
      module: this.module,
      message,
      data,
      error: error ? {
        name: error.name,
        message: error.message,
        stack: error.stack
      } : null,
      userAgent: this._getUserAgent(),
      url: this._getCurrentUrl()
    }

    // 控制台输出
    if (LOG_CONFIG.OUTPUT.console) {
      this._consoleOutput(level, logEntry)
    }

    // 添加到队列
    if (LOG_CONFIG.OUTPUT.remote) {
      this._addToQueue(logEntry)
    }

    // 文件输出（小程序不支持）
    if (LOG_CONFIG.OUTPUT.file && typeof wx === 'undefined') {
      this._fileOutput(logEntry)
    }
  }

  /**
   * 控制台输出
   * @private
   */
  _consoleOutput(level, logEntry) {
    const { timestamp, level: levelName, module, message, data, error } = logEntry
    const color = LEVEL_COLORS[level]
    const prefix = `[${timestamp}] [${levelName}] [${module}]`

    if (typeof console !== 'undefined') {
      const args = [`%c${prefix} ${message}`, `color: ${color}; font-weight: bold;`]
      
      if (data) {
        args.push('\nData:', data)
      }
      
      if (error) {
        args.push('\nError:', error)
      }

      switch (level) {
        case LOG_LEVELS.ERROR:
          console.error(...args)
          break
        case LOG_LEVELS.WARN:
          console.warn(...args)
          break
        case LOG_LEVELS.INFO:
          console.info(...args)
          break
        case LOG_LEVELS.DEBUG:
          console.debug(...args)
          break
        default:
          console.log(...args)
      }
    }
  }

  /**
   * 添加到远程日志队列
   * @private
   */
  _addToQueue(logEntry) {
    logQueue.push(logEntry)

    // 达到批量大小时立即发送
    if (logQueue.length >= LOG_CONFIG.REMOTE.batchSize) {
      this._flushLogs()
    } else {
      // 设置定时发送
      this._scheduleFlush()
    }
  }

  /**
   * 调度日志发送
   * @private
   */
  _scheduleFlush() {
    if (flushTimer) {
      return
    }

    flushTimer = setTimeout(() => {
      this._flushLogs()
    }, LOG_CONFIG.REMOTE.flushInterval)
  }

  /**
   * 发送日志到远程服务器
   * @private
   */
  _flushLogs() {
    if (logQueue.length === 0) {
      return
    }

    const logs = [...logQueue]
    logQueue = []

    if (flushTimer) {
      clearTimeout(flushTimer)
      flushTimer = null
    }

    // 发送日志
    this._sendLogs(logs).catch(error => {
      console.error('Failed to send logs:', error)
      // 发送失败时重新加入队列
      logQueue.unshift(...logs)
    })
  }

  /**
   * 发送日志到服务器
   * @private
   */
  async _sendLogs(logs) {
    try {
      const response = await uni.request({
        url: LOG_CONFIG.REMOTE.url,
        method: 'POST',
        data: {
          logs,
          appInfo: this._getAppInfo()
        },
        header: {
          'Content-Type': 'application/json'
        },
        timeout: 10000
      })

      if (response.statusCode !== 200) {
        throw new Error(`HTTP ${response.statusCode}: ${response.data}`)
      }
    } catch (error) {
      throw error
    }
  }

  /**
   * 获取用户代理信息
   * @private
   */
  _getUserAgent() {
    try {
      const systemInfo = uni.getSystemInfoSync()
      return `${systemInfo.platform} ${systemInfo.system} ${systemInfo.version}`
    } catch (error) {
      return 'Unknown'
    }
  }

  /**
   * 获取当前页面URL
   * @private
   */
  _getCurrentUrl() {
    try {
      const pages = getCurrentPages()
      if (pages.length > 0) {
        const currentPage = pages[pages.length - 1]
        return currentPage.route || 'Unknown'
      }
    } catch (error) {
      // ignore
    }
    return 'Unknown'
  }

  /**
   * 获取应用信息
   * @private
   */
  _getAppInfo() {
    try {
      const systemInfo = uni.getSystemInfoSync()
      return {
        platform: systemInfo.platform,
        system: systemInfo.system,
        version: systemInfo.version,
        appVersion: CONFIG.APP_VERSION || '1.0.0',
        timestamp: Date.now()
      }
    } catch (error) {
      return {
        platform: 'Unknown',
        system: 'Unknown',
        version: 'Unknown',
        appVersion: '1.0.0',
        timestamp: Date.now()
      }
    }
  }

  /**
   * 文件输出（仅在非小程序环境下可用）
   * @private
   */
  _fileOutput(logEntry) {
    // 小程序环境下不支持文件操作
    if (typeof wx !== 'undefined' || typeof uni !== 'undefined') {
      return
    }

    // 在其他环境下可以实现文件日志
    console.log('File logging not implemented for this environment')
  }
}

// 默认日志记录器实例
const defaultLogger = new Logger('APP')

// 导出日志记录器工厂函数
export const createLogger = (module) => {
  return new Logger(module)
}

// 导出便捷方法
export const log = {
  error: (message, data, error) => defaultLogger.error(message, data, error),
  warn: (message, data) => defaultLogger.warn(message, data),
  info: (message, data) => defaultLogger.info(message, data),
  debug: (message, data) => defaultLogger.debug(message, data),
  performance: (operation, duration, data) => defaultLogger.performance(operation, duration, data),
  api: (method, url, params, status, duration) => defaultLogger.api(method, url, params, status, duration),
  userAction: (action, data) => defaultLogger.userAction(action, data),
  pageView: (page, params) => defaultLogger.pageView(page, params)
}

// 全局错误处理
if (typeof uni !== 'undefined') {
  uni.onError((error) => {
    defaultLogger.error('Global Error', null, new Error(error))
  })

  uni.onUnhandledRejection((event) => {
    defaultLogger.error('Unhandled Promise Rejection', {
      reason: event.reason
    })
  })
}

// 页面性能监控
export const performanceMonitor = {
  /**
   * 开始性能监控
   * @param {string} name - 监控名称
   * @returns {function} 结束监控的函数
   */
  start(name) {
    const startTime = Date.now()
    
    return (data = null) => {
      const duration = Date.now() - startTime
      defaultLogger.performance(name, duration, data)
      return duration
    }
  },

  /**
   * 监控异步操作
   * @param {string} name - 操作名称
   * @param {Promise} promise - 异步操作
   * @returns {Promise} 原始Promise
   */
  async monitor(name, promise) {
    const startTime = Date.now()
    
    try {
      const result = await promise
      const duration = Date.now() - startTime
      defaultLogger.performance(name, duration, { success: true })
      return result
    } catch (error) {
      const duration = Date.now() - startTime
      defaultLogger.performance(name, duration, { success: false, error: error.message })
      throw error
    }
  },

  /**
   * 监控函数执行
   * @param {string} name - 函数名称
   * @param {function} fn - 要监控的函数
   * @returns {any} 函数执行结果
   */
  measureSync(name, fn) {
    const startTime = Date.now()
    
    try {
      const result = fn()
      const duration = Date.now() - startTime
      defaultLogger.performance(name, duration, { success: true })
      return result
    } catch (error) {
      const duration = Date.now() - startTime
      defaultLogger.performance(name, duration, { success: false, error: error.message })
      throw error
    }
  }
}

// 导出默认日志记录器
export default defaultLogger