"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { RefreshCw, Search, Truck } from "lucide-react";
import { PageHeader } from "@/components/layout/PageHeader";
import { EmptyState } from "@/components/layout/EmptyState";
import { ErrorState } from "@/components/layout/ErrorState";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Skeleton } from "@/components/ui/skeleton";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { apiFetch } from "@/lib/api";
import { formatDateTime } from "@/lib/geotab-display";

type Vehicle = {
  id: string;
  name: string;
  geotabDeviceId?: string | null;
  isActive: boolean;
  lastSyncedAt?: string | null;
};

type SyncResult = {
  message: string;
  synced?: number;
  created?: number;
  updated?: number;
  deactivated?: number;
};

const PAGE_SIZE = 25;

export default function DevicesPage() {
  const [vehicles, setVehicles] = useState<Vehicle[]>([]);
  const [query, setQuery] = useState("");
  const [page, setPage] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [syncing, setSyncing] = useState(false);
  const [syncMessage, setSyncMessage] = useState<string | null>(null);
  const [syncError, setSyncError] = useState<string | null>(null);

  const load = useCallback(async () => {
    const data = await apiFetch<Vehicle[]>("/vehicles");
    setVehicles(data);
  }, []);

  useEffect(() => {
    setLoading(true);
    setError(null);
    load()
      .catch((err) => setError(err instanceof Error ? err.message : "Failed"))
      .finally(() => setLoading(false));
  }, [load]);

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return vehicles;
    return vehicles.filter(
      (v) =>
        v.name.toLowerCase().includes(q) ||
        (v.geotabDeviceId || "").toLowerCase().includes(q),
    );
  }, [vehicles, query]);

  const pageCount = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE));
  const currentPage = Math.min(page, pageCount - 1);
  const pageRows = filtered.slice(currentPage * PAGE_SIZE, currentPage * PAGE_SIZE + PAGE_SIZE);

  async function runSync() {
    setSyncing(true);
    setSyncError(null);
    setSyncMessage(null);
    try {
      const result = await apiFetch<SyncResult>("/geotab/sync-vehicles", { method: "POST" });
      const synced =
        typeof result.synced === "number"
          ? result.synced
          : (result.created ?? 0) + (result.updated ?? 0);
      setSyncMessage(`${result.message} · ${synced} vehicle(s) synchronized`);
      await load();
    } catch (err) {
      setSyncError(err instanceof Error ? err.message : "Sync failed");
    } finally {
      setSyncing(false);
    }
  }

  return (
    <>
      <PageHeader
        title="Vehicles"
        description="Synchronized MyGeotab device catalog for your tenant."
        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 vehicles…"
                value={query}
                onChange={(e) => {
                  setQuery(e.target.value);
                  setPage(0);
                }}
                aria-label="Search vehicles"
              />
            </div>
            <Button size="sm" disabled={syncing || loading} onClick={() => void runSync()}>
              <RefreshCw className={`mr-2 h-4 w-4 ${syncing ? "animate-spin" : ""}`} />
              Sync
            </Button>
          </div>
        }
      />

      {error ? <ErrorState message={error} /> : null}

      {syncError ? (
        <Alert variant="destructive" className="mb-4">
          <AlertTitle>Sync failed</AlertTitle>
          <AlertDescription>{syncError}</AlertDescription>
        </Alert>
      ) : null}

      {syncMessage ? (
        <Alert className="mb-4">
          <AlertTitle>Sync complete</AlertTitle>
          <AlertDescription>{syncMessage}</AlertDescription>
        </Alert>
      ) : null}

      {loading ? (
        <div className="space-y-2">
          <Skeleton className="h-10 w-full" />
          <Skeleton className="h-40 w-full" />
        </div>
      ) : !filtered.length ? (
        <EmptyState
          icon={Truck}
          title="No vehicles found"
          description={
            query
              ? "Try a different search term."
              : "No synchronized vehicles yet. Ask your administrator to connect MyGeotab, then Sync."
          }
        />
      ) : (
        <>
          <div className="overflow-hidden rounded-lg border bg-card">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Vehicle</TableHead>
                  <TableHead className="hidden sm:table-cell">Device ID</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead className="hidden lg:table-cell">Last Synced</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {pageRows.map((v) => (
                  <TableRow key={v.id}>
                    <TableCell className="font-medium">{v.name}</TableCell>
                    <TableCell className="hidden text-muted-foreground sm:table-cell">
                      {v.geotabDeviceId || "—"}
                    </TableCell>
                    <TableCell>
                      <Badge variant={v.isActive ? "secondary" : "outline"}>
                        {v.isActive ? "Active" : "Inactive"}
                      </Badge>
                    </TableCell>
                    <TableCell className="hidden text-muted-foreground lg:table-cell">
                      {formatDateTime(v.lastSyncedAt)}
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>
          {filtered.length > PAGE_SIZE ? (
            <div className="mt-3 flex items-center justify-between text-sm text-muted-foreground">
              <span>
                Page {currentPage + 1} of {pageCount} · {filtered.length} vehicles
              </span>
              <div className="flex gap-2">
                <Button
                  size="sm"
                  variant="outline"
                  disabled={currentPage === 0}
                  onClick={() => setPage((p) => Math.max(0, p - 1))}
                >
                  Previous
                </Button>
                <Button
                  size="sm"
                  variant="outline"
                  disabled={currentPage >= pageCount - 1}
                  onClick={() => setPage((p) => Math.min(pageCount - 1, p + 1))}
                >
                  Next
                </Button>
              </div>
            </div>
          ) : null}
        </>
      )}
    </>
  );
}
