import { useState } from "react";
import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import { ArrowLeft, Crown, Phone, Plus, Smartphone, Trash2, TriangleAlert } from "lucide-react";
import { toast } from "sonner";

import { GuestDocumentsPanel } from "@/components/app/GuestDocumentsPanel";
import { GuestFormSheet } from "@/components/app/GuestFormSheet";
import { GuestProfileHeader, GuestStatTiles } from "@/components/app/GuestProfileHeader";
import { GuestPreferencesPanel } from "@/components/app/GuestPreferencesPanel";
import { Page } from "@/components/app/Page";
import {
  Avatar,
  DetailRow,
  EmptyState,
  SectionHeading,
  formatDate,
  formatINR,
} from "@/components/app/Primitives";
import { StatusPill } from "@/components/app/StatusPill";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { useDropdownOptions } from "@/features/master-types/api";
import {
  useCreateEmergencyContact,
  useDeleteEmergencyContact,
  useEmergencyContacts,
  useTraveller,
  useTravellerBookings,
  useTravellerCompanions,
  useTravellerDocuments,
  useTravellerPreferences,
  type Traveller,
} from "@/features/travellers/api";
import { ApiClientError } from "@/lib/api";
import { useBreadcrumbLabel } from "@/lib/breadcrumb-label";

export const Route = createFileRoute("/guests/$id")({
  head: () => ({
    meta: [{ title: "Guest | KareVoyage Operations" }],
  }),
  component: GuestDetail,
});

const titleCase = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);

/** Resolves a stored dropdown value back to its friendly label, falling back to the raw value if
 * the option was later renamed — same treatment the tour and trip pages give these. */
function OptionLabel({ groupKey, value }: { groupKey: string; value: string | null }) {
  const { data: options } = useDropdownOptions(groupKey);
  if (!value) return <>—</>;
  return <>{options?.find((o) => o.value === value)?.label ?? value}</>;
}

function EmergencyContactsPanel({ travellerId }: { travellerId: string }) {
  const { data: contacts = [], isLoading } = useEmergencyContacts(travellerId);
  const { data: relationOptions = [] } = useDropdownOptions("relationship");
  const create = useCreateEmergencyContact(travellerId);
  const remove = useDeleteEmergencyContact(travellerId);
  const [draft, setDraft] = useState({ name: "", phone: "", relationship: "", isPrimary: false });

  const add = () => {
    if (
      draft.name.trim().length < 2 ||
      draft.phone.trim().length < 6 ||
      !draft.relationship.trim()
    ) {
      toast.error("Name, phone and relationship are all needed.");
      return;
    }
    create.mutate(
      {
        name: draft.name.trim(),
        phone: draft.phone.trim(),
        relationship: draft.relationship.trim(),
        isPrimary: contacts.length === 0 || draft.isPrimary,
      },
      {
        onSuccess: () => {
          toast.success("Contact added.");
          setDraft({ name: "", phone: "", relationship: "", isPrimary: false });
        },
        onError: (err) =>
          toast.error(err instanceof ApiClientError ? err.message : "Couldn't add the contact."),
      },
    );
  };

  return (
    <div className="space-y-4">
      <SectionHeading
        title="Emergency contacts"
        description="Who to call. For this age group the trip manifest treats a missing contact like a missing document."
      />

      {isLoading ? (
        <p className="text-sm text-muted-foreground">Loading…</p>
      ) : contacts.length === 0 ? (
        <div className="flex items-start gap-2.5 rounded-lg bg-warning/10 px-3.5 py-3 text-xs leading-relaxed text-warning-foreground">
          <TriangleAlert className="mt-0.5 h-3.5 w-3.5 shrink-0" />
          <span>No emergency contact on file. Add one before this guest travels.</span>
        </div>
      ) : (
        <ul className="divide-y divide-border rounded-xl border border-border bg-surface">
          {contacts.map((ct) => (
            <li key={ct.id} className="flex items-center justify-between gap-3 px-4 py-3">
              <div className="min-w-0">
                <p className="flex items-center gap-2 text-sm font-medium">
                  {ct.name}
                  {ct.isPrimary ? (
                    <span className="inline-flex items-center gap-1 rounded-md bg-primary-soft px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-accent-foreground">
                      <Crown className="h-2.5 w-2.5" /> Primary
                    </span>
                  ) : null}
                </p>
                <p className="text-xs text-muted-foreground">
                  <OptionLabel groupKey="relationship" value={ct.relationship} /> · {ct.phone}
                </p>
              </div>
              <Button
                variant="ghost"
                size="icon"
                className="h-7 w-7 text-destructive hover:text-destructive"
                aria-label={`Remove ${ct.name}`}
                onClick={() =>
                  remove.mutate(ct.id, {
                    onSuccess: () => toast.success("Contact removed."),
                    onError: () => toast.error("Couldn't remove the contact."),
                  })
                }
              >
                <Trash2 className="h-3.5 w-3.5" />
              </Button>
            </li>
          ))}
        </ul>
      )}

      <div className="grid gap-2.5 rounded-xl border border-border bg-surface p-4 sm:grid-cols-4">
        <div className="space-y-1.5">
          <Label htmlFor="ec-name" className="kv-eyebrow">
            Name
          </Label>
          <Input
            id="ec-name"
            value={draft.name}
            onChange={(e) => setDraft((d) => ({ ...d, name: e.target.value }))}
            placeholder="e.g. Amit Sharma"
          />
        </div>
        <div className="space-y-1.5">
          <Label htmlFor="ec-phone" className="kv-eyebrow">
            Phone
          </Label>
          <Input
            id="ec-phone"
            value={draft.phone}
            onChange={(e) => setDraft((d) => ({ ...d, phone: e.target.value }))}
            placeholder="98765 43210"
          />
        </div>
        <div className="space-y-1.5">
          <Label htmlFor="ec-rel" className="kv-eyebrow">
            Relationship
          </Label>
          <select
            id="ec-rel"
            value={draft.relationship}
            onChange={(e) => setDraft((d) => ({ ...d, relationship: e.target.value }))}
            className="h-9 w-full rounded-md border border-input bg-transparent px-3 text-sm"
          >
            <option value="">Select…</option>
            {relationOptions.map((o) => (
              <option key={o.id} value={o.value}>
                {o.label}
              </option>
            ))}
          </select>
        </div>
        <div className="flex items-end">
          <Button className="w-full gap-1.5" disabled={create.isPending} onClick={add}>
            <Plus className="h-3.5 w-3.5" /> Add
          </Button>
        </div>
      </div>
    </div>
  );
}

/** Every trip this person has been on, in either role, with the relation used that time. */
function TripsPanel({ travellerId }: { travellerId: string }) {
  const { data: history = [], isLoading } = useTravellerBookings(travellerId);
  const { data: companions = [] } = useTravellerCompanions(travellerId);
  const { data: relationOptions = [] } = useDropdownOptions("relationship");
  const relLabel = (v: string | null) =>
    v ? (relationOptions.find((o) => o.value === v)?.label ?? v) : null;

  if (isLoading) return <p className="text-sm text-muted-foreground">Loading trips…</p>;

  return (
    <div className="space-y-8">
      <div>
        <SectionHeading
          title="Trips"
          description="As the lead who booked, or as someone else's companion."
        />
        {history.length === 0 ? (
          <EmptyState title="No trips yet" message="This guest hasn't been booked on a trip." />
        ) : (
          <ul className="divide-y divide-border rounded-xl border border-border bg-surface">
            {history.map((h) => (
              <li
                key={h.bookingId}
                className="flex flex-wrap items-center justify-between gap-3 px-4 py-3"
              >
                <div className="min-w-0">
                  <p className="truncate text-sm font-medium">
                    <Link to="/trips/$id" params={{ id: h.tripId }} className="hover:underline">
                      {h.tripTitle || h.tripTourTitle}
                    </Link>
                  </p>
                  <p className="truncate text-xs text-muted-foreground">
                    {h.tripCode} · {h.tripDestination} · {formatDate(h.tripDepartureDate)} →{" "}
                    {formatDate(h.tripReturnDate)}
                  </p>
                </div>
                <div className="flex items-center gap-2 text-xs">
                  {h.isLead ? (
                    <span className="inline-flex items-center gap-1 rounded-md bg-primary-soft px-1.5 py-0.5 font-semibold uppercase tracking-wide text-accent-foreground">
                      <Crown className="h-2.5 w-2.5" /> Lead
                    </span>
                  ) : (
                    <span className="text-muted-foreground">
                      {relLabel(h.relationToLead) ?? "Companion"} of {h.leadTravellerName}
                    </span>
                  )}
                  {h.price ? (
                    <span className="tabular-nums">{formatINR(Number(h.price))}</span>
                  ) : null}
                  <StatusPill
                    value={titleCase(
                      h.travellerStatus === "cancelled" ? "cancelled" : h.tripDisplayStatus,
                    )}
                  />
                </div>
              </li>
            ))}
          </ul>
        )}
      </div>

      {companions.length > 0 ? (
        <div>
          <SectionHeading
            title="Usually travels with"
            description="Built from real bookings, in either direction — offered first when this guest books again."
          />
          <ul className="divide-y divide-border rounded-xl border border-border bg-surface">
            {companions.map((cm) => (
              <li
                key={cm.travellerId}
                className="flex items-center justify-between gap-3 px-4 py-2.5"
              >
                <div className="min-w-0">
                  <p className="truncate text-sm">
                    <Link
                      to="/guests/$id"
                      params={{ id: cm.travellerId }}
                      className="hover:underline"
                    >
                      {cm.fullName}
                    </Link>
                  </p>
                  <p className="text-xs text-muted-foreground">
                    {relLabel(cm.lastRelationToThisLead) ?? "Relation not recorded this way round"}
                  </p>
                </div>
                <p className="shrink-0 text-xs text-muted-foreground">
                  {cm.timesTravelledTogether} trip{cm.timesTravelledTogether === 1 ? "" : "s"}{" "}
                  together
                  {cm.lastTravelledWithAt ? ` · last ${formatDate(cm.lastTravelledWithAt)}` : ""}
                </p>
              </li>
            ))}
          </ul>
        </div>
      ) : null}
    </div>
  );
}

function GuestDetail() {
  const { id } = Route.useParams();
  const { data: guest, isLoading, isError } = useTraveller(id);

  if (isLoading) {
    return (
      <Page>
        <p className="text-sm text-muted-foreground">Loading guest…</p>
      </Page>
    );
  }

  if (isError || !guest) {
    return (
      <Page>
        <EmptyState
          title="Guest not found"
          message="This guest doesn't exist or may have been removed."
          action={
            <Button asChild>
              <Link to="/guests">Back to guests</Link>
            </Button>
          }
        />
      </Page>
    );
  }

  return <GuestDetailView guest={guest} />;
}

function GuestDetailView({ guest }: { guest: Traveller }) {
  const navigate = useNavigate();
  const [editOpen, setEditOpen] = useState(false);
  useBreadcrumbLabel(guest.fullName);
  const { data: history = [] } = useTravellerBookings(guest.id);
  const { data: contacts = [] } = useEmergencyContacts(guest.id);
  const { data: documents = [] } = useTravellerDocuments(guest.id);
  const { data: preferences } = useTravellerPreferences(guest.id);

  return (
    <Page className="space-y-6">
      <button
        type="button"
        onClick={() => navigate({ to: "/guests" })}
        className="inline-flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground"
      >
        <ArrowLeft className="h-3.5 w-3.5" /> All guests
      </button>

      <GuestProfileHeader
        guest={guest}
        documents={documents}
        preferences={preferences}
        contacts={contacts}
        onEdit={() => setEditOpen(true)}
      />

      <GuestStatTiles documents={documents} history={history} contacts={contacts} />

      <Tabs defaultValue="overview">
        <TabsList className="flex h-auto w-full flex-wrap justify-start gap-1 bg-transparent p-0">
          {[
            { value: "overview", label: "Overview" },
            { value: "documents", label: "Documents" },
            { value: "preferences", label: "Preferences & health" },
            { value: "contacts", label: "Emergency contacts" },
            { value: "trips", label: "Trips" },
          ].map((t) => (
            <TabsTrigger
              key={t.value}
              value={t.value}
              className="rounded-lg px-3 py-1.5 text-sm data-[state=active]:bg-primary-soft data-[state=active]:text-accent-foreground data-[state=active]:shadow-none"
            >
              {t.label}
            </TabsTrigger>
          ))}
        </TabsList>

        <TabsContent value="overview" className="mt-6 grid gap-6 lg:grid-cols-3">
          <div className="rounded-xl border border-border bg-surface p-5">
            <SectionHeading title="Personal" />
            <dl className="divide-y divide-border">
              <DetailRow
                label="Date of birth"
                value={guest.dateOfBirth ? formatDate(guest.dateOfBirth) : null}
              />
              <DetailRow label="Age" value={guest.age != null ? `${guest.age} years` : null} />
              <DetailRow
                label="Gender"
                value={<OptionLabel groupKey="gender" value={guest.gender} />}
              />
              <DetailRow label="Nationality" value={guest.nationality} />
              <DetailRow label="Added" value={formatDate(guest.createdAt)} />
            </dl>
          </div>
          <div className="rounded-xl border border-border bg-surface p-5">
            <SectionHeading title="Contact" />
            <dl className="divide-y divide-border">
              <DetailRow label="Phone" value={guest.phone} />
              <DetailRow label="Alternate" value={guest.alternatePhone} />
              <DetailRow label="Email" value={guest.email} />
              <DetailRow label="Address" value={guest.addressLine} />
              <DetailRow
                label="City"
                value={[guest.city, guest.state, guest.pincode].filter(Boolean).join(", ") || null}
              />
              <DetailRow label="Country" value={guest.country} />
            </dl>
          </div>
          <div className="rounded-xl border border-border bg-surface p-5">
            <SectionHeading title="Account & notes" />
            <dl className="divide-y divide-border">
              <DetailRow
                label="App account"
                value={<StatusPill value={guest.hasAppAccount ? "Yes" : "No"} />}
              />
              <DetailRow
                label="Status"
                value={<StatusPill value={guest.isActive ? "Active" : "Inactive"} />}
              />
            </dl>
            <p className="mt-3 whitespace-pre-wrap text-sm text-muted-foreground">
              {guest.notes || "No notes yet."}
            </p>
          </div>
        </TabsContent>

        <TabsContent value="documents" className="mt-6">
          <div className="rounded-xl border border-border bg-surface p-5">
            <GuestDocumentsPanel travellerId={guest.id} />
          </div>
        </TabsContent>

        <TabsContent value="preferences" className="mt-6">
          <div className="rounded-xl border border-border bg-surface p-5">
            <GuestPreferencesPanel travellerId={guest.id} />
          </div>
        </TabsContent>

        <TabsContent value="contacts" className="mt-6">
          <EmergencyContactsPanel travellerId={guest.id} />
        </TabsContent>

        <TabsContent value="trips" className="mt-6">
          <TripsPanel travellerId={guest.id} />
        </TabsContent>
      </Tabs>

      <GuestFormSheet open={editOpen} onOpenChange={setEditOpen} guest={guest} />
    </Page>
  );
}
