import { useState, type FormEvent } from 'react'
import { ExternalLink, RefreshCw, Terminal, X } from 'lucide-react'
import type { Agent, FeedEntry, GpuStatus, NodeDetail, TerminalLine, TopologyNode, WorkloadData } from '../../types'
import { AGENT_NODE } from '../../lib/constants'
import { getAgentMeta } from '../../lib/agentMeta'
import { copyShellCommand, resolveInfraNode } from '../../lib/infraCatalog'
import { Button } from '../ui/Button'
import { Card, CardDescription, CardTitle } from '../ui/Card'
import { Input } from '../ui/Input'
import { cn } from '../../lib/utils'

type Tab = 'overview' | 'apps' | 'terminal'

type Props = {
  node: TopologyNode | null
  nodeDetail: NodeDetail | null
  agent: Agent | null
  agents: Agent[]
  workload: WorkloadData | null
  gpu: GpuStatus | null
  feed: FeedEntry[]
  lines: TerminalLine[]
  busy: boolean
  onProbe: () => void
  onAsk: (message: string) => void
  onSelectAgent: (id: string) => void
  onSendPrompt: (message: string, agentId?: string) => void
  onClear: () => void
  onOpenTerminal: (nodeId: string) => void
  onProbeNodeId: (nodeId: string) => void
}

export function InspectorPanel({
  node,
  nodeDetail,
  agent,
  agents,
  workload,
  gpu,
  feed,
  lines,
  busy,
  onProbe,
  onAsk,
  onSelectAgent,
  onSendPrompt,
  onClear,
  onOpenTerminal,
  onProbeNodeId,
}: Props) {
  const [tab, setTab] = useState<Tab>('overview')
  const [input, setInput] = useState('')
  const [shellCopied, setShellCopied] = useState(false)
  const d = nodeDetail || node
  const infra = resolveInfraNode(d?.id || null)
  const linkedAgent = d
    ? agents.find((a) => a.id === d.id || AGENT_NODE[a.id] === d.id || a.id === infra?.agentId || a.zone === d.id)
    : agent

  const submit = (e: FormEvent) => {
    e.preventDefault()
    if (!input.trim() || busy) return
    onAsk(input.trim())
    setInput('')
    setTab('terminal')
    if (d?.id) onOpenTerminal(d.id)
  }

  const runShell = async () => {
    if (!infra) return
    await copyShellCommand(infra.ssh)
    setShellCopied(true)
    setTimeout(() => setShellCopied(false), 2000)
    onOpenTerminal(infra.id)
    onProbeNodeId(infra.id)
    setTab('terminal')
  }

  return (
    <aside className="flex min-h-0 flex-1 flex-col bg-surface-raised">
      <header className="flex items-start justify-between gap-2 border-b border-border p-3">
        <div className="min-w-0">
          <p className="text-[9px] font-semibold uppercase tracking-widest text-docker">Inspector</p>
          <h2 className="truncate text-sm font-semibold text-foreground">
            {d ? d.label : agent ? agent.name.split(' ·')[0] : 'Lab overview'}
          </h2>
        </div>
        {(d || agent) && (
          <Button variant="ghost" size="icon" onClick={onClear} aria-label="Clear">
            <X className="h-4 w-4" />
          </Button>
        )}
      </header>

      {!d && !agent && (
        <div className="scrollbar-thin flex-1 space-y-3 overflow-y-auto p-3">
          <div className="rounded-lg border border-docker/25 bg-docker-light/50 p-2.5 dark:bg-blue-500/10">
            <p className="mb-1.5 text-[10px] font-semibold text-foreground">Quick start</p>
            <ol className="list-decimal space-y-1 pl-4 text-[10px] leading-relaxed text-foreground-muted">
              <li>Select an <strong className="text-foreground">infrastructure card</strong> or topology node</li>
              <li>Click <strong className="text-foreground">Shell</strong> for SSH + live terminal output</li>
              <li>Click <strong className="text-foreground">UI</strong> to open Airflow, Trino, Kafka UI, etc.</li>
              <li>Ask questions via <strong className="text-foreground">Chat</strong> below — agents see the full cluster</li>
            </ol>
          </div>
          <div>
            <p className="mb-1.5 text-[9px] uppercase tracking-wider text-foreground-faint">Agents & domains</p>
            <div className="space-y-1">
              {agents.filter((a) => !a.supervisor).map((a) => {
                const meta = getAgentMeta(a.id)
                return (
                  <button
                    key={a.id}
                    type="button"
                    onClick={() => onSelectAgent(a.id)}
                    className="flex w-full items-start gap-2 rounded border border-border bg-surface-overlay/60 px-2 py-1.5 text-left hover:border-border-strong"
                  >
                    <span className="mt-0.5 text-[9px] font-semibold" style={{ color: meta.accent }}>{a.name.split(' ·')[0]}</span>
                    <span className="min-w-0 flex-1 text-[9px] text-foreground-muted">{a.role}</span>
                  </button>
                )
              })}
            </div>
          </div>
          {workload && (
            <div className="grid grid-cols-2 gap-1.5">
              <Stat label="VMs" value={String(workload.totals.vms ?? '—')} />
              <Stat label="Containers" value={`${workload.totals.apps_running}/${workload.totals.apps_total}`} />
              <Stat label="Connectors" value={String(workload.totals.connectors)} />
              <Stat label="Pipeline" value={workload.totals.pipeline_active ? 'active' : 'degraded'} ok={workload.totals.pipeline_active} />
            </div>
          )}
          {gpu?.ok && (
            <Card padding className="!p-2">
              <CardTitle>GPU · {gpu.host}</CardTitle>
              <CardDescription>{gpu.active_model || 'No model'}</CardDescription>
            </Card>
          )}
        </div>
      )}

      {agent && !d && (
        <div className="scrollbar-thin flex-1 overflow-y-auto p-3">
          {(() => {
            const meta = getAgentMeta(agent.id)
            const Icon = meta.icon
            return (
              <>
                <div className="mb-3 flex items-center gap-2 rounded-lg border border-border bg-surface-overlay p-2">
                  <span className="flex h-10 w-10 items-center justify-center rounded-lg bg-surface" style={{ color: meta.accent }}>
                    <Icon className="h-5 w-5" />
                  </span>
                  <div>
                    <p className="text-sm font-semibold text-foreground">{agent.name}</p>
                    <p className="text-[10px] text-foreground-muted">{meta.domain} · {agent.zone}</p>
                  </div>
                </div>
                <p className="mb-2 text-[10px] italic text-foreground-muted">"{agent.motto || agent.role}"</p>
                <div className="mb-2 flex flex-wrap gap-1">
                  {(agent.suggested_prompts || []).slice(0, 4).map((prompt) => (
                    <button
                      key={prompt}
                      type="button"
                      onClick={() => onSendPrompt(prompt, agent.id)}
                      className="rounded border border-border px-1.5 py-0.5 text-[9px] text-foreground-muted hover:border-docker/40 hover:text-docker"
                    >
                      {prompt}
                    </button>
                  ))}
                </div>
                <button
                  type="button"
                  onClick={() => onOpenTerminal(agent.id)}
                  className="mb-2 inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[9px] hover:border-docker/40"
                >
                  <Terminal className="h-3 w-3" /> Agent terminal
                </button>
              </>
            )
          })()}
        </div>
      )}

      {d && (
        <>
          {linkedAgent && (
            <div className="flex items-center gap-2 border-b border-border bg-surface-overlay/50 px-3 py-1.5">
              <span className="text-[8px] uppercase tracking-wider text-foreground-faint">Agent</span>
              <button type="button" onClick={() => onSelectAgent(linkedAgent.id)} className="truncate text-[10px] font-medium text-docker hover:underline">
                {linkedAgent.name.split(' ·')[0]}
              </button>
            </div>
          )}
          <div className="flex flex-wrap items-center gap-1 border-b border-border px-3 py-1.5 font-mono text-[9px] text-foreground-muted">
            <span className={cn('h-1.5 w-1.5 rounded-full', d.level === 'ok' ? 'bg-success' : 'bg-warning')} />
            {d.vm} · {d.ip}
            <span className="ml-auto">{d.running}/{d.total}</span>
          </div>

          <div className="flex flex-wrap gap-1 border-b border-border p-2">
            {infra && (
              <Button size="sm" variant="outline" onClick={runShell} disabled={busy}>
                <Terminal className="h-3 w-3" />
                {shellCopied ? 'SSH copied' : 'Shell'}
              </Button>
            )}
            <Button size="sm" variant="outline" onClick={onProbe} disabled={busy}>
              <RefreshCw className={cn('h-3 w-3', busy && 'animate-spin')} /> Probe
            </Button>
            {(infra?.apps || []).slice(0, 3).map((app) => (
              <a
                key={app.url}
                href={app.url}
                target="_blank"
                rel="noreferrer"
                className="inline-flex items-center gap-1 rounded-md border border-docker/30 bg-docker-light/30 px-2 py-1 text-[9px] text-docker hover:underline dark:bg-blue-500/10"
              >
                <ExternalLink className="h-3 w-3" /> {app.label}
              </a>
            ))}
            {(d.links || []).map((l) => (
              <a key={l.url} href={l.url} target="_blank" rel="noreferrer" className="inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-[9px] hover:bg-surface-overlay">
                <ExternalLink className="h-3 w-3" /> {l.label}
              </a>
            ))}
          </div>

          <nav className="flex gap-1 border-b border-border px-2 py-1">
            {(['overview', 'apps', 'terminal'] as Tab[]).map((t) => (
              <button key={t} type="button" onClick={() => setTab(t)} className={cn('rounded px-2 py-0.5 text-[10px] capitalize', tab === t ? 'bg-docker-light text-docker' : 'text-foreground-muted')}>
                {t}
              </button>
            ))}
          </nav>
          <div className="scrollbar-thin min-h-0 flex-1 overflow-y-auto p-3 text-[10px]">
            {tab === 'overview' && (
              <div className="space-y-2">
                {(d.description || infra?.description) && <p className="text-foreground-muted">{d.description || infra?.description}</p>}
                {infra && <p className="font-mono text-[9px] text-foreground-faint">{infra.ssh}</p>}
                {(d.endpoints || []).map((ep) => (
                  <p key={ep.name} className="font-mono text-foreground-muted">{ep.name}: {ep.host}:{ep.port}</p>
                ))}
                {(d.commands || []).map((cmd) => (
                  <button
                    key={cmd}
                    type="button"
                    onClick={() => { setInput(cmd); setTab('terminal') }}
                    className="block w-full rounded border border-border px-2 py-1 text-left font-mono text-[9px] hover:bg-surface-overlay"
                  >
                    $ {cmd}
                  </button>
                ))}
              </div>
            )}
            {tab === 'apps' && (
              <div className="space-y-1">
                {(d.apps || []).map((app) => (
                  <div key={app.name} className="rounded border border-border bg-surface px-2 py-1">
                    <p className="font-medium text-foreground">{app.name}</p>
                    <p className="font-mono text-[9px] text-foreground-faint">{app.state} · {app.image}</p>
                  </div>
                ))}
              </div>
            )}
            {tab === 'terminal' && (
              <div className="rounded border border-border bg-black/40 p-2 font-mono text-[9px]">
                {lines.map((line) => (
                  <div key={line.id} className="text-foreground-muted">
                    <span className="text-foreground-faint">{line.ts ? new Date(line.ts).toLocaleTimeString('en-US', { hour12: false }) : ''}</span>{' '}
                    <span className="text-docker">{line.phase}</span> {line.text}
                  </div>
                ))}
                {busy && <span className="text-docker animate-pulse">█</span>}
              </div>
            )}
          </div>
          <form onSubmit={submit} className="flex gap-1 border-t border-border p-2">
            <Input value={input} onChange={(e) => setInput(e.target.value)} placeholder={`Ask about ${d.label}…`} disabled={busy} className="text-xs" />
            <Button type="submit" size="sm" disabled={busy || !input.trim()}>Send</Button>
          </form>
        </>
      )}
    </aside>
  )
}

function Stat({ label, value, ok }: { label: string; value: string; ok?: boolean }) {
  return (
    <div className="rounded border border-border bg-surface-overlay px-2 py-1.5">
      <p className="text-[8px] uppercase text-foreground-faint">{label}</p>
      <p className={cn('font-mono text-[11px] font-medium', ok === false ? 'text-warning' : ok ? 'text-success' : 'text-foreground')}>{value}</p>
    </div>
  )
}
