import { useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/solid"
import { createSignal } from "solid-js"
import { TextAttributes } from "@opentui/core"
import * as Clipboard from "@tui/util/clipboard"
import { InstallationVersion } from "@saeeol/core/installation/version"
import { win32FlushInputBuffer } from "@tui/win32"
import { resetTerminalState } from "@/saeeol/cli/cmd/tui/util/terminal"

function tryUseRenderer() {
  try {
    return useRenderer()
  } catch {
    return undefined
  }
}

function tryUseTerminalDimensions() {
  try {
    return useTerminalDimensions()
  } catch {
    return undefined
  }
}

export function ErrorComponent(props: {
  error: Error
  reset: () => void
  onBeforeExit?: () => Promise<void>
  onExit: () => Promise<void>
  mode?: "dark" | "light"
}) {
  const term = tryUseTerminalDimensions()
  const renderer = tryUseRenderer()
  const height = () => term?.().height ?? process.stdout.rows ?? 24
  const handleExit = async () => {
    await props.onBeforeExit?.()
    renderer?.setTerminalTitle("")
    renderer?.destroy()
    win32FlushInputBuffer()
    resetTerminalState()
    await props.onExit()
  }
  try {
    useKeyboard((evt) => {
      if (evt.ctrl && evt.name === "c") {
        handleExit()
      }
    })
  } catch {
    // Keyboard handler unavailable — renderer context may be missing.
  }
  const [copied, setCopied] = createSignal(false)
  const issueURL = new URL("https://github.com/Saeeol-Org/saeeol/issues/new?template=bug-report.yml")
  const isLight = props.mode === "light"
  const colors = {
    bg: isLight ? "#ffffff" : "#0a0a0a",
    text: isLight ? "#1a1a1a" : "#eeeeee",
    muted: isLight ? "#8a8a8a" : "#808080",
    primary: isLight ? "#3b7dd8" : "#fab283",
  }
  if (props.error.message) {
    issueURL.searchParams.set("title", `opentui: fatal: ${props.error.message}`)
  }
  if (props.error.stack) {
    issueURL.searchParams.set(
      "description",
      "```\n" + props.error.stack.substring(0, 6000 - issueURL.toString().length) + "...\n```",
    )
  }
  issueURL.searchParams.set("saeeol-version", InstallationVersion)
  const copyIssueURL = () => {
    Clipboard.copy(issueURL.toString()).then(() => {
      setCopied(true)
    })
  }
  return (
    <box flexDirection="column" gap={1} backgroundColor={colors.bg}>
      <box flexDirection="row" gap={1} alignItems="center">
        <text attributes={TextAttributes.BOLD} fg={colors.text}>
          Please report an issue.
        </text>
        <box onMouseUp={copyIssueURL} backgroundColor={colors.primary} padding={1}>
          <text attributes={TextAttributes.BOLD} fg={colors.bg}>
            Copy issue URL (exception info pre-filled)
          </text>
        </box>
        {copied() && <text fg={colors.muted}>Successfully copied</text>}
      </box>
      <box flexDirection="row" gap={2} alignItems="center">
        <text fg={colors.text}>A fatal error occurred!</text>
        <box onMouseUp={props.reset} backgroundColor={colors.primary} padding={1}>
          <text fg={colors.bg}>Reset TUI</text>
        </box>
        <box onMouseUp={handleExit} backgroundColor={colors.primary} padding={1}>
          <text fg={colors.bg}>Exit</text>
        </box>
      </box>
      <scrollbox height={Math.floor(height() * 0.7)}>
        <text fg={colors.muted}>{props.error.stack}</text>
      </scrollbox>
      <text fg={colors.text}>{props.error.message}</text>
    </box>
  )
}
