"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { MoreVerticalIcon, Plus, Search } from "lucide-react";
import { PageHeader } from "@/components/layout/PageHeader";
import { EmptyState } from "@/components/layout/EmptyState";
import { ErrorState } from "@/components/layout/ErrorState";
import { StatusBadge } from "@/components/ui/status-badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Skeleton } from "@/components/ui/skeleton";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { apiFetch, errorMessageForUi } from "@/lib/api";
import {
  connectionBadgeVariant,
  connectionStatusIndicator,
  formatConnectionStatus,
} from "@/lib/geotab-display";
import {
  hasCreateCustomerFieldErrors,
  validateCreateCustomerForm,
  type CreateCustomerFieldErrors,
  type CreateCustomerFormValues,
} from "@/lib/onboarding";
import {
  formatTenantStatus,
  tenantStatusBadgeVariant,
  tenantStatusIndicator,
} from "@/lib/status";

type Tenant = {
  id: string;
  name: string;
  slug: string;
  status: string;
  _count?: { users: number; vehicles: number };
  subscriptions?: Array<{ status: string; plan?: { name: string } }>;
  primaryAdmin?: { email: string } | null;
  geotab?: {
    connectionStatus: string;
    isConnected: boolean;
    databaseName: string;
  } | null;
};

const emptyForm = (): CreateCustomerFormValues => ({
  name: "",
  billingEmail: "",
  adminEmail: "",
  adminPassword: "",
  adminFirstName: "",
  adminLastName: "",
});

function RequiredMark() {
  return (
    <span className="text-destructive" aria-hidden>
      *
    </span>
  );
}

export default function CustomersPage() {
  const router = useRouter();
  const [tenants, setTenants] = useState<Tenant[]>([]);
  const [query, setQuery] = useState("");
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [open, setOpen] = useState(false);
  const [form, setForm] = useState<CreateCustomerFormValues>(emptyForm);
  const [saving, setSaving] = useState(false);
  const [formError, setFormError] = useState<string | null>(null);
  const [fieldErrors, setFieldErrors] = useState<CreateCustomerFieldErrors>({});

  useEffect(() => {
    apiFetch<Tenant[]>("/tenants")
      .then(setTenants)
      .catch((err) => setError(errorMessageForUi(err, "Failed")))
      .finally(() => setLoading(false));
  }, []);

  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.primaryAdmin?.email || "").toLowerCase().includes(q),
    );
  }, [tenants, query]);

  function updateField<K extends keyof CreateCustomerFormValues>(
    key: K,
    value: CreateCustomerFormValues[K],
  ) {
    setFieldErrors((prev) => ({ ...prev, [key]: undefined }));
    setForm((prev) => ({ ...prev, [key]: value }));
  }

  function openCreateDialog() {
    setForm(emptyForm());
    setFieldErrors({});
    setFormError(null);
    setOpen(true);
  }

  async function submitCreate() {
    const errors = validateCreateCustomerForm(form);
    if (hasCreateCustomerFieldErrors(errors)) {
      setFieldErrors(errors);
      setFormError(null);
      return;
    }
    setSaving(true);
    setFormError(null);
    setFieldErrors({});
    try {
      const companyName = form.name.trim();
      const created = await apiFetch<Tenant>("/tenants", {
        method: "POST",
        body: JSON.stringify({
          name: companyName,
          companyName,
          billingEmail: form.billingEmail.trim() || undefined,
          adminEmail: form.adminEmail.trim(),
          adminPassword: form.adminPassword,
          adminFirstName: form.adminFirstName.trim() || undefined,
          adminLastName: form.adminLastName.trim() || undefined,
          status: "TRIAL",
        }),
      });
      setOpen(false);
      setForm(emptyForm());
      router.push(`/admin/customers/${created.id}`);
    } catch (err) {
      const message = errorMessageForUi(err, "Create failed");
      if (message) setFormError(message);
    } finally {
      setSaving(false);
    }
  }

  return (
    <>
      <PageHeader
        title="Customers"
        description="Each customer is a company workspace with one Customer Admin in the MVP."
        actions={
          <div className="flex w-full flex-col gap-2 sm:w-auto sm:flex-row sm:items-center">
            <div className="relative w-full sm:w-72">
              <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
              <Input
                className="pl-8"
                placeholder="Search customers…"
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                aria-label="Search customers"
              />
            </div>
            <Button size="sm" onClick={openCreateDialog}>
              <Plus className="mr-2 h-4 w-4" />
              Create customer
            </Button>
          </div>
        }
      />
      {error ? <ErrorState message={error} /> : null}
      {loading ? (
        <Skeleton className="h-48 w-full" />
      ) : !filtered.length ? (
        <EmptyState
          title="No customers"
          description="Create a customer to begin MyGeotab onboarding."
        />
      ) : (
        <div className="overflow-hidden rounded-lg border bg-card">
          <Table>
            <TableHeader>
              <TableRow className="hover:bg-muted">
                <TableHead>Name</TableHead>
                <TableHead className="hidden sm:table-cell">Admin</TableHead>
                <TableHead>Status</TableHead>
                <TableHead className="hidden md:table-cell">MyGeotab</TableHead>
                <TableHead className="hidden lg:table-cell">Vehicles</TableHead>
                <TableHead className="w-12" />
              </TableRow>
            </TableHeader>
            <TableBody>
              {filtered.map((t) => (
                <TableRow key={t.id}>
                  <TableCell className="font-medium">
                    <div>{t.name}</div>
                    <div className="text-xs text-muted-foreground">{t.slug}</div>
                  </TableCell>
                  <TableCell className="hidden text-muted-foreground sm:table-cell">
                    {t.primaryAdmin?.email || "—"}
                  </TableCell>
                  <TableCell>
                    <StatusBadge
                      variant={tenantStatusBadgeVariant(t.status)}
                      indicator={tenantStatusIndicator(t.status)}
                    >
                      {formatTenantStatus(t.status)}
                    </StatusBadge>
                  </TableCell>
                  <TableCell className="hidden md:table-cell">
                    {t.geotab ? (
                      <StatusBadge
                        variant={connectionBadgeVariant(t.geotab.connectionStatus)}
                        indicator={connectionStatusIndicator(t.geotab.connectionStatus)}
                      >
                        {formatConnectionStatus(t.geotab.connectionStatus)}
                      </StatusBadge>
                    ) : (
                      <StatusBadge variant="warning" indicator="warning">
                        Not configured
                      </StatusBadge>
                    )}
                  </TableCell>
                  <TableCell className="hidden lg:table-cell">{t._count?.vehicles ?? 0}</TableCell>
                  <TableCell className="text-right">
                    <DropdownMenu>
                      <DropdownMenuTrigger asChild>
                        <Button
                          variant="ghost"
                          size="icon"
                          className="flex size-8 text-muted-foreground data-[state=open]:bg-muted"
                        >
                          <MoreVerticalIcon />
                          <span className="sr-only">Open menu</span>
                        </Button>
                      </DropdownMenuTrigger>
                      <DropdownMenuContent align="end" className="w-40">
                        <DropdownMenuItem asChild>
                          <Link href={`/admin/customers/${t.id}`}>Edit</Link>
                        </DropdownMenuItem>
                        <DropdownMenuItem>Make a copy</DropdownMenuItem>
                        <DropdownMenuItem>Favorite</DropdownMenuItem>
                        <DropdownMenuSeparator />
                        <DropdownMenuItem className="text-destructive focus:text-destructive">
                          Delete
                        </DropdownMenuItem>
                      </DropdownMenuContent>
                    </DropdownMenu>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </div>
      )}

      <Dialog
        open={open}
        onOpenChange={(next) => {
          setOpen(next);
          if (!next) {
            setFieldErrors({});
            setFormError(null);
          }
        }}
      >
        <DialogContent className="sm:max-w-xl">
          <DialogHeader>
            <DialogTitle>Create customer</DialogTitle>
            <DialogDescription>
              Creates a company workspace and one Customer Admin. MyGeotab is configured on the
              customer detail page.
            </DialogDescription>
          </DialogHeader>

          <div className="grid items-start gap-3 py-1 sm:grid-cols-2">
            <div className="grid content-start gap-1.5">
              <Label htmlFor="cust-name">
                Company name <RequiredMark />
              </Label>
              <Input
                id="cust-name"
                value={form.name}
                onChange={(e) => updateField("name", e.target.value)}
                autoComplete="organization"
                aria-invalid={Boolean(fieldErrors.name)}
                aria-describedby={fieldErrors.name ? "cust-name-error" : undefined}
              />
              {fieldErrors.name ? (
                <p id="cust-name-error" className="text-sm text-destructive" role="alert">
                  {fieldErrors.name}
                </p>
              ) : null}
            </div>
            <div className="grid content-start gap-1.5">
              <Label htmlFor="cust-billing">Billing email</Label>
              <Input
                id="cust-billing"
                type="email"
                value={form.billingEmail}
                onChange={(e) => updateField("billingEmail", e.target.value)}
                aria-invalid={Boolean(fieldErrors.billingEmail)}
                aria-describedby={fieldErrors.billingEmail ? "cust-billing-error" : undefined}
              />
              {fieldErrors.billingEmail ? (
                <p id="cust-billing-error" className="text-sm text-destructive" role="alert">
                  {fieldErrors.billingEmail}
                </p>
              ) : null}
            </div>
            <div className="grid content-start gap-1.5">
              <Label htmlFor="admin-first">First name</Label>
              <Input
                id="admin-first"
                value={form.adminFirstName}
                onChange={(e) => updateField("adminFirstName", e.target.value)}
              />
            </div>
            <div className="grid content-start gap-1.5">
              <Label htmlFor="admin-last">Last name</Label>
              <Input
                id="admin-last"
                value={form.adminLastName}
                onChange={(e) => updateField("adminLastName", e.target.value)}
              />
            </div>
            <div className="grid content-start gap-1.5">
              <Label htmlFor="admin-email">
                Email <RequiredMark />
              </Label>
              <Input
                id="admin-email"
                type="email"
                value={form.adminEmail}
                onChange={(e) => updateField("adminEmail", e.target.value)}
                autoComplete="off"
                aria-invalid={Boolean(fieldErrors.adminEmail)}
                aria-describedby={fieldErrors.adminEmail ? "admin-email-error" : undefined}
              />
              {fieldErrors.adminEmail ? (
                <p id="admin-email-error" className="text-sm text-destructive" role="alert">
                  {fieldErrors.adminEmail}
                </p>
              ) : null}
            </div>
            <div className="grid content-start gap-1.5">
              <Label htmlFor="admin-password">
                Temporary password <RequiredMark />
              </Label>
              <Input
                id="admin-password"
                type="password"
                value={form.adminPassword}
                onChange={(e) => updateField("adminPassword", e.target.value)}
                autoComplete="new-password"
                aria-invalid={Boolean(fieldErrors.adminPassword)}
                aria-describedby={
                  fieldErrors.adminPassword ? "admin-password-error" : undefined
                }
              />
              {fieldErrors.adminPassword ? (
                <p id="admin-password-error" className="text-sm text-destructive" role="alert">
                  {fieldErrors.adminPassword}
                </p>
              ) : null}
            </div>
          </div>

          {formError ? (
            <Alert variant="destructive">
              <AlertTitle>Could not create customer</AlertTitle>
              <AlertDescription>{formError}</AlertDescription>
            </Alert>
          ) : null}

          <DialogFooter>
            <Button variant="outline" disabled={saving} onClick={() => setOpen(false)}>
              Cancel
            </Button>
            <Button disabled={saving} onClick={() => void submitCreate()}>
              {saving ? "Creating…" : "Create customer"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
