import { useState } from "react";
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { Smartphone } from "lucide-react";

import { GuestFormSheet } from "@/components/app/GuestFormSheet";
import { ListPage } from "@/components/app/ListPage";
import { Avatar, formatDate } from "@/components/app/Primitives";
import { StatusPill } from "@/components/app/StatusPill";
import type { TableColumn } from "@/components/table/DataTable";
import type { GridColumn } from "@/components/grid/types";
import { validators } from "@/components/grid/types";
import { Button } from "@/components/ui/button";
import { useTravellers, type Traveller } from "@/features/travellers/api";

export const Route = createFileRoute("/guests/")({
  head: () => ({
    meta: [
      { title: "Guests | KareVoyage Operations" },
      {
        name: "description",
        content: "Every traveller on file — with or without an app account.",
      },
      { property: "og:title", content: "Guests | KareVoyage Operations" },
      { property: "og:description", content: "Search and manage every KareVoyage traveller." },
    ],
  }),
  component: GuestsPage,
});

/**
 * Grid columns mirror what a guest record actually holds. Membership, points and profile
 * completion are deliberately absent: those belong to the rewards module, which doesn't exist —
 * showing empty columns for them would imply data that was never captured.
 */
const gridColumns: GridColumn<Traveller>[] = [
  {
    key: "fullName",
    header: "Name",
    width: 190,
    frozen: true,
    validate: validators.required("Name"),
  },
  { key: "phone", header: "Phone", width: 140, validate: validators.phone },
  { key: "email", header: "Email", width: 210, validate: validators.email },
  {
    key: "dateOfBirth",
    header: "Date of birth",
    width: 130,
    type: "date",
    validate: validators.date,
  },
  { key: "gender", header: "Gender", width: 110 },
  { key: "city", header: "City", width: 130 },
  { key: "state", header: "State", width: 130 },
  { key: "pincode", header: "PIN", width: 90 },
  { key: "nationality", header: "Nationality", width: 130 },
  { key: "isActive", header: "Active", width: 90, type: "boolean" },
];

function GuestsPage() {
  const navigate = useNavigate();
  const [formOpen, setFormOpen] = useState(false);
  const { data, isLoading } = useTravellers({ limit: 100 });
  const guests = data?.rows ?? [];

  const columns: TableColumn<Traveller>[] = [
    {
      key: "guest",
      header: "Guest",
      sortValue: (g) => g.fullName,
      cell: (g) => (
        <div className="flex items-center gap-3">
          <Avatar name={g.fullName} />
          <div className="min-w-0">
            <p className="flex items-center gap-1.5 truncate font-medium">
              {g.fullName}
              {g.hasAppAccount ? (
                <span
                  title="Also has an app account"
                  className="inline-flex items-center gap-1 rounded-md bg-primary-soft px-1.5 py-0.5 text-[10px] font-medium text-accent-foreground"
                >
                  <Smartphone className="h-2.5 w-2.5" /> app
                </span>
              ) : null}
            </p>
            <p className="truncate text-xs text-muted-foreground">
              {[g.city, g.nationality].filter(Boolean).join(" · ") || "No address on file"}
            </p>
          </div>
        </div>
      ),
    },
    {
      key: "contact",
      header: "Contact",
      responsive: "hidden lg:table-cell",
      sortValue: (g) => g.phone ?? "",
      cell: (g) => (
        <div className="min-w-0">
          <p className="truncate text-sm">{g.phone ?? "—"}</p>
          <p className="truncate text-xs text-muted-foreground">{g.email ?? "No email"}</p>
        </div>
      ),
    },
    {
      key: "age",
      header: "Age",
      align: "right",
      sortValue: (g) => g.age ?? -1,
      /** Computed from date of birth server-side. A blank age means the DOB was never captured,
       * which the manifest also flags — it's needed for fares and documentation. */
      cell: (g) => (g.age != null ? g.age : <span className="text-muted-foreground">—</span>),
    },
    {
      key: "dob",
      header: "Date of birth",
      responsive: "hidden xl:table-cell",
      sortValue: (g) => g.dateOfBirth ?? "",
      cell: (g) => (g.dateOfBirth ? formatDate(g.dateOfBirth) : "—"),
    },
    {
      key: "account",
      header: "App account",
      responsive: "hidden xl:table-cell",
      sortValue: (g) => (g.hasAppAccount ? "1" : "0"),
      cell: (g) => <StatusPill value={g.hasAppAccount ? "Yes" : "No"} />,
    },
    {
      key: "status",
      header: "Status",
      sortValue: (g) => (g.isActive ? "Active" : "Inactive"),
      cell: (g) => <StatusPill value={g.isActive ? "Active" : "Inactive"} />,
    },
  ];

  return (
    <>
      <ListPage
        title="Guests"
        description="Everyone who travels with you — most booked over the phone, with no app account at all."
        countLabel={(n) => (isLoading ? "Loading…" : `${n} guests`)}
        searchPlaceholder="Search name, phone or email…"
        actions={<Button onClick={() => setFormOpen(true)}>Add guest</Button>}
        rows={guests}
        columns={columns}
        getId={(g) => g.id}
        searchText={(g) => `${g.fullName} ${g.phone ?? ""} ${g.email ?? ""} ${g.city ?? ""}`}
        filters={[
          { key: "city", label: "City", get: (g) => g.city ?? "" },
          { key: "account", label: "App account", get: (g) => (g.hasAppAccount ? "Yes" : "No") },
          { key: "status", label: "Status", get: (g) => (g.isActive ? "Active" : "Inactive") },
        ]}
        onRowClick={(g) => navigate({ to: "/guests/$id", params: { id: g.id } })}
        rowActions={[
          {
            label: "Open profile",
            onSelect: (g) => navigate({ to: "/guests/$id", params: { id: g.id } }),
          },
        ]}
        cardRender={(g) => (
          <div className="flex items-center gap-3">
            <Avatar name={g.fullName} />
            <div className="min-w-0">
              <p className="truncate font-medium">{g.fullName}</p>
              <p className="truncate text-xs text-muted-foreground">
                {[g.phone, g.age != null ? `${g.age} yrs` : null].filter(Boolean).join(" · ")}
              </p>
            </div>
          </div>
        )}
        gridColumns={gridColumns}
        gridModule="Guests"
        emptyTitle={isLoading ? "Loading guests…" : "No guests yet"}
        emptyMessage={
          isLoading
            ? ""
            : "Add a guest to get started — a name is all that's required, and no app account is needed."
        }
        emptyAction={
          isLoading ? undefined : <Button onClick={() => setFormOpen(true)}>Add guest</Button>
        }
      />
      <GuestFormSheet
        open={formOpen}
        onOpenChange={setFormOpen}
        onSaved={(g) => navigate({ to: "/guests/$id", params: { id: g.id } })}
      />
    </>
  );
}
