'use client'

import { useEffect, useRef, useState } from 'react'
import { ChevronDown } from 'lucide-react'
import { Panel } from '@/components/cluster/Panel'
import { SlotMeter } from '@/components/cluster/SlotMeter'

const DAILY_BUDGET = 12

type Turn = {
  role: 'user' | 'model'
  reasoning?: string
  content: string
  streaming?: boolean
}

const SEED: Turn[] = [
  { role: 'user', content: 'Why is the sms application degraded?' },
  {
    role: 'model',
    reasoning:
      'The snapshot lists sms with health "degraded" and sync "synced". Sync being clean means the manifests applied fine, so this is a runtime problem rather than a delivery one. The sms namespace shows 0 of 1 pods running. A single pod that never reaches Running, with Argo reporting the desired state as applied, usually means the pod cannot be placed at all.',
    content:
      'Delivery is fine — sms is Synced, so Argo applied everything it was asked to. The failure is at runtime: the namespace has one pod and zero running. Argo marks the app degraded because the workload never became ready, not because the manifests are wrong.',
  },
]

const REPLY =
  'Wave 4 is empty. Waves are sort keys, not a sequence — Argo orders by value and skips gaps, so 3 is followed directly by 5. Nothing is missing.'

const REPLY_REASONING =
  'The user is asking about a gap in the wave column display. Argo CD sync waves are integers used purely for ordering; there is no requirement that they be contiguous. The cluster uses 0,1,2,3,5,6,7,8. This is normal and usually happens when a wave is retired or intentionally reserved.'

export default function ChatPage() {
  const [turns, setTurns] = useState<Turn[]>(SEED)
  const [value, setValue] = useState('')
  const [queue, setQueue] = useState<number | null>(null)
  const [slots, setSlots] = useState(3)
  const [used, setUsed] = useState(2)
  const [openReasoning, setOpenReasoning] = useState<number | null>(1)
  const scrollRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight, behavior: 'smooth' })
  }, [turns, queue])

  const send = () => {
    if (!value.trim() || queue !== null || used >= DAILY_BUDGET) return
    setTurns((t) => [...t, { role: 'user', content: value }])
    setValue('')
    setQueue(3)
  }

  // Placeholder for the queue → stream transition. Real version is SSE from atlas.
  useEffect(() => {
    if (queue === null) return
    if (queue > 0) {
      const t = setTimeout(() => setQueue((q) => (q === null ? null : q - 1)), 700)
      return () => clearTimeout(t)
    }
    setQueue(null)
    setSlots((s) => Math.min(s + 1, 6))
    setUsed((u) => u + 1)
    setTurns((t) => [...t, { role: 'model', reasoning: REPLY_REASONING, content: '', streaming: true }])

    let i = 0
    const stream = setInterval(() => {
      i += 3
      setTurns((t) => {
        const next = [...t]
        const last = next[next.length - 1]
        if (last?.role !== 'model') return t
        next[next.length - 1] = { ...last, content: REPLY.slice(0, i), streaming: i < REPLY.length }
        return next
      })
      if (i >= REPLY.length) {
        clearInterval(stream)
        setSlots((s) => Math.max(s - 1, 1))
      }
    }, 40)
    return () => clearInterval(stream)
  }, [queue])

  const exhausted = used >= DAILY_BUDGET

  return (
    <div className="space-y-6">
      <header className="border border-wire bg-deck p-6 md:p-8">
        <p className="font-data text-[10px] uppercase tracking-[0.2em] text-dim">Surface D — Chat</p>
        <h1 className="mt-3 max-w-3xl font-signage text-3xl font-semibold leading-[1.1] tracking-signage md:text-5xl">
          A 32B model, running on one card, <span className="text-lamp">two rooms from here.</span>
        </h1>
        <p className="mt-5 max-w-2xl font-plex text-sm leading-relaxed text-dim">
          It reads a redacted snapshot of the cluster and answers questions about it. It cannot query anything, run
          anything, or change anything. When all six public slots are busy, you wait in line — the queue is real,
          and so is the hardware.
        </p>
        <div className="mt-6 flex flex-wrap items-center gap-6">
          <SlotMeter used={slots} size="lg" showCap />
          <span className="font-data text-[10px] uppercase tracking-[0.14em] text-dim">
            {DAILY_BUDGET - used} of {DAILY_BUDGET} messages left today
          </span>
        </div>
      </header>

      <div className="grid gap-6 lg:grid-cols-[1fr_260px]">
        <Panel label="Session" hint="anonymous">
          <div ref={scrollRef} className="h-[440px] space-y-5 overflow-y-auto pr-1">
            {turns.map((turn, i) =>
              turn.role === 'user' ? (
                <div key={i} className="flex justify-end">
                  <p className="max-w-[85%] border border-wire-lit bg-riser px-3 py-2 font-plex text-sm text-chalk">
                    {turn.content}
                  </p>
                </div>
              ) : (
                <div key={i} className="max-w-[92%] space-y-2">
                  {turn.reasoning && (
                    <div className="border-l-2 border-lamp/50">
                      <button
                        onClick={() => setOpenReasoning(openReasoning === i ? null : i)}
                        aria-expanded={openReasoning === i}
                        className="flex w-full items-center gap-2 py-1 pl-3 font-data text-[10px] uppercase tracking-[0.16em] text-lamp focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lamp"
                      >
                        <ChevronDown
                          size={12}
                          className={`transition-transform ${openReasoning === i ? '' : '-rotate-90'}`}
                        />
                        thinking
                      </button>
                      {openReasoning === i && (
                        <p className="py-1 pl-3 pr-2 font-data text-[11px] leading-relaxed text-dim">
                          {turn.reasoning}
                        </p>
                      )}
                    </div>
                  )}
                  <p className="font-plex text-sm leading-relaxed text-chalk">
                    {turn.content}
                    {turn.streaming && <span className="ml-0.5 inline-block h-4 w-2 animate-pulse bg-lamp align-text-bottom" />}
                  </p>
                </div>
              ),
            )}

            {queue !== null && (
              <div className="flex items-center gap-3 border border-lamp/40 px-3 py-2">
                <SlotMeter used={6} />
                <p className="font-data text-[11px] text-lamp">
                  all six public slots busy · position {queue} in queue
                </p>
              </div>
            )}
          </div>

          <form
            onSubmit={(e) => {
              e.preventDefault()
              send()
            }}
            className="mt-3 flex items-center gap-2 border-t border-wire pt-3"
          >
            <input
              value={value}
              onChange={(e) => setValue(e.target.value)}
              disabled={exhausted}
              aria-label="Message"
              placeholder={exhausted ? 'Daily limit reached — resets in 14h' : 'Ask about the cluster'}
              className="min-w-0 flex-1 bg-transparent font-plex text-sm text-chalk placeholder:text-dim/60 focus:outline-none disabled:cursor-not-allowed"
            />
            <button
              type="submit"
              disabled={exhausted || queue !== null}
              className="border border-lamp px-3 py-1 font-data text-[10px] uppercase tracking-[0.14em] text-lamp transition-colors hover:bg-lamp hover:text-void focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lamp disabled:opacity-30 disabled:hover:bg-transparent disabled:hover:text-lamp"
            >
              send
            </button>
          </form>
        </Panel>

        <div className="space-y-6">
          <Panel label="Limits" hint="tier 3">
            <dl className="space-y-2.5 font-data text-[11px]">
              {[
                ['public slots', '6 of 8'],
                ['queue depth', '20'],
                ['per session', '12 / day'],
                ['request timeout', '120s'],
                ['output cap', '1500 tokens'],
              ].map(([k, v]) => (
                <div key={k} className="flex items-baseline gap-2">
                  <dt className="text-dim">{k}</dt>
                  <dd className="ml-auto tabular-nums text-chalk">{v}</dd>
                </div>
              ))}
            </dl>
            <p className="mt-4 border-t border-wire pt-3 font-plex text-[11px] leading-relaxed text-dim">
              Closing this tab frees your slot immediately. Two slots stay reserved so the operator is never locked
              out of their own hardware.
            </p>
          </Panel>

          <Panel label="Cannot do" hint="by construction">
            <ul className="space-y-1.5 font-data text-[10px] text-dim">
              {['call tools', 'query the cluster', 'read logs', 'change anything', 'see Secret contents'].map((x) => (
                <li key={x} className="flex items-center gap-2">
                  <span className="h-px w-3 bg-wire-lit" />
                  {x}
                </li>
              ))}
            </ul>
          </Panel>
        </div>
      </div>
    </div>
  )
}
