import { useCallback, useEffect, useMemo, useState } from "react"
import { Link } from "react-router"
import {
  AlertTriangle,
  CheckCircle2,
  Mail,
  Plus,
  RefreshCw,
  Trash2,
} from "lucide-react"

import { ArcadiaError, useArcadiaClient } from "@crema/arcadia-client"
import { AlertBanner, ConfirmDialog, EmptyState, LoadingOverlay } from "@crema/feedback-ui"
import {
  IncidentTimeline,
  StatusBoard,
  type ComponentState,
  type Severity,
  type StatusComponent as StatusUiComponent,
  type StatusIncident,
} from "@crema/status-ui"

import { AppShell } from "~/components/layout/app-shell"
import { Badge } from "~/components/ui/badge"
import { Button } from "~/components/ui/button"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "~/components/ui/card"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "~/components/ui/dialog"
import { Input } from "~/components/ui/input"
import { Label } from "~/components/ui/label"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "~/components/ui/select"
import { Textarea } from "~/components/ui/textarea"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs"
import {
  addIncidentUpdate,
  createComponent,
  createIncident,
  deleteComponent,
  listComponents,
  listIncidents,
  listSubscribers,
  resolveIncident,
  updateComponent,
  updateIncident,
  type ComponentInput,
  type ComponentStatus,
  type Incident,
  type IncidentImpact,
  type IncidentInput,
  type IncidentStatus,
  type StatusComponent,
  type Subscriber,
} from "~/lib/arcadia/status-page"
import { pageTitle } from "~/lib/page-meta"
import { useSession } from "~/lib/session"
import { useRegisterAdminContext } from "~/lib/admin-context"

export const meta = () => pageTitle("Status page")

const STATUSES: ComponentStatus[] = [
  "operational",
  "degraded_performance",
  "partial_outage",
  "major_outage",
  "maintenance",
]
const INCIDENT_STATUSES: IncidentStatus[] = ["investigating", "identified", "monitoring", "resolved"]
const IMPACTS: IncidentImpact[] = ["none", "minor", "major", "critical"]

type ComponentEditor =
  | { kind: "create" }
  | { kind: "edit"; component: StatusComponent }
  | null

type IncidentEditor =
  | { kind: "create" }
  | { kind: "edit"; incident: Incident }
  | { kind: "update"; incident: Incident }
  | null

export default function StatusPageRoute() {
  const session = useSession()
  const arcadia = useArcadiaClient()

  const [components, setComponents] = useState<StatusComponent[]>([])
  const [incidents, setIncidents] = useState<Incident[]>([])
  const [subscribers, setSubscribers] = useState<Subscriber[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [info, setInfo] = useState<string | null>(null)

  const refresh = useCallback(async () => {
    setError(null)
    setLoading(true)
    try {
      const [c, i, s] = await Promise.all([
        listComponents(arcadia).catch(() => [] as StatusComponent[]),
        listIncidents(arcadia).catch(() => [] as Incident[]),
        listSubscribers(arcadia).catch(() => [] as Subscriber[]),
      ])
      setComponents(c)
      setIncidents(i)
      setSubscribers(s)
    } catch (err) {
      setError(err instanceof ArcadiaError ? err.message : "Failed to load status page.")
    } finally {
      setLoading(false)
    }
  }, [arcadia])

  useEffect(() => {
    if (session) refresh()
  }, [session, refresh])

  useRegisterAdminContext("status_page", {
    components: components.length,
    open_incidents: incidents.filter((i) => i.status !== "resolved").length,
    subscribers: subscribers.length,
  })

  // Map arcadia component statuses to status-ui ComponentState.
  const uiComponents: StatusUiComponent[] = useMemo(
    () =>
      components.map((c) => ({
        id: c.id,
        name: c.name,
        description: c.description ?? undefined,
        state: arcadiaToUiComponentState(c.status),
      })),
    [components],
  )

  const uiIncidents: StatusIncident[] = useMemo(
    () =>
      incidents.map((i) => ({
        id: i.id,
        title: i.title,
        severity: impactToSeverity(i.impact),
        startedAt: new Date(i.inserted_at),
        resolvedAt: i.resolved_at ? new Date(i.resolved_at) : undefined,
        affectedComponentIds: i.components.map((c) => c.id),
        updates: i.updates.map((u) => ({
          id: u.id,
          at: new Date(u.inserted_at),
          status: u.status as StatusIncident["updates"][number]["status"],
          body: u.body,
        })),
      })),
    [incidents],
  )

  const componentsById = useMemo(
    () => new Map(uiComponents.map((c) => [c.id, c])),
    [uiComponents],
  )

  if (!session) {
    return (
      <AppShell title="Status page">
        <div className="p-8">
          <Card className="max-w-md">
            <CardHeader>
              <CardTitle>Sign in required</CardTitle>
              <CardDescription>Status page admin requires an admin session.</CardDescription>
            </CardHeader>
            <CardContent>
              <Button asChild>
                <Link to="/login?next=/status-page">Sign in</Link>
              </Button>
            </CardContent>
          </Card>
        </div>
      </AppShell>
    )
  }

  return (
    <AppShell title="Status page">
      <div className="flex flex-col gap-4 p-6">
        <header className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
          <div>
            <h1 className="text-2xl font-semibold tracking-tight">Status page</h1>
            <p className="text-sm text-muted-foreground">
              Public-facing status board: components, incidents, email subscribers.
            </p>
          </div>
          <Button
            variant="outline"
            size="sm"
            onClick={refresh}
            disabled={loading}
            data-action="status-refresh"
          >
            <RefreshCw className={`size-4 ${loading ? "animate-spin" : ""}`} />
            Refresh
          </Button>
        </header>

        {error ? (
          <AlertBanner variant="error" dismissible onDismiss={() => setError(null)}>
            {error}
          </AlertBanner>
        ) : null}
        {info ? (
          <AlertBanner variant="success" dismissible onDismiss={() => setInfo(null)}>
            {info}
          </AlertBanner>
        ) : null}

        {/* Live preview using the public-facing widget */}
        {uiComponents.length > 0 ? (
          <Card>
            <CardHeader>
              <CardTitle className="text-base">Public preview</CardTitle>
              <CardDescription>What subscribers see right now.</CardDescription>
            </CardHeader>
            <CardContent>
              <StatusBoard components={uiComponents} />
              {uiIncidents.length > 0 ? (
                <div className="mt-4">
                  <IncidentTimeline
                    incidents={uiIncidents.slice(0, 5)}
                    componentsById={componentsById}
                  />
                </div>
              ) : null}
            </CardContent>
          </Card>
        ) : null}

        <Tabs defaultValue="components">
          <TabsList>
            <TabsTrigger value="components" data-action="status-tab-components">
              Components ({components.length})
            </TabsTrigger>
            <TabsTrigger value="incidents" data-action="status-tab-incidents">
              Incidents ({incidents.length})
            </TabsTrigger>
            <TabsTrigger value="subscribers" data-action="status-tab-subscribers">
              Subscribers ({subscribers.length})
            </TabsTrigger>
          </TabsList>

          <TabsContent value="components" className="pt-4">
            <ComponentsPanel
              components={components}
              loading={loading}
              onChanged={refresh}
              onError={setError}
              onInfo={setInfo}
            />
          </TabsContent>

          <TabsContent value="incidents" className="pt-4">
            <IncidentsPanel
              incidents={incidents}
              components={components}
              loading={loading}
              onChanged={refresh}
              onError={setError}
              onInfo={setInfo}
            />
          </TabsContent>

          <TabsContent value="subscribers" className="pt-4">
            <SubscribersPanel subscribers={subscribers} loading={loading} />
          </TabsContent>
        </Tabs>
      </div>
    </AppShell>
  )
}

function arcadiaToUiComponentState(s: ComponentStatus): ComponentState {
  switch (s) {
    case "operational":
      return "operational"
    case "degraded_performance":
      return "degraded"
    case "partial_outage":
      return "partial-outage"
    case "major_outage":
      return "major-outage"
    case "maintenance":
      return "maintenance"
    default:
      return "operational"
  }
}

function impactToSeverity(i: IncidentImpact): Severity {
  if (i === "critical") return "critical"
  if (i === "major") return "major"
  return "minor"
}

// --- Components panel --------------------------------------------------

function ComponentsPanel({
  components,
  loading,
  onChanged,
  onError,
  onInfo,
}: {
  components: StatusComponent[]
  loading: boolean
  onChanged: () => Promise<void>
  onError: (msg: string | null) => void
  onInfo: (msg: string | null) => void
}) {
  const arcadia = useArcadiaClient()
  const [editor, setEditor] = useState<ComponentEditor>(null)
  const [pendingDelete, setPendingDelete] = useState<StatusComponent | null>(null)

  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between">
        <CardDescription>
          Each component shows its operational state on the public page. Group related ones via
          group_name.
        </CardDescription>
        <Button size="sm" onClick={() => setEditor({ kind: "create" })} data-action="status-component-create">
          <Plus className="size-4" />
          New component
        </Button>
      </CardHeader>
      <CardContent className="relative p-0">
        <LoadingOverlay
          active={loading && components.length === 0}
          label="Loading components…"
        />
        {components.length === 0 && !loading ? (
          <EmptyState title="No components yet." description="Add the first one to seed the public board." className="py-8" />
        ) : (
          <ul className="divide-y border-y">
            {components.map((c) => (
              <li
                key={c.id}
                className="flex items-center justify-between gap-3 px-3 py-2 text-sm"
              >
                <div className="flex flex-col gap-0.5">
                  <span className="flex items-center gap-2">
                    <span className="font-medium">{c.name}</span>
                    <Badge variant={statusVariant(c.status)}>{c.status}</Badge>
                    {c.group_name ? (
                      <span className="text-xs text-muted-foreground">
                        group: {c.group_name}
                      </span>
                    ) : null}
                  </span>
                  {c.description ? (
                    <span className="text-xs text-muted-foreground">{c.description}</span>
                  ) : null}
                </div>
                <div className="flex gap-2">
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => setEditor({ kind: "edit", component: c })}
                    data-action={`status-component-${c.id}-edit`}
                  >
                    Edit
                  </Button>
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => setPendingDelete(c)}
                    data-action={`status-component-${c.id}-delete`}
                  >
                    <Trash2 className="size-3.5" />
                  </Button>
                </div>
              </li>
            ))}
          </ul>
        )}
      </CardContent>

      <ComponentEditorDialog
        state={editor}
        onClose={() => setEditor(null)}
        onSaved={async (msg) => {
          setEditor(null)
          if (msg) onInfo(msg)
          await onChanged()
        }}
        onError={onError}
      />

      <ConfirmDialog
        open={pendingDelete !== null}
        onOpenChange={(o) => !o && setPendingDelete(null)}
        title="Delete component?"
        description={
          pendingDelete
            ? `${pendingDelete.name} will be removed from the public status page.`
            : ""
        }
        confirmLabel="Delete"
        variant="danger"
        onConfirm={async () => {
          if (!pendingDelete) return
          try {
            await deleteComponent(arcadia, pendingDelete.id)
            setPendingDelete(null)
            onInfo("Component deleted.")
            await onChanged()
          } catch (err) {
            onError(err instanceof ArcadiaError ? err.message : "Delete failed.")
            setPendingDelete(null)
          }
        }}
      />
    </Card>
  )
}

function statusVariant(s: ComponentStatus): "default" | "secondary" | "destructive" | "outline" {
  if (s === "operational") return "default"
  if (s === "major_outage") return "destructive"
  if (s === "partial_outage" || s === "degraded_performance") return "secondary"
  return "outline"
}

function ComponentEditorDialog({
  state,
  onClose,
  onSaved,
  onError,
}: {
  state: ComponentEditor
  onClose: () => void
  onSaved: (msg?: string) => Promise<void>
  onError: (msg: string | null) => void
}) {
  const arcadia = useArcadiaClient()
  const open = state !== null
  const isEdit = state?.kind === "edit"
  const initial = isEdit ? state.component : null

  const [name, setName] = useState("")
  const [description, setDescription] = useState("")
  const [status, setStatus] = useState<ComponentStatus>("operational")
  const [groupName, setGroupName] = useState("")
  const [displayOrder, setDisplayOrder] = useState("0")
  const [saving, setSaving] = useState(false)

  useEffect(() => {
    if (!open) return
    if (initial) {
      setName(initial.name)
      setDescription(initial.description ?? "")
      setStatus(initial.status)
      setGroupName(initial.group_name ?? "")
      setDisplayOrder(String(initial.display_order))
    } else {
      setName("")
      setDescription("")
      setStatus("operational")
      setGroupName("")
      setDisplayOrder("0")
    }
  }, [open, initial])

  const submit = async () => {
    onError(null)
    setSaving(true)
    try {
      const input: ComponentInput = {
        name,
        description: description || undefined,
        status,
        group_name: groupName || null,
        display_order: Number(displayOrder) || 0,
      }
      if (isEdit && initial) {
        await updateComponent(arcadia, initial.id, input)
        await onSaved("Component updated.")
      } else {
        await createComponent(arcadia, input)
        await onSaved("Component created.")
      }
    } catch (err) {
      onError(err instanceof ArcadiaError ? err.message : "Save failed.")
    } finally {
      setSaving(false)
    }
  }

  return (
    <Dialog open={open} onOpenChange={(o) => !o && onClose()}>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>{isEdit ? "Edit component" : "New component"}</DialogTitle>
        </DialogHeader>
        <div className="grid grid-cols-2 gap-3">
          <div className="col-span-2 flex flex-col gap-1.5">
            <Label htmlFor="comp-name">Name</Label>
            <Input
              id="comp-name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              data-action="status-component-form-name"
            />
          </div>
          <div className="col-span-2 flex flex-col gap-1.5">
            <Label htmlFor="comp-description">Description</Label>
            <Textarea
              id="comp-description"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              rows={2}
              data-action="status-component-form-description"
            />
          </div>
          <div className="flex flex-col gap-1.5">
            <Label>Status</Label>
            <Select value={status} onValueChange={setStatus}>
              <SelectTrigger data-action="status-component-form-status">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {STATUSES.map((s) => (
                  <SelectItem key={s} value={s}>
                    {s.replace(/_/g, " ")}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="flex flex-col gap-1.5">
            <Label htmlFor="comp-order">Display order</Label>
            <Input
              id="comp-order"
              type="number"
              value={displayOrder}
              onChange={(e) => setDisplayOrder(e.target.value)}
              data-action="status-component-form-order"
            />
          </div>
          <div className="col-span-2 flex flex-col gap-1.5">
            <Label htmlFor="comp-group">Group (optional)</Label>
            <Input
              id="comp-group"
              value={groupName}
              onChange={(e) => setGroupName(e.target.value)}
              placeholder="API · Storage · Workers"
              data-action="status-component-form-group"
            />
          </div>
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={onClose} disabled={saving}>
            Cancel
          </Button>
          <Button onClick={submit} disabled={saving || !name} data-action="status-component-form-save">
            {saving ? <RefreshCw className="size-4 animate-spin" /> : <CheckCircle2 className="size-4" />}
            {isEdit ? "Save" : "Create"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

// --- Incidents panel ---------------------------------------------------

function IncidentsPanel({
  incidents,
  components,
  loading,
  onChanged,
  onError,
  onInfo,
}: {
  incidents: Incident[]
  components: StatusComponent[]
  loading: boolean
  onChanged: () => Promise<void>
  onError: (msg: string | null) => void
  onInfo: (msg: string | null) => void
}) {
  const arcadia = useArcadiaClient()
  const [editor, setEditor] = useState<IncidentEditor>(null)

  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between">
        <CardDescription>
          Open an incident as soon as you detect impact, then post updates as you investigate and
          resolve.
        </CardDescription>
        <Button size="sm" onClick={() => setEditor({ kind: "create" })} data-action="status-incident-create">
          <Plus className="size-4" />
          New incident
        </Button>
      </CardHeader>
      <CardContent className="relative p-0">
        <LoadingOverlay active={loading && incidents.length === 0} label="Loading incidents…" />
        {incidents.length === 0 && !loading ? (
          <EmptyState
            icon={<AlertTriangle className="size-6" />}
            title="No incidents."
            description="No drama is the right state."
            className="py-8"
          />
        ) : (
          <ul className="flex flex-col divide-y border-y">
            {incidents.map((i) => (
              <li key={i.id} className="flex flex-col gap-2 px-3 py-3 text-sm">
                <div className="flex items-start justify-between gap-3">
                  <div className="flex flex-col gap-0.5">
                    <span className="flex items-center gap-2">
                      <span className="font-medium">{i.title}</span>
                      <Badge variant={incidentVariant(i.status)}>{i.status}</Badge>
                      <Badge variant="secondary">impact: {i.impact}</Badge>
                    </span>
                    <span className="text-xs text-muted-foreground">
                      Started {new Date(i.inserted_at).toLocaleString()}
                      {i.resolved_at
                        ? ` · resolved ${new Date(i.resolved_at).toLocaleString()}`
                        : ""}
                      {i.components.length > 0
                        ? ` · affects: ${i.components.map((c) => c.name).join(", ")}`
                        : ""}
                    </span>
                  </div>
                  <div className="flex flex-col gap-1">
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => setEditor({ kind: "update", incident: i })}
                      data-action={`status-incident-${i.id}-update`}
                    >
                      Post update
                    </Button>
                    {i.status !== "resolved" ? (
                      <Button
                        variant="outline"
                        size="sm"
                        onClick={async () => {
                          try {
                            await resolveIncident(arcadia, i.id)
                            onInfo("Incident resolved.")
                            await onChanged()
                          } catch (err) {
                            onError(
                              err instanceof ArcadiaError ? err.message : "Resolve failed.",
                            )
                          }
                        }}
                        data-action={`status-incident-${i.id}-resolve`}
                      >
                        Resolve
                      </Button>
                    ) : null}
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => setEditor({ kind: "edit", incident: i })}
                      data-action={`status-incident-${i.id}-edit`}
                    >
                      Edit
                    </Button>
                  </div>
                </div>
                {i.updates.length > 0 ? (
                  <ol className="ml-2 flex flex-col gap-1 border-l-2 border-border pl-3 text-xs">
                    {i.updates
                      .slice()
                      .reverse()
                      .map((u) => (
                        <li key={u.id} className="flex flex-col">
                          <span className="font-medium">
                            <Badge variant="outline" className="mr-1 text-[10px]">
                              {u.status}
                            </Badge>
                            {new Date(u.inserted_at).toLocaleString()}
                          </span>
                          <span className="text-muted-foreground">{u.body}</span>
                        </li>
                      ))}
                  </ol>
                ) : null}
              </li>
            ))}
          </ul>
        )}
      </CardContent>

      <IncidentEditorDialog
        state={editor}
        components={components}
        onClose={() => setEditor(null)}
        onSaved={async (msg) => {
          setEditor(null)
          if (msg) onInfo(msg)
          await onChanged()
        }}
        onError={onError}
      />
    </Card>
  )
}

function incidentVariant(
  s: IncidentStatus,
): "default" | "secondary" | "destructive" | "outline" {
  if (s === "resolved") return "default"
  if (s === "investigating") return "destructive"
  return "secondary"
}

function IncidentEditorDialog({
  state,
  components,
  onClose,
  onSaved,
  onError,
}: {
  state: IncidentEditor
  components: StatusComponent[]
  onClose: () => void
  onSaved: (msg?: string) => Promise<void>
  onError: (msg: string | null) => void
}) {
  const arcadia = useArcadiaClient()
  const open = state !== null

  if (state?.kind === "update") {
    return (
      <PostUpdateDialog
        incident={state.incident}
        onClose={onClose}
        onSaved={() => onSaved("Update posted.")}
        onError={onError}
      />
    )
  }

  const isEdit = state?.kind === "edit"
  const initial = isEdit ? state.incident : null

  const [title, setTitle] = useState("")
  const [status, setStatus] = useState<IncidentStatus>("investigating")
  const [impact, setImpact] = useState<IncidentImpact>("minor")
  const [componentIds, setComponentIds] = useState<Set<string>>(new Set())
  const [saving, setSaving] = useState(false)

  useEffect(() => {
    if (!open) return
    if (initial) {
      setTitle(initial.title)
      setStatus(initial.status)
      setImpact(initial.impact)
      setComponentIds(new Set(initial.components.map((c) => c.id)))
    } else {
      setTitle("")
      setStatus("investigating")
      setImpact("minor")
      setComponentIds(new Set())
    }
  }, [open, initial])

  const submit = async () => {
    onError(null)
    setSaving(true)
    try {
      const input: IncidentInput = {
        title,
        status,
        impact,
        component_ids: Array.from(componentIds),
      }
      if (isEdit && initial) {
        await updateIncident(arcadia, initial.id, input)
        await onSaved("Incident updated.")
      } else {
        await createIncident(arcadia, input)
        await onSaved("Incident opened.")
      }
    } catch (err) {
      onError(err instanceof ArcadiaError ? err.message : "Save failed.")
    } finally {
      setSaving(false)
    }
  }

  return (
    <Dialog open={open && state?.kind !== "update"} onOpenChange={(o) => !o && onClose()}>
      <DialogContent className="sm:max-w-lg">
        <DialogHeader>
          <DialogTitle>{isEdit ? "Edit incident" : "New incident"}</DialogTitle>
          <DialogDescription>
            Once created, post updates from the incident row to inform subscribers.
          </DialogDescription>
        </DialogHeader>
        <div className="grid grid-cols-2 gap-3">
          <div className="col-span-2 flex flex-col gap-1.5">
            <Label htmlFor="incident-title">Title</Label>
            <Input
              id="incident-title"
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              data-action="status-incident-form-title"
            />
          </div>
          <div className="flex flex-col gap-1.5">
            <Label>Status</Label>
            <Select value={status} onValueChange={setStatus}>
              <SelectTrigger data-action="status-incident-form-status">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {INCIDENT_STATUSES.map((s) => (
                  <SelectItem key={s} value={s}>
                    {s}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="flex flex-col gap-1.5">
            <Label>Impact</Label>
            <Select value={impact} onValueChange={setImpact}>
              <SelectTrigger data-action="status-incident-form-impact">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {IMPACTS.map((i) => (
                  <SelectItem key={i} value={i}>
                    {i}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="col-span-2 flex flex-col gap-1.5">
            <Label>Affected components</Label>
            {components.length === 0 ? (
              <p className="text-xs text-muted-foreground">
                Create components first; you'll be able to attach them here.
              </p>
            ) : (
              <div className="flex flex-wrap gap-1.5 rounded-md border p-2">
                {components.map((c) => {
                  const active = componentIds.has(c.id)
                  return (
                    <button
                      key={c.id}
                      type="button"
                      onClick={() => {
                        setComponentIds((prev) => {
                          const next = new Set(prev)
                          if (next.has(c.id)) next.delete(c.id)
                          else next.add(c.id)
                          return next
                        })
                      }}
                      data-action={`status-incident-form-component-${c.id}`}
                      className={[
                        "rounded-full border px-2.5 py-1 text-xs font-medium transition-colors",
                        active
                          ? "border-primary bg-primary/10 text-primary"
                          : "border-border text-muted-foreground hover:bg-accent",
                      ].join(" ")}
                    >
                      {c.name}
                    </button>
                  )
                })}
              </div>
            )}
          </div>
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={onClose} disabled={saving}>
            Cancel
          </Button>
          <Button
            onClick={submit}
            disabled={saving || !title}
            data-action="status-incident-form-save"
          >
            {saving ? <RefreshCw className="size-4 animate-spin" /> : <CheckCircle2 className="size-4" />}
            {isEdit ? "Save" : "Open incident"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

function PostUpdateDialog({
  incident,
  onClose,
  onSaved,
  onError,
}: {
  incident: Incident
  onClose: () => void
  onSaved: () => Promise<void>
  onError: (msg: string | null) => void
}) {
  const arcadia = useArcadiaClient()
  const [status, setStatus] = useState<IncidentStatus>(incident.status)
  const [body, setBody] = useState("")
  const [saving, setSaving] = useState(false)

  const submit = async () => {
    onError(null)
    setSaving(true)
    try {
      await addIncidentUpdate(arcadia, incident.id, { status, body })
      await onSaved()
    } catch (err) {
      onError(err instanceof ArcadiaError ? err.message : "Post failed.")
    } finally {
      setSaving(false)
    }
  }

  return (
    <Dialog open onOpenChange={(o) => !o && onClose()}>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>Post update</DialogTitle>
          <DialogDescription>
            On <em>{incident.title}</em>. Updates appear on the public timeline.
          </DialogDescription>
        </DialogHeader>
        <div className="flex flex-col gap-3">
          <div className="flex flex-col gap-1.5">
            <Label>Status</Label>
            <Select value={status} onValueChange={setStatus}>
              <SelectTrigger data-action="status-incident-update-status">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {INCIDENT_STATUSES.map((s) => (
                  <SelectItem key={s} value={s}>
                    {s}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="flex flex-col gap-1.5">
            <Label htmlFor="update-body">Body</Label>
            <Textarea
              id="update-body"
              value={body}
              onChange={(e) => setBody(e.target.value)}
              rows={5}
              placeholder="What's the latest? Be brief and concrete."
              data-action="status-incident-update-body"
            />
          </div>
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={onClose} disabled={saving}>
            Cancel
          </Button>
          <Button onClick={submit} disabled={saving || !body} data-action="status-incident-update-save">
            {saving ? <RefreshCw className="size-4 animate-spin" /> : <CheckCircle2 className="size-4" />}
            Post
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

// --- Subscribers panel -------------------------------------------------

function SubscribersPanel({
  subscribers,
  loading,
}: {
  subscribers: Subscriber[]
  loading: boolean
}) {
  if (loading && subscribers.length === 0) {
    return (
      <Card>
        <CardContent className="relative py-8">
          <LoadingOverlay active label="Loading subscribers…" />
        </CardContent>
      </Card>
    )
  }
  return (
    <Card>
      <CardContent className="p-0">
        {subscribers.length === 0 ? (
          <EmptyState
            icon={<Mail className="size-6" />}
            title="No subscribers yet."
            description="They appear here once they confirm via the public status page."
            className="py-8"
          />
        ) : (
          <ul className="divide-y border-y">
            {subscribers.map((s) => (
              <li
                key={s.id}
                className="flex items-center justify-between gap-3 px-3 py-2 text-sm"
              >
                <div className="flex flex-col gap-0.5">
                  <span className="flex items-center gap-2 font-medium">
                    <Mail className="size-3.5 text-muted-foreground" />
                    {s.email}
                  </span>
                  <span className="text-xs text-muted-foreground">
                    Subscribed {new Date(s.inserted_at).toLocaleString()}
                    {s.confirmed_at
                      ? ` · confirmed ${new Date(s.confirmed_at).toLocaleString()}`
                      : " · pending confirmation"}
                  </span>
                </div>
                {s.confirmed_at ? <Badge>confirmed</Badge> : <Badge variant="secondary">pending</Badge>}
              </li>
            ))}
          </ul>
        )}
      </CardContent>
    </Card>
  )
}
