import { useEffect, useState } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import type { HoloLakeUiPlugin, UiPluginNode } from '@/lib/uiPluginSystem'
import { applyUiPluginTokens, validateUiPlugin } from '@/lib/uiPluginSystem'

export type LanguageShellViewState = {
  status: string
  confirmationQuestion: string | null
  receipt: string | null
  evidence?: string | null
}

export type LanguageShellBridge = {
  submitGoal(goal: string): void
  answerConfirmation(approved: boolean): void
}

type Props = {
  plugin: HoloLakeUiPlugin
  state: LanguageShellViewState
  bridge: LanguageShellBridge
}

export function HotPluggableLanguageShell({ plugin, state, bridge }: Props) {
  const validation = validateUiPlugin(plugin)
  const [goal, setGoal] = useState('')
  const [evidenceOpen, setEvidenceOpen] = useState(false)

  useEffect(() => {
    if (!validation.ok) return
    const root = document.documentElement.style
    const names = applyUiPluginTokens(plugin, root)
    return () => names.forEach((name) => root.removeProperty(name))
  }, [plugin, validation.ok])

  if (!validation.ok) throw new Error(`UI_PLUGIN_REJECTED:${validation.errors.join(',')}`)

  const renderNode = (node: UiPluginNode, path: string): React.ReactNode => {
    const children = node.children?.map((child, index) => renderNode(child, `${path}.${index}`))
    switch (node.kind) {
      case 'shell': return <main key={path} data-ui-plugin={plugin.manifest.id}>{children}</main>
      case 'stack': return <section key={path} className="flex flex-col gap-4">{children}</section>
      case 'row': return <div key={path} className="flex items-center gap-3">{children}</div>
      case 'text': return <p key={path}>{node.text}</p>
      case 'language_input': return (
        <form key={path} className="flex gap-3" onSubmit={(event) => { event.preventDefault(); bridge.submitGoal(goal) }}>
          <Input value={goal} onChange={(event) => setGoal(event.target.value)} aria-label="language goal" />
          <Button type="submit">{node.text}</Button>
        </form>
      )
      case 'task_status': return <p key={path} role="status">{state.status}</p>
      case 'reality_boundary_confirmation': return state.confirmationQuestion ? (
        <section key={path} aria-label="reality boundary confirmation">
          <p>{state.confirmationQuestion}</p>
          <div className="flex gap-3">
            <Button onClick={() => bridge.answerConfirmation(true)}>{node.approveText}</Button>
            <Button variant="outline" onClick={() => bridge.answerConfirmation(false)}>{node.declineText}</Button>
          </div>
        </section>
      ) : <span key={path} hidden />
      case 'human_receipt': return state.receipt ? <p key={path}>{state.receipt}</p> : <span key={path} hidden />
      case 'evidence_toggle': return (
        <section key={path}>
          <Button variant="ghost" onClick={() => setEvidenceOpen((open) => !open)}>{node.text}</Button>
          {evidenceOpen && state.evidence ? <pre>{state.evidence}</pre> : null}
        </section>
      )
      case 'button': return <Button key={path}>{node.text}</Button>
    }
  }

  return renderNode(plugin.layout, 'root')
}
