import type { Logger } from '@linktr.ee/messaging-core'
import React, { createContext, useContext, useMemo } from 'react'

/**
 * Default sink: the console calls the package makes today. Wrappers, not
 * `console.error.bind(console)`, so a later-installed spy is still observed.
 */
export const consoleLogger: Required<Logger> = {
  debug: (message, ...args) => console.log(message, ...args),
  info: (message, ...args) => console.log(message, ...args),
  warn: (message, ...args) => console.warn(message, ...args),
  error: (message, ...args) => console.error(message, ...args),
}

/**
 * Merge a partial sink over the console defaults, so a consumer can route only
 * the levels it cares about (e.g. `error`) and leave the rest on console.
 */
export const resolveLogger = (logger?: Logger): Required<Logger> => ({
  debug: logger?.debug ?? consoleLogger.debug,
  info: logger?.info ?? consoleLogger.info,
  warn: logger?.warn ?? consoleLogger.warn,
  error: logger?.error ?? consoleLogger.error,
})

const LoggerContext = createContext<Required<Logger>>(consoleLogger)

/**
 * Provides the resolved logger sink to the messaging subtree. Rendered by
 * `MessagingProvider`; usable standalone in tests or in a subtree that needs a
 * different sink.
 */
export const MessagingLoggerProvider: React.FC<{
  logger?: Logger
  children: React.ReactNode
}> = ({ logger, children }) => {
  const value = useMemo(() => resolveLogger(logger), [logger])
  return (
    <LoggerContext.Provider value={value}>{children}</LoggerContext.Provider>
  )
}

/**
 * The logger sink for the current subtree. Falls back to console when no
 * provider (or no `logger` prop) is present, so call sites never branch.
 */
export const useMessagingLogger = (): Required<Logger> =>
  useContext(LoggerContext)
