import { useEffect, useRef, useState } from 'react'
import { Terminal as XTerm } from '@xterm/xterm'
import { FitAddon } from '@xterm/addon-fit'
import '@xterm/xterm/css/xterm.css'
import { api, getToken, type Integration } from '../lib/api'

const GOLD = '#C8A434'
const TEXT_SECONDARY = '#7A7D85'

export default function Terminal() {
  const [hosts, setHosts] = useState<Integration[]>([])
  const [activeHostId, setActiveHostId] = useState<number | null>(null)
  const [connected, setConnected] = useState(false)
  const containerRef = useRef<HTMLDivElement>(null)
  const termRef = useRef<XTerm | null>(null)
  const fitRef = useRef<FitAddon | null>(null)
  const wsRef = useRef<WebSocket | null>(null)

  useEffect(() => {
    api.listIntegrations().then(({ integrations }) => {
      setHosts(integrations.filter((i) => i.type === 'ssh'))
    })
  }, [])

  useEffect(() => {
    if (!containerRef.current) return
    const term = new XTerm({
      cursorBlink: true,
      fontSize: 13,
      fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
      theme: { background: '#15161A', foreground: '#E8E6E0', cursor: GOLD },
    })
    const fit = new FitAddon()
    term.loadAddon(fit)
    term.open(containerRef.current)
    fit.fit()
    termRef.current = term
    fitRef.current = fit

    const onResize = () => fit.fit()
    window.addEventListener('resize', onResize)
    return () => {
      window.removeEventListener('resize', onResize)
      term.dispose()
      wsRef.current?.close()
    }
  }, [])

  function connect(hostId: number) {
    wsRef.current?.close()
    setActiveHostId(hostId)
    setConnected(false)
    const term = termRef.current
    if (!term) return
    term.reset()
    term.writeln('Connecting…')

    const token = getToken()
    const proto = window.location.protocol === 'https:' ? 'wss' : 'ws'
    const ws = new WebSocket(`${proto}://${window.location.host}/api/terminal?token=${encodeURIComponent(token ?? '')}`)
    wsRef.current = ws

    ws.onopen = () => {
      ws.send(JSON.stringify({ type: 'connect', integrationId: hostId, cols: term.cols, rows: term.rows }))
    }
    ws.onmessage = (event) => {
      const msg = JSON.parse(event.data)
      if (msg.type === 'connected') {
        setConnected(true)
        term.reset()
      } else if (msg.type === 'data') {
        term.write(msg.data)
      } else if (msg.type === 'error') {
        term.writeln(`\r\n\x1b[31mError: ${msg.message}\x1b[0m`)
        setConnected(false)
      } else if (msg.type === 'closed') {
        term.writeln('\r\n\x1b[33mConnection closed.\x1b[0m')
        setConnected(false)
      }
    }
    ws.onclose = () => setConnected(false)

    term.onData((data) => {
      if (ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify({ type: 'input', data }))
    })
    term.onResize(({ cols, rows }) => {
      if (ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify({ type: 'resize', cols, rows }))
    })
  }

  return (
    <div className="flex h-full gap-4">
      <div className="w-56 shrink-0 overflow-y-auto rounded-lg border border-white/10 bg-white/5 p-3">
        <p className="mb-2 text-xs font-medium uppercase tracking-wide" style={{ color: TEXT_SECONDARY }}>
          SSH Hosts
        </p>
        {hosts.length === 0 && (
          <p className="text-xs" style={{ color: TEXT_SECONDARY }}>
            No SSH integrations configured. Add one in Settings → Integrations.
          </p>
        )}
        <div className="flex flex-col gap-1">
          {hosts.map((h) => (
            <button
              key={h.id}
              onClick={() => connect(h.id)}
              className="rounded-md px-2 py-1.5 text-left text-sm transition-colors"
              style={{
                background: activeHostId === h.id ? 'rgba(200,164,52,0.15)' : 'transparent',
                color: activeHostId === h.id ? GOLD : '#E8E6E0',
              }}
            >
              {h.name}
            </button>
          ))}
        </div>
      </div>

      <div className="flex min-w-0 flex-1 flex-col rounded-lg border border-white/10 bg-[#15161A] p-2">
        <div className="mb-2 flex items-center gap-2 px-1 text-xs" style={{ color: TEXT_SECONDARY }}>
          <span
            className="inline-block h-2 w-2 rounded-full"
            style={{ background: connected ? '#2ECC71' : '#7A7D85' }}
          />
          {activeHostId ? (connected ? 'Connected' : 'Disconnected') : 'Select a host to connect'}
        </div>
        <div ref={containerRef} className="min-h-0 flex-1" />
      </div>
    </div>
  )
}
