const DEBUG_KEY = "editor:debug"

type LogLevel = "debug" | "info" | "warn" | "error"

const LEVEL_RANK: Record<LogLevel, number> = {
  debug: 0,
  info: 1,
  warn: 2,
  error: 3,
}

interface DebugConfig {
  namespaces: Set<string> | "*"
  minLevel: LogLevel
}

const config: DebugConfig = loadConfig()

function loadConfig(): DebugConfig {
  try {
    const stored = localStorage.getItem(DEBUG_KEY)
    if (stored === "*") return { namespaces: "*", minLevel: "debug" }
    if (stored) {
      return {
        namespaces: new Set(stored.split(",").map((s) => s.trim())),
        minLevel: "debug",
      }
    }
  } catch {
    // localStorage unavailable (SSR, tests)
  }
  return { namespaces: "*", minLevel: "info" }
}

export function configureDebug(
  opts: Partial<{ namespaces: string; minLevel: LogLevel }>,
) {
  if (opts.namespaces !== undefined) {
    config.namespaces =
      opts.namespaces === "*"
        ? "*"
        : new Set(opts.namespaces.split(",").map((s) => s.trim()))
  }
  if (opts.minLevel !== undefined) {
    config.minLevel = opts.minLevel
  }
}

function parseFilter(filter: string): Set<string> | "*" {
  if (filter === "*") return "*"
  return new Set(filter.split(",").map((s) => s.trim()))
}

export function createLogger(namespace: string, componentFilter?: string) {
  const filter =
    componentFilter !== undefined ? parseFilter(componentFilter) : null

  const shouldLog = (level: LogLevel): boolean => {
    if (LEVEL_RANK[level] < LEVEL_RANK[config.minLevel]) return false

    // Component-level filter takes priority
    if (filter !== null) {
      if (filter === "*") return true
      return filter.has(namespace)
    }

    // Fall back to global config
    if (config.namespaces === "*") return true
    return config.namespaces.has(namespace) || config.namespaces.has("*")
  }

  return {
    debug: (...args: unknown[]) => {
      if (shouldLog("debug")) console.debug(`[${namespace}]`, ...args)
    },
    info: (...args: unknown[]) => {
      if (shouldLog("info")) console.info(`[${namespace}]`, ...args)
    },
    warn: (...args: unknown[]) => {
      if (shouldLog("warn")) console.warn(`[${namespace}]`, ...args)
    },
    error: (...args: unknown[]) => {
      if (shouldLog("error")) console.error(`[${namespace}]`, ...args)
    },
  }
}
