// Integrations (operator) — platform/pooled external-API arrangements across
// every scope, backed by the integration registry on arcadia-llm-gateway
// (`/api/v1/integrations*`). The operator manages pooled credentials and
// inspects cross-tenant usage metadata; secrets are write-only.

import { useCallback, useEffect, useMemo, useState } from "react"
import {
  AlertTriangle,
  CheckCircle2,
  FlaskConical,
  KeyRound,
  Pencil,
  Plug,
  Plus,
  Trash2,
} from "lucide-react"
import { ArcadiaError } from "@crema/arcadia-core-client"

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 { Switch } from "~/components/ui/switch"
import { useGatewayClient } from "~/lib/gateway"
import {
  addCredential,
  createIntegration,
  credentialHealth,
  deleteIntegration,
  formatUsd,
  listIntegrations,
  testIntegration,
  updateIntegration,
  usageSummary,
  type AuthKind,
  type Integration,
  type Scope,
  type UsageEntry,
} from "~/lib/arcadia/integrations"

const AUTH_KINDS: AuthKind[] = ["bearer_static", "api_key_header", "basic", "oauth2"]
const SCOPES: Scope[] = ["platform", "tenant", "app", "user", "agent"]
const SCOPE_FILTERS: Array<Scope | "all"> = ["all", ...SCOPES]

type Form = {
  scope: Scope
  scope_id: string
  provider: string
  capability: string
  display_name: string
  unit: string
  price_usd: string
  monthly_budget_usd: string
  secret_name: string
  auth_kind: AuthKind
  secret: string
  pooled: boolean
}

const emptyForm: Form = {
  scope: "platform",
  scope_id: "",
  provider: "",
  capability: "",
  display_name: "",
  unit: "call",
  price_usd: "",
  monthly_budget_usd: "",
  secret_name: "",
  auth_kind: "bearer_static",
  secret: "",
  pooled: true,
}

export default function IntegrationsRoute() {
  const gw = useGatewayClient()
  const [items, setItems] = useState<Integration[]>([])
  const [usage, setUsage] = useState<UsageEntry[]>([])
  const [scopeFilter, setScopeFilter] = useState<Scope | "all">("all")
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [editing, setEditing] = useState<Integration | "new" | null>(null)
  const [tests, setTests] = useState<Record<string, { ok: boolean; message: string }>>({})

  const refresh = useCallback(async () => {
    setError(null)
    const filter = scopeFilter === "all" ? {} : { scope: scopeFilter }
    try {
      const [list, use] = await Promise.all([
        listIntegrations(gw, filter),
        usageSummary(gw, filter).catch(() => [] as UsageEntry[]),
      ])
      setItems(list)
      setUsage(use)
    } catch (e) {
      setError(e instanceof Error ? e.message : "Failed to load integrations.")
    } finally {
      setLoading(false)
    }
  }, [gw, scopeFilter])

  useEffect(() => {
    void refresh()
  }, [refresh])

  const usageById = useMemo(
    () => new Map(usage.map((u) => [u.integration_id, u] as const)),
    [usage],
  )

  const runTest = useCallback(
    async (it: Integration) => {
      setTests((t) => ({ ...t, [it.id]: { ok: true, message: "Testing…" } }))
      try {
        const verdict = await testIntegration(gw, it.id)
        const remaining = verdict.policy?.remaining_budget_usd
        setTests((t) => ({
          ...t,
          [it.id]: {
            ok: true,
            message:
              verdict.status === "ok"
                ? `OK — within budget & rate${remaining ? ` (${formatUsd(remaining)} left)` : ""}`
                : verdict.status,
          },
        }))
      } catch (e) {
        const msg =
          e instanceof ArcadiaError
            ? e.status === 409
              ? "Credential expired — rotate it"
              : e.status === 429
                ? "Over budget / rate limit"
                : e.status === 404
                  ? "No credential to test"
                  : e.message
            : "Test failed"
        setTests((t) => ({ ...t, [it.id]: { ok: false, message: msg } }))
      }
    },
    [gw],
  )

  const toggleEnabled = useCallback(
    async (it: Integration, enabled: boolean) => {
      setItems((xs) => xs.map((x) => (x.id === it.id ? { ...x, enabled } : x)))
      try {
        await updateIntegration(gw, it.id, { enabled })
      } catch {
        setItems((xs) => xs.map((x) => (x.id === it.id ? { ...x, enabled: !enabled } : x)))
      }
    },
    [gw],
  )

  const remove = useCallback(
    async (it: Integration) => {
      if (!window.confirm(`Delete ${it.display_name || it.provider} and its credentials?`)) return
      await deleteIntegration(gw, it.id)
      await refresh()
    },
    [gw, refresh],
  )

  return (
    <AppShell>
      <div className="flex items-center justify-between gap-3">
        <div className="flex items-center gap-3">
          <div className="flex size-10 items-center justify-center rounded-lg bg-primary/10 text-primary">
            <Plug className="size-5" />
          </div>
          <div>
            <h1 className="text-2xl font-semibold">Integrations</h1>
            <p className="text-sm text-muted-foreground">
              Platform &amp; pooled external-API credentials across every scope.
              Keys are stored encrypted and never shown; usage is metadata only.
            </p>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <Select value={scopeFilter} onValueChange={(v) => setScopeFilter((v as Scope | "all") ?? "all")}>
            <SelectTrigger className="w-36">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {SCOPE_FILTERS.map((s) => (
                <SelectItem key={s} value={s}>
                  {s === "all" ? "All scopes" : s}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Button onClick={() => setEditing("new")}>
            <Plus className="size-4" /> Add integration
          </Button>
        </div>
      </div>

      {error ? (
        <Card className="border-destructive/40">
          <CardHeader>
            <CardTitle className="text-destructive">Couldn’t load integrations</CardTitle>
            <CardDescription>{error}</CardDescription>
          </CardHeader>
        </Card>
      ) : loading ? (
        <p className="text-sm text-muted-foreground">Loading…</p>
      ) : items.length === 0 ? (
        <Card>
          <CardHeader>
            <CardTitle>No integrations in this scope</CardTitle>
            <CardDescription>
              Register a platform/pooled arrangement — a shared key the platform
              meters and bills to tenants who opt in.
            </CardDescription>
          </CardHeader>
          <CardContent>
            <Button onClick={() => setEditing("new")}>
              <Plus className="size-4" /> Add integration
            </Button>
          </CardContent>
        </Card>
      ) : (
        <div className="grid gap-4">
          {items.map((it) => {
            const u = usageById.get(it.id)
            const test = tests[it.id]
            return (
              <Card key={it.id}>
                <CardHeader>
                  <div className="flex items-start justify-between gap-3">
                    <div>
                      <CardTitle className="flex items-center gap-2">
                        {it.display_name || it.provider}
                        <Badge>{it.scope}</Badge>
                        {it.scope_id ? (
                          <span className="font-mono text-xs text-muted-foreground">
                            {it.scope_id}
                          </span>
                        ) : null}
                        {it.capability ? (
                          <Badge variant="secondary">{it.capability}</Badge>
                        ) : null}
                      </CardTitle>
                      <CardDescription>
                        {it.provider}
                        {it.cost_model?.price_usd
                          ? ` · ${formatUsd(it.cost_model.price_usd)}/${it.cost_model.unit ?? "call"}`
                          : ""}
                        {it.constraints?.monthly_budget_usd
                          ? ` · budget ${formatUsd(it.constraints.monthly_budget_usd)}/mo`
                          : ""}
                      </CardDescription>
                    </div>
                    <div className="flex items-center gap-2">
                      <Label htmlFor={`en-${it.id}`} className="text-xs text-muted-foreground">
                        {it.enabled ? "Enabled" : "Disabled"}
                      </Label>
                      <Switch
                        id={`en-${it.id}`}
                        checked={it.enabled}
                        onCheckedChange={(v) => toggleEnabled(it, v)}
                      />
                    </div>
                  </div>
                </CardHeader>
                <CardContent className="space-y-3">
                  <div className="space-y-1">
                    {it.credentials.length === 0 ? (
                      <p className="text-sm text-muted-foreground">No credential set.</p>
                    ) : (
                      it.credentials.map((cred) => {
                        const health = credentialHealth(cred)
                        return (
                          <div key={cred.id} className="flex items-center gap-2 text-sm">
                            <KeyRound className="size-4 text-muted-foreground" />
                            <span className="font-mono">{cred.secret_name}</span>
                            <Badge variant="outline">{cred.source}</Badge>
                            <HealthBadge health={health} />
                            {cred.expires_at ? (
                              <span className="text-xs text-muted-foreground">
                                expires {new Date(cred.expires_at).toLocaleDateString()}
                              </span>
                            ) : null}
                          </div>
                        )
                      })
                    )}
                  </div>

                  <p className="text-sm text-muted-foreground">
                    {u ? `${u.calls} calls · ${formatUsd(u.cost_usd)} this month` : "No usage yet"}
                  </p>

                  {test ? (
                    <p
                      className={`text-sm ${test.ok ? "text-emerald-600 dark:text-emerald-400" : "text-destructive"}`}
                    >
                      {test.message}
                    </p>
                  ) : null}

                  <div className="flex flex-wrap gap-2 pt-1">
                    <Button variant="outline" size="sm" onClick={() => runTest(it)}>
                      <FlaskConical className="size-4" /> Test
                    </Button>
                    <Button variant="outline" size="sm" onClick={() => setEditing(it)}>
                      <Pencil className="size-4" /> Edit
                    </Button>
                    <Button
                      variant="ghost"
                      size="sm"
                      className="text-destructive"
                      onClick={() => remove(it)}
                    >
                      <Trash2 className="size-4" /> Delete
                    </Button>
                  </div>
                </CardContent>
              </Card>
            )
          })}
        </div>
      )}

      {editing ? (
        <IntegrationDialog
          mode={editing === "new" ? "new" : "edit"}
          initial={editing === "new" ? null : editing}
          onClose={() => setEditing(null)}
          onSaved={async () => {
            setEditing(null)
            await refresh()
          }}
        />
      ) : null}
    </AppShell>
  )
}

function HealthBadge({ health }: { health: ReturnType<typeof credentialHealth> }) {
  if (health === "ok")
    return (
      <Badge variant="secondary" className="gap-1">
        <CheckCircle2 className="size-3" /> healthy
      </Badge>
    )
  const label = health === "missing" ? "no secret" : health
  return (
    <Badge variant="destructive" className="gap-1">
      <AlertTriangle className="size-3" /> {label}
    </Badge>
  )
}

function IntegrationDialog({
  mode,
  initial,
  onClose,
  onSaved,
}: {
  mode: "new" | "edit"
  initial: Integration | null
  onClose: () => void
  onSaved: () => void | Promise<void>
}) {
  const gw = useGatewayClient()
  const [form, setForm] = useState<Form>(() =>
    initial
      ? {
          ...emptyForm,
          scope: initial.scope,
          scope_id: initial.scope_id ?? "",
          provider: initial.provider,
          capability: initial.capability ?? "",
          display_name: initial.display_name ?? "",
          unit: initial.cost_model?.unit ?? "call",
          price_usd: initial.cost_model?.price_usd?.toString() ?? "",
          monthly_budget_usd: initial.constraints?.monthly_budget_usd?.toString() ?? "",
        }
      : emptyForm,
  )
  const [saving, setSaving] = useState(false)
  const [err, setErr] = useState<string | null>(null)
  const set = (patch: Partial<Form>) => setForm((f) => ({ ...f, ...patch }))

  const needsScopeId = form.scope !== "platform"

  const submit = async () => {
    setSaving(true)
    setErr(null)
    try {
      const cost_model = form.price_usd
        ? { unit: form.unit as "call" | "search" | "1k_tokens", price_usd: form.price_usd, currency: "USD" }
        : undefined
      const constraints = form.monthly_budget_usd
        ? { monthly_budget_usd: form.monthly_budget_usd }
        : undefined

      if (mode === "edit" && initial) {
        await updateIntegration(gw, initial.id, {
          provider: form.provider.trim(),
          capability: form.capability.trim() || undefined,
          display_name: form.display_name.trim() || undefined,
          cost_model,
          constraints,
        })
      } else {
        const created = await createIntegration(gw, {
          scope: form.scope,
          scope_id: needsScopeId ? form.scope_id.trim() || undefined : undefined,
          provider: form.provider.trim(),
          capability: form.capability.trim() || undefined,
          display_name: form.display_name.trim() || undefined,
          cost_model,
          constraints,
        })
        if (form.secret_name.trim() && form.secret.trim()) {
          await addCredential(gw, created.id, {
            secret_name: form.secret_name.trim(),
            auth_kind: form.auth_kind,
            secret: form.secret,
            source: form.pooled ? "pooled" : "byo",
          })
        }
      }
      await onSaved()
    } catch (e) {
      setErr(e instanceof Error ? e.message : "Save failed.")
    } finally {
      setSaving(false)
    }
  }

  return (
    <Dialog open onOpenChange={(o) => (!o ? onClose() : undefined)}>
      <DialogContent className="max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle>{mode === "new" ? "Add integration" : "Edit integration"}</DialogTitle>
          <DialogDescription>
            Register an external-API arrangement. Platform scope = a pooled key
            the platform meters and bills.
          </DialogDescription>
        </DialogHeader>

        <div className="grid gap-4 py-2">
          {mode === "new" ? (
            <div className="grid grid-cols-2 gap-3">
              <Field label="Scope">
                <Select value={form.scope} onValueChange={(v) => set({ scope: (v as Scope) ?? "platform" })}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {SCOPES.map((s) => (
                      <SelectItem key={s} value={s}>
                        {s}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </Field>
              <Field label="Scope ID" hint={needsScopeId ? "tenant/app/user/agent id" : "n/a for platform"}>
                <Input
                  value={form.scope_id}
                  onChange={(e) => set({ scope_id: e.target.value })}
                  disabled={!needsScopeId}
                  placeholder={needsScopeId ? "acme" : "—"}
                />
              </Field>
            </div>
          ) : null}

          <Field label="Provider" hint="e.g. tavily, google_maps, duffel">
            <Input
              value={form.provider}
              onChange={(e) => set({ provider: e.target.value })}
              placeholder="tavily"
            />
          </Field>
          <Field label="Capability (optional)" hint="e.g. web_search, geocode">
            <Input
              value={form.capability}
              onChange={(e) => set({ capability: e.target.value })}
              placeholder="web_search"
            />
          </Field>
          <Field label="Display name (optional)">
            <Input
              value={form.display_name}
              onChange={(e) => set({ display_name: e.target.value })}
            />
          </Field>
          <div className="grid grid-cols-2 gap-3">
            <Field label="Price (USD)" hint="per unit, for metering">
              <Input
                inputMode="decimal"
                value={form.price_usd}
                onChange={(e) => set({ price_usd: e.target.value })}
                placeholder="0.01"
              />
            </Field>
            <Field label="Unit">
              <Select value={form.unit} onValueChange={(v) => set({ unit: v ?? "call" })}>
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="call">call</SelectItem>
                  <SelectItem value="search">search</SelectItem>
                  <SelectItem value="1k_tokens">1k_tokens</SelectItem>
                </SelectContent>
              </Select>
            </Field>
          </div>
          <Field label="Monthly budget (USD, optional)" hint="resolve is refused past this">
            <Input
              inputMode="decimal"
              value={form.monthly_budget_usd}
              onChange={(e) => set({ monthly_budget_usd: e.target.value })}
              placeholder="500"
            />
          </Field>

          {mode === "new" ? (
            <div className="space-y-3 rounded-lg border p-3">
              <p className="text-sm font-medium">Credential (optional)</p>
              <Field label="Secret name" hint="the stable handle tools resolve by">
                <Input
                  value={form.secret_name}
                  onChange={(e) => set({ secret_name: e.target.value })}
                  placeholder="tavily_default"
                />
              </Field>
              <div className="grid grid-cols-2 gap-3">
                <Field label="Auth kind">
                  <Select
                    value={form.auth_kind}
                    onValueChange={(v) => set({ auth_kind: (v as AuthKind) ?? "bearer_static" })}
                  >
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      {AUTH_KINDS.map((k) => (
                        <SelectItem key={k} value={k}>
                          {k}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </Field>
                <Field label="Source">
                  <div className="flex h-9 items-center gap-2">
                    <Switch
                      id="pooled"
                      checked={form.pooled}
                      onCheckedChange={(v) => set({ pooled: v })}
                    />
                    <Label htmlFor="pooled" className="text-sm">
                      {form.pooled ? "pooled (billed)" : "BYO key"}
                    </Label>
                  </div>
                </Field>
              </div>
              <Field label="Secret value" hint="stored encrypted, never shown again">
                <Input
                  type="password"
                  value={form.secret}
                  onChange={(e) => set({ secret: e.target.value })}
                  placeholder="sk-…"
                />
              </Field>
            </div>
          ) : null}

          {err ? <p className="text-sm text-destructive">{err}</p> : null}
        </div>

        <DialogFooter>
          <Button variant="ghost" onClick={onClose} disabled={saving}>
            Cancel
          </Button>
          <Button onClick={submit} disabled={saving || !form.provider.trim()}>
            {saving ? "Saving…" : mode === "new" ? "Create" : "Save"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

function Field({
  label,
  hint,
  children,
}: {
  label: string
  hint?: string
  children: React.ReactNode
}) {
  return (
    <div className="grid gap-1.5">
      <Label>{label}</Label>
      {children}
      {hint ? <p className="text-xs text-muted-foreground">{hint}</p> : null}
    </div>
  )
}

export { RouteErrorBoundary as ErrorBoundary } from "~/components/route-error"
