import analytics from './index'
import { ERROR_EVENTS } from '../../constants/events'

/**
 * 错误追踪器
 */
class ErrorTracker {
  constructor() {
    this.initialized = false
  }

  /**
   * 初始化错误监控
   */
  init() {
    if (this.initialized) return
    this.initialized = true

    // 监听小程序全局错误
    this._setupGlobalErrorHandler()

    console.log('[ErrorTracker] Initialized')
  }

  /**
   * 设置全局错误处理
   */
  _setupGlobalErrorHandler() {
    // 监听小程序错误
    uni.onError((error) => {
      this.trackJSError({
        message: error,
        source: 'uni.onError',
      })
    })

    // 监听未处理的Promise错误
    uni.onUnhandledRejection?.((res) => {
      this.trackJSError({
        message: res.reason?.message || String(res.reason),
        stack: res.reason?.stack,
        source: 'unhandledRejection',
      })
    })
  }

  /**
   * 追踪API错误
   * @param {object} error - 错误信息
   */
  trackApiError(error) {
    const {
      path,
      method = 'GET',
      statusCode,
      message,
      duration,
      params,
    } = error

    analytics.track(ERROR_EVENTS.API_ERROR, {
      api_path: path,
      api_method: method,
      error_code: statusCode,
      error_message: message,
      request_duration: duration,
      // 脱敏后的参数
      request_params: this._sanitizeParams(params),
    })
  }

  /**
   * 追踪JS错误
   * @param {object} error - 错误信息
   */
  trackJSError(error) {
    const {
      message,
      stack,
      file,
      line,
      column,
      source = 'unknown',
    } = error

    analytics.track(ERROR_EVENTS.JS_ERROR, {
      error_message: this._truncate(message, 500),
      error_stack: this._truncate(stack, 1000),
      error_file: file,
      error_line: line,
      error_column: column,
      error_source: source,
      page_path: this._getCurrentPagePath(),
    })
  }

  /**
   * 追踪页面错误
   * @param {object} error - 错误信息
   */
  trackPageError(error) {
    const {
      type,
      message,
      pagePath,
    } = error

    analytics.track(ERROR_EVENTS.PAGE_ERROR, {
      error_type: type,
      error_message: message,
      page_path: pagePath || this._getCurrentPagePath(),
    })
  }

  /**
   * 追踪网络错误
   * @param {object} error - 错误信息
   */
  trackNetworkError(error) {
    const {
      type = 'unknown',
      message,
      url,
    } = error

    analytics.track(ERROR_EVENTS.NETWORK_ERROR, {
      error_type: type,
      error_message: message,
      request_url: this._sanitizeUrl(url),
      network_type: this._getNetworkType(),
    })
  }

  /**
   * 追踪资源加载失败
   * @param {object} error - 错误信息
   */
  trackResourceError(error) {
    const {
      resourceType,
      resourceUrl,
      message,
    } = error

    analytics.track(ERROR_EVENTS.RESOURCE_LOAD_FAILED, {
      resource_type: resourceType,
      resource_url: this._sanitizeUrl(resourceUrl),
      error_message: message,
      page_path: this._getCurrentPagePath(),
    })
  }

  /**
   * 获取当前页面路径
   */
  _getCurrentPagePath() {
    try {
      const pages = getCurrentPages()
      if (pages.length > 0) {
        return '/' + pages[pages.length - 1].route
      }
    } catch (e) {
      // ignore
    }
    return 'unknown'
  }

  /**
   * 获取网络类型
   */
  _getNetworkType() {
    try {
      const res = uni.getNetworkType()
      return res?.networkType || 'unknown'
    } catch (e) {
      return 'unknown'
    }
  }

  /**
   * 参数脱敏
   */
  _sanitizeParams(params) {
    if (!params) return {}

    const sensitiveKeys = ['password', 'token', 'secret', 'key', 'auth']
    const sanitized = { ...params }

    for (const key of Object.keys(sanitized)) {
      if (sensitiveKeys.some((k) => key.toLowerCase().includes(k))) {
        sanitized[key] = '***'
      }
    }

    return sanitized
  }

  /**
   * URL脱敏
   */
  _sanitizeUrl(url) {
    if (!url) return ''
    // 移除查询参数中的敏感信息
    try {
      const urlObj = new URL(url)
      const sensitiveParams = ['token', 'key', 'secret', 'password']
      sensitiveParams.forEach((param) => {
        if (urlObj.searchParams.has(param)) {
          urlObj.searchParams.set(param, '***')
        }
      })
      return urlObj.toString()
    } catch (e) {
      return url
    }
  }

  /**
   * 截断字符串
   */
  _truncate(str, maxLength) {
    if (!str) return ''
    if (str.length <= maxLength) return str
    return str.substring(0, maxLength) + '...'
  }
}

// 导出单例
export default new ErrorTracker()