import { defineStore } from 'pinia'
import { ref } from 'vue'

export type LogLevel = 'log' | 'info' | 'warn' | 'error'

export interface LogEntry {
  id: string
  timestamp: string
  level: LogLevel
  message: string
}

const MAX_ENTRIES = 500

function serialize(args: unknown[]): string {
  return args
    .map((a) => {
      if (typeof a === 'string') return a
      try {
        return JSON.stringify(a, null, 2)
      } catch {
        return String(a)
      }
    })
    .join(' ')
}

export const useLogsStore = defineStore('logs', () => {
  const entries = ref<LogEntry[]>([])
  let installed = false

  function addEntry(level: LogLevel, message: string) {
    entries.value.unshift({
      id: self.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2) + Date.now().toString(36),
      timestamp: new Date().toISOString(),
      level,
      message,
    })
    if (entries.value.length > MAX_ENTRIES) {
      entries.value = entries.value.slice(0, MAX_ENTRIES)
    }
  }

  function install() {
    if (installed) return
    installed = true

    const origLog = console.log.bind(console)
    const origInfo = console.info.bind(console)
    const origWarn = console.warn.bind(console)
    const origError = console.error.bind(console)

    console.log = (...args: unknown[]) => {
      origLog(...args)
      addEntry('log', serialize(args))
    }
    console.info = (...args: unknown[]) => {
      origInfo(...args)
      addEntry('info', serialize(args))
    }
    console.warn = (...args: unknown[]) => {
      origWarn(...args)
      addEntry('warn', serialize(args))
    }
    console.error = (...args: unknown[]) => {
      origError(...args)
      addEntry('error', serialize(args))
    }
  }

  function clear() {
    entries.value = []
  }

  return { entries, install, clear }
})