import { LogLevel, LogLevelName } from "./common"

/**
 * 错误详情接口
 */
interface ErrorDetail {
  message: string
  stack?: string
  componentInfo?: string
  additionalInfo?: Record<string, any>
  timestamp: string
  type: string
}

/**
 * 错误处理配置
 */
interface ErrorHandlerOptions {
  namespace?: string
  level?: LogLevel
  includeStack?: boolean
  includeComponentInfo?: boolean
}

/**
 * 渲染进程错误处理接口
 */
export interface IRendererErrorHandler {
  /**
   * 捕获错误
   */
  captureError(error: any, componentInfo?: string, additionalInfo?: Record<string, any>): void

  /**
   * 设置错误处理选项
   */
  setOptions(options: Partial<ErrorHandlerOptions>): void

  /**
   * 获取当前选项
   */
  getOptions(): ErrorHandlerOptions

  /**
   * 安装全局错误处理器
   */
  installGlobalHandlers(): void
}

/**
 * 默认错误处理配置
 */
const DEFAULT_OPTIONS: ErrorHandlerOptions = {
  namespace: "error",
  level: LogLevel.ERROR,
  includeStack: true,
  includeComponentInfo: true,
}

/**
 * 格式化错误信息
 */
const formatError = (error: any, options: ErrorHandlerOptions): ErrorDetail => {
  // 基本错误信息
  const errorDetail: ErrorDetail = {
    message: "",
    timestamp: new Date().toISOString(),
    type: "Unknown",
  }
  console.log(error)

  // 处理不同类型的错误
  if (error instanceof Error) {
    errorDetail.message = error.message
    errorDetail.type = error.name || error.constructor.name
    if (options.includeStack) {
      errorDetail.stack = error.stack
    }
  } else if (typeof error === "string") {
    errorDetail.message = error
    errorDetail.type = "String"
  } else if (error === null) {
    errorDetail.message = "Null error received"
    errorDetail.type = "Null"
  } else if (error === undefined) {
    errorDetail.message = "Undefined error received"
    errorDetail.type = "Undefined"
  } else if (typeof error === "object") {
    try {
      errorDetail.message = error.message || JSON.stringify(error)
      errorDetail.type = "Object"
      errorDetail.additionalInfo = { ...error }
    } catch (e) {
      errorDetail.message = "Unserializable error object"
      errorDetail.type = "Unserializable"
    }
  } else {
    try {
      errorDetail.message = String(error)
      errorDetail.type = typeof error
    } catch (e) {
      errorDetail.message = "Error converting to string"
      errorDetail.type = "Unknown"
    }
  }

  return errorDetail
}

// @ts-ignore
const preloadErrorHandler = window.preloadErrorHandler

/**
 * 创建渲染进程错误处理器
 */
export const createRendererErrorHandler = (): IRendererErrorHandler => {
  // 当前错误处理选项
  let options: ErrorHandlerOptions = { ...DEFAULT_OPTIONS }

  /**
   * 处理错误并序列化
   */
  const processError = (error: any, componentInfo?: string, additionalInfo?: Record<string, any>): ErrorDetail => {
    const errorDetail = formatError(error, options)

    // 添加组件信息
    if (options.includeComponentInfo && componentInfo) {
      errorDetail.componentInfo = componentInfo
    }

    // 添加额外信息
    if (additionalInfo) {
      errorDetail.additionalInfo = {
        ...errorDetail.additionalInfo,
        ...additionalInfo,
      }
    }

    return errorDetail
  }

  /**
   * 发送错误到preload层
   */
  const sendError = (error: any, componentInfo?: string, additionalInfo?: Record<string, any>) => {
    // 处理并序列化错误
    const errorDetail = processError(error, componentInfo, additionalInfo)

    // 调用window.errorHandler.captureError发送错误
    // 这里假设preload层已经暴露了errorHandler对象
    if (preloadErrorHandler && typeof preloadErrorHandler.captureError === "function") {
      preloadErrorHandler.captureError(errorDetail)
    } else {
      // 如果errorHandler不可用,则降级到控制台输出
      console.error("[ErrorHandler]", errorDetail)
    }
  }

  /**
   * 安装全局错误处理器
   */
  const installGlobalHandlers = () => {
    // 捕获未处理的异常
    window.addEventListener("error", event => {
      event.preventDefault()
      sendError(event.error || event.message, "window.onerror", {
        filename: event.filename,
        lineno: event.lineno,
        colno: event.colno,
      })
      return true
    })

    // 捕获未处理的Promise拒绝
    window.addEventListener("unhandledrejection", event => {
      event.preventDefault()
      sendError(event.reason, "unhandledrejection", {
        promise: "[Promise]", // 不能直接序列化Promise对象
      })
      return true
    })

    // 捕获资源加载错误
    document.addEventListener(
      "error",
      event => {
        // 只处理资源加载错误
        if (event.target && (event.target as HTMLElement).tagName) {
          const target = event.target as HTMLElement
          sendError(`Resource load failed: ${(target as any).src || (target as any).href}`, "resource.error", {
            tagName: target.tagName,
            src: (target as any).src,
            href: (target as any).href,
          })
        }
      },
      true,
    ) // 使用捕获阶段

    console.info("[ErrorHandler] Global error handlers installed")
  }

  return {
    captureError: sendError,
    setOptions: (newOptions: Partial<ErrorHandlerOptions>) => {
      options = { ...options, ...newOptions }
      // 同步选项到preload层
      if (preloadErrorHandler && typeof preloadErrorHandler.setOptions === "function") {
        preloadErrorHandler.setOptions(options)
      }
    },
    getOptions: () => ({ ...options }),
    installGlobalHandlers,
  }
}

// 导出类型定义,方便在渲染进程中使用
export type { ErrorDetail, ErrorHandlerOptions }

// 创建渲染进程错误处理器
const errorHandler = createRendererErrorHandler()

// 安装全局错误处理器
errorHandler.installGlobalHandlers()

window.errorHandler = errorHandler

/**
 * 使用示例:
 *
 * // 捕获特定错误
 * try {
 *   // 可能出错的代码
 * } catch (error) {
 *   errorHandler.captureError(error, 'ComponentName', { additionalInfo: 'value' })
 * }
 *
 * // 设置错误处理选项
 * errorHandler.setOptions({
 *   namespace: 'custom-error',
 *   includeComponentInfo: true
 * })
 */