import { useCallback, useEffect, useMemo, useState } from "react"
import { Link } from "react-router"
import { AlertTriangle, Loader2, MoreHorizontal, Pause, Play, Plus, RefreshCw, Search, X } from "lucide-react"

import { ArcadiaError, useArcadiaClient } from "@crema/arcadia-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 {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu"
import { Input } from "~/components/ui/input"
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "~/components/ui/table"
import { activateTenant, deactivateTenant, listTenants, suspendTenant, type Tenant, type TenantStatus } from "~/lib/arcadia/tenants"
import { pageTitle } from "~/lib/page-meta"
import { useSession } from "~/lib/session"

export const meta = () => pageTitle("Tenants")

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

  const [tenants, setTenants] = useState<Tenant[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [query, setQuery] = useState("")

  const refresh = useCallback(async () => {
    setError(null)
    setLoading(true)
    try {
      const list = await listTenants(arcadia)
      setTenants(list)
    } catch (err) {
      setError(err instanceof ArcadiaError ? err.message : "Failed to load tenants.")
    } finally {
      setLoading(false)
    }
  }, [arcadia])

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

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase()
    if (!q) return tenants
    return tenants.filter(
      (t) =>
        t.name.toLowerCase().includes(q) ||
        t.slug.toLowerCase().includes(q) ||
        t.id.toLowerCase().includes(q),
    )
  }, [tenants, query])

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

  return (
    <AppShell title="Tenants">
      <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">Tenants</h1>
            <p className="text-sm text-muted-foreground">
              Multi-tenant workspaces on this arcadia deployment.
            </p>
          </div>
          <div className="flex items-center gap-2">
            <Button
              variant="outline"
              size="sm"
              onClick={refresh}
              disabled={loading}
              data-action="tenants-refresh"
            >
              <RefreshCw className={`size-4 ${loading ? "animate-spin" : ""}`} />
              Refresh
            </Button>
            <Button size="sm" disabled data-action="tenants-create">
              <Plus className="size-4" />
              New tenant
            </Button>
          </div>
        </header>

        <Card>
          <CardHeader className="flex flex-row items-center justify-between gap-4">
            <div className="relative max-w-sm flex-1">
              <Search className="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                data-action="tenants-search"
                placeholder="Search by name, slug, or ID"
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                className="pl-9"
              />
              {query ? (
                <button
                  type="button"
                  data-action="tenants-search-clear"
                  onClick={() => setQuery("")}
                  className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
                >
                  <X className="size-4" />
                </button>
              ) : null}
            </div>
            <div className="text-xs text-muted-foreground">
              {filtered.length} of {tenants.length}
            </div>
          </CardHeader>

          <CardContent className="p-0">
            {error ? (
              <div className="flex items-start gap-2 border-t border-destructive/30 bg-destructive/10 px-4 py-3 text-sm text-destructive">
                <AlertTriangle className="mt-0.5 size-4 shrink-0" />
                <span>{error}</span>
              </div>
            ) : null}

            {loading && tenants.length === 0 ? (
              <div className="flex items-center justify-center gap-2 p-12 text-sm text-muted-foreground">
                <Loader2 className="size-4 animate-spin" />
                Loading tenants…
              </div>
            ) : filtered.length === 0 ? (
              <div className="p-12 text-center text-sm text-muted-foreground">
                {query ? "No tenants match that search." : "No tenants yet."}
              </div>
            ) : (
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Name</TableHead>
                    <TableHead>Slug</TableHead>
                    <TableHead>Status</TableHead>
                    <TableHead>Plan</TableHead>
                    <TableHead>Created</TableHead>
                    <TableHead className="w-10" />
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {filtered.map((t) => (
                    <TenantRow key={t.id} tenant={t} onChange={refresh} />
                  ))}
                </TableBody>
              </Table>
            )}
          </CardContent>
        </Card>
      </div>
    </AppShell>
  )
}

function TenantRow({ tenant, onChange }: { tenant: Tenant; onChange: () => void | Promise<void> }) {
  const arcadia = useArcadiaClient()
  const [busy, setBusy] = useState(false)

  const act = async (fn: () => Promise<unknown>) => {
    setBusy(true)
    try {
      await fn()
      await onChange()
    } finally {
      setBusy(false)
    }
  }

  return (
    <TableRow data-action={`tenants-row-${tenant.slug}`}>
      <TableCell className="font-medium">{tenant.name}</TableCell>
      <TableCell>
        <code className="rounded bg-muted px-1.5 py-0.5 font-mono text-xs">{tenant.slug}</code>
      </TableCell>
      <TableCell>
        <StatusBadge status={tenant.status} />
      </TableCell>
      <TableCell>
        <span className="text-sm text-muted-foreground">{tenant.plan?.name ?? "—"}</span>
      </TableCell>
      <TableCell>
        <span className="text-xs text-muted-foreground">{formatDate(tenant.inserted_at)}</span>
      </TableCell>
      <TableCell>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button
              variant="ghost"
              size="icon"
              disabled={busy}
              data-action={`tenants-row-${tenant.slug}-menu`}
            >
              {busy ? <Loader2 className="size-4 animate-spin" /> : <MoreHorizontal className="size-4" />}
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end">
            {tenant.status === "active" ? (
              <DropdownMenuItem onClick={() => act(() => suspendTenant(arcadia, tenant.id))}>
                <Pause className="size-4" />
                Suspend
              </DropdownMenuItem>
            ) : (
              <DropdownMenuItem onClick={() => act(() => activateTenant(arcadia, tenant.id))}>
                <Play className="size-4" />
                Activate
              </DropdownMenuItem>
            )}
            <DropdownMenuSeparator />
            <DropdownMenuItem onClick={() => act(() => deactivateTenant(arcadia, tenant.id))}>
              Deactivate
            </DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      </TableCell>
    </TableRow>
  )
}

function StatusBadge({ status }: { status: TenantStatus }) {
  const variant: "default" | "secondary" | "destructive" | "outline" =
    status === "active" ? "default" : status === "suspended" ? "secondary" : "outline"
  return (
    <Badge variant={variant} className="capitalize">
      {status}
    </Badge>
  )
}

function formatDate(iso: string): string {
  try {
    return new Date(iso).toLocaleDateString(undefined, { year: "numeric", month: "short", day: "numeric" })
  } catch {
    return iso
  }
}
