'use client'

import { useCallback, useEffect, useState } from 'react'
import { parseCertList, type CertInfo } from '@/lib/parse-caddy'
import { apiFetch } from '@/lib/csrf'

async function fetchCerts(): Promise<CertInfo[]> {
  const res = await apiFetch('/api/agent/exec', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ command_key: 'caddy_list_certs', args: [] }),
  })

  if (!res.ok) {
    const text = await res.text()
    throw new Error(`agent ${res.status}: ${text}`)
  }

  const reader = res.body?.getReader()
  if (!reader) throw new Error('no response body')

  const decoder = new TextDecoder()
  let buffer = ''
  let output = ''

  while (true) {
    const { done, value } = await reader.read()
    if (done) break

    buffer += decoder.decode(value, { stream: true })
    const lines = buffer.split('\n')
    buffer = lines.pop() ?? ''

    for (const line of lines) {
      if (line.startsWith('data:')) {
        try {
          const parsed = JSON.parse(line.slice(5).trim()) as { data?: string }
          if (parsed.data !== undefined) output += parsed.data
        } catch {
          // ignore malformed
        }
      }
    }
  }

  return parseCertList(output)
}

type Props = {
  initialCerts: CertInfo[]
  certsError: string | null
}

export default function CaddyView({ initialCerts, certsError }: Props) {
  const [certs, setCerts] = useState<CertInfo[]>(initialCerts)
  const [error, setError] = useState<string | null>(certsError)
  const [refreshing, setRefreshing] = useState(false)
  const [lastUpdated, setLastUpdated] = useState<Date>(new Date())

  const refresh = useCallback(async () => {
    setRefreshing(true)
    try {
      const updated = await fetchCerts()
      setCerts(updated)
      setError(null)
      setLastUpdated(new Date())
    } catch (err) {
      setError(err instanceof Error ? err.message : 'failed')
    } finally {
      setRefreshing(false)
    }
  }, [])

  useEffect(() => {
    const id = setInterval(refresh, 60000)
    return () => clearInterval(id)
  }, [refresh])

  return (
    <section className="space-y-3">
      <div className="flex items-center justify-between">
        <h2 className="text-lg font-medium tracking-tight">TLS Certificates</h2>
        <div className="flex items-center gap-3">
          {refreshing && (
            <span className="text-xs text-muted-foreground animate-pulse">refreshing…</span>
          )}
          <span className="text-xs text-muted-foreground">
            updated {lastUpdated.toLocaleTimeString()}
          </span>
          <button
            onClick={refresh}
            disabled={refreshing}
            className="rounded-md border border-border px-3 py-1 text-xs hover:bg-muted/50 disabled:opacity-50 transition-colors"
          >
            Refresh
          </button>
        </div>
      </div>

      {error ? (
        <div className="rounded-lg border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive">
          {error}
        </div>
      ) : certs.length === 0 ? (
        <div className="rounded-lg border border-border p-6 text-sm text-muted-foreground">
          No certificates found in <code className="font-mono">/data/caddy/certificates/</code>.
        </div>
      ) : (
        <div className="overflow-x-auto rounded-lg border border-border">
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-border bg-muted/50">
                <th className="px-4 py-3 text-left font-medium text-muted-foreground">Domain</th>
                <th className="px-4 py-3 text-left font-medium text-muted-foreground">Issuer</th>
                <th className="px-4 py-3 text-left font-medium text-muted-foreground">Valid from</th>
                <th className="px-4 py-3 text-left font-medium text-muted-foreground">Expires</th>
                <th className="px-4 py-3 text-left font-medium text-muted-foreground">Status</th>
              </tr>
            </thead>
            <tbody>
              {certs.map((cert) => (
                <tr
                  key={cert.domain}
                  className="border-b border-border last:border-0 hover:bg-muted/30 transition-colors"
                >
                  <td className="px-4 py-3 font-mono text-xs font-medium">{cert.domain}</td>
                  <td className="px-4 py-3 text-xs text-muted-foreground">{cert.issuerCN}</td>
                  <td className="px-4 py-3 text-xs text-muted-foreground">{cert.notBefore || '—'}</td>
                  <td className="px-4 py-3 text-xs text-muted-foreground">{cert.notAfter || '—'}</td>
                  <td className="px-4 py-3">
                    <CertStatusBadge cert={cert} />
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </section>
  )
}

function CertStatusBadge({ cert }: { cert: CertInfo }) {
  if (cert.expired) {
    return (
      <span className="inline-flex items-center gap-1.5 rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-800 dark:bg-red-900/30 dark:text-red-400">
        <span className="size-1.5 rounded-full bg-red-500" />
        Expired
      </span>
    )
  }
  if (cert.expiringWarning) {
    return (
      <span className="inline-flex items-center gap-1.5 rounded-full bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-800 dark:bg-amber-900/30 dark:text-amber-400">
        <span className="size-1.5 rounded-full bg-amber-500" />
        Expiring soon
      </span>
    )
  }
  return (
    <span className="inline-flex items-center gap-1.5 rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800 dark:bg-green-900/30 dark:text-green-400">
      <span className="size-1.5 rounded-full bg-green-500" />
      Valid
    </span>
  )
}
