"use client";

import * as React from "react";
import Link from "next/link";
import { CalendarSearch, ChevronRight, Loader2, LogIn, LogOut, Users } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Input, Field } from "@/components/ui/input";
import { StatusBadge } from "@/components/ui/badge";
import { addDays, parseDay, dayKey, fmtDate, fmtRange } from "@/lib/dates";
import { fmtMoney } from "@/lib/format";
import { useReservationDrawer } from "@/components/reservations/reservation-drawer";
import type { CalApt, CalRes, CalBlock, CalPerms } from "./calendar-view";

const visualEnd = (r: CalRes) => (r.actualCheckOut && r.actualCheckOut < r.checkOut ? r.actualCheckOut : r.checkOut);

/** Mobile agenda: the next days as a scrollable list of arrivals, departures and free units. */
export function CalendarAgenda({ apartments, reservations, blocks, start, today, days = 10, perms }: { apartments: CalApt[]; reservations: CalRes[]; blocks: CalBlock[]; start: Date; today: string; days?: number; perms: CalPerms }) {
  const { open } = useReservationDrawer();
  const aptIds = new Set(apartments.map((a) => a.id));
  const list = Array.from({ length: days }, (_, i) => addDays(start, i));
  return (
    <div className="space-y-3">
      {list.map((d) => {
        const k = dayKey(d);
        const ins = reservations.filter((r) => aptIds.has(r.apartmentId) && r.checkIn === k && r.status !== "INQUIRY" && r.status !== "CANCELLED");
        const outs = reservations.filter((r) => aptIds.has(r.apartmentId) && visualEnd(r) === k && r.status !== "INQUIRY" && r.status !== "CANCELLED");
        const free = apartments.filter((a) => !reservations.some((r) => r.apartmentId === a.id && ["CONFIRMED", "CHECKED_IN", "PENDING"].includes(r.status) && parseDay(r.checkIn) <= d && parseDay(r.checkOut) > d) && !blocks.some((b) => b.apartmentId === a.id && parseDay(b.startDate) <= d && parseDay(b.endDate) > d));
        return (
          <section key={k} className={cn("rounded-xl border bg-surface shadow-xs", k === today ? "border-primary/40" : "border-border")}>
            <header className="flex items-center justify-between px-4 pt-3 pb-2">
              <h3 className="text-sm font-semibold">
                {fmtDate(d, { style: "weekday" })}
                {k === today ? <span className="ml-2 rounded-full bg-primary/10 px-2 py-0.5 text-2xs text-primary">Today</span> : null}
              </h3>
              <span className="text-2xs text-fg-muted">
                {ins.length} in · {outs.length} out · {free.length} free
              </span>
            </header>
            {ins.length === 0 && outs.length === 0 ? <p className="px-4 pb-3 text-xs text-fg-muted">No movements.</p> : null}
            <ul className="divide-y divide-border">
              {[...ins.map((r) => ({ r, kind: "in" as const })), ...outs.map((r) => ({ r, kind: "out" as const }))].map(({ r, kind }) => (
                <li key={`${kind}-${r.id}`}>
                  <button type="button" onClick={() => open(r.id)} className="flex w-full items-center gap-3 px-4 py-2 text-left active:bg-surface-2">
                    <span className={cn("flex size-8 shrink-0 items-center justify-center rounded-full", kind === "in" ? "bg-brand-50 text-brand-700 dark:bg-brand-500/10 dark:text-brand-300" : "bg-surface-2 text-fg-muted")}>{kind === "in" ? <LogIn className="size-4" /> : <LogOut className="size-4" />}</span>
                    <span className="min-w-0 flex-1">
                      <span className="block truncate text-sm font-medium">
                        {apartments.find((a) => a.id === r.apartmentId)?.code} · {r.customer.fullName}
                      </span>
                      <span className="block text-2xs text-fg-muted">
                        {fmtRange(r.checkIn, visualEnd(r))} · {r.adults + r.children} guests
                      </span>
                    </span>
                    <StatusBadge status={r.status} size="sm" />
                  </button>
                </li>
              ))}
            </ul>
            {free.length ? (
              <div className="flex flex-wrap gap-1 px-4 pb-3 pt-1">
                {free.map((a) => (
                  <Link key={a.id} href={perms.create ? `/reservations/new?apartment=${a.id}&checkIn=${k}&checkOut=${dayKey(addDays(d, 1))}` : `/apartments/${a.id}`} className="rounded-md border border-positive-500/30 bg-positive-50 px-2 py-0.5 font-mono text-2xs font-semibold text-positive-700 dark:bg-positive-500/10">
                    {a.code}
                  </Link>
                ))}
              </div>
            ) : null}
          </section>
        );
      })}
    </div>
  );
}

/** Per-apartment strip for phones: each apartment as a row of the next 14 nights. */
export function ApartmentStrips({ apartments, reservations, blocks, start, today }: { apartments: CalApt[]; reservations: CalRes[]; blocks: CalBlock[]; start: Date; today: string }) {
  const { open } = useReservationDrawer();
  const days = Array.from({ length: 14 }, (_, i) => addDays(start, i));
  return (
    <div className="space-y-2">
      <div className="flex items-center gap-1 pl-16 text-[9px] text-fg-subtle">
        {days.map((d) => (
          <span key={dayKey(d)} className={cn("flex-1 text-center", dayKey(d) === today && "font-bold text-primary")}>
            {d.getUTCDate()}
          </span>
        ))}
      </div>
      {apartments.map((a) => (
        <div key={a.id} className="flex items-center gap-1 rounded-lg border border-border bg-surface px-2 py-1.5">
          <Link href={`/apartments/${a.id}`} className="w-14 shrink-0 font-mono text-xs font-semibold">
            {a.code}
          </Link>
          {days.map((d) => {
            const k = dayKey(d);
            const r = reservations.find((x) => x.apartmentId === a.id && ["CONFIRMED", "PENDING", "CHECKED_IN"].includes(x.status) && x.checkIn <= k && visualEnd(x) > k);
            const b = !r && blocks.find((x) => x.apartmentId === a.id && x.startDate <= k && x.endDate > k);
            return (
              <button key={k} type="button" onClick={() => r && open(r.id)} className={cn("h-6 flex-1 rounded-[3px]", r ? (r.status === "CHECKED_IN" ? "bg-info-500" : r.status === "PENDING" ? "bg-warning-500" : "bg-positive-500") : b ? (b.type === "HOLD" ? "bg-warning-500/40" : "bg-negative-500/70") : "bg-surface-3", k === today && "ring-1 ring-primary")} aria-label={r ? `${r.customer.fullName}` : b ? "blocked" : "free"} />
            );
          })}
        </div>
      ))}
    </div>
  );
}

/** Mobile availability search: dates + guests → free apartments with price. */
export function AvailabilitySearch({ today, perms, currency }: { today: string; perms: CalPerms; currency: string }) {
  const [checkIn, setCheckIn] = React.useState(today);
  const [checkOut, setCheckOut] = React.useState(dayKey(addDays(parseDay(today), 1)));
  const [guests, setGuests] = React.useState(2);
  const [loading, setLoading] = React.useState(false);
  const [items, setItems] = React.useState<{ id: string; code: string; name: string; maxGuests: number; bedrooms: number; available: boolean; conflicts: { label: string }[]; pricing: { nights: number; subtotal: number; nightlyPrice: number } }[] | null>(null);
  async function search() {
    setLoading(true);
    try {
      const r = await fetch(`/api/availability?checkIn=${checkIn}&checkOut=${checkOut}`);
      if (r.ok) setItems(((await r.json()) as { items: typeof items }).items);
    } finally {
      setLoading(false);
    }
  }
  const fits = (a: NonNullable<typeof items>[number]) => a.available && a.maxGuests >= guests;
  return (
    <div className="space-y-3">
      <div className="rounded-xl border border-border bg-surface p-3 shadow-xs">
        <div className="grid grid-cols-2 gap-2">
          <Field label="Check-in">
            <Input type="date" value={checkIn} onChange={(e) => setCheckIn(e.target.value)} className="h-11 text-base" />
          </Field>
          <Field label="Check-out">
            <Input type="date" value={checkOut} min={checkIn} onChange={(e) => setCheckOut(e.target.value)} className="h-11 text-base" />
          </Field>
          <Field label="Guests">
            <Input type="number" min={1} max={12} value={guests} onChange={(e) => setGuests(Number(e.target.value) || 1)} className="h-11 text-base" />
          </Field>
          <div className="flex items-end">
            <Button className="h-11 w-full" onClick={search} loading={loading}>
              <CalendarSearch /> Search
            </Button>
          </div>
        </div>
      </div>
      {loading ? (
        <p className="flex items-center gap-2 text-sm text-fg-muted">
          <Loader2 className="size-4 animate-spin" /> Checking availability…
        </p>
      ) : items ? (
        items.filter(fits).length === 0 ? (
          <p className="rounded-xl border border-dashed border-border p-4 text-center text-sm text-fg-muted">Nothing free for {fmtRange(checkIn, checkOut)} with {guests} guest{guests > 1 ? "s" : ""}.{items.some((a) => a.available) ? " Try fewer guests." : ""}</p>
        ) : (
          <ul className="space-y-2">
            {items.filter(fits).map((a) => (
              <li key={a.id}>
                <Link href={perms.create ? `/reservations/new?apartment=${a.id}&checkIn=${checkIn}&checkOut=${checkOut}` : `/apartments/${a.id}`} className="flex items-center gap-3 rounded-xl border border-positive-500/30 bg-surface p-3 shadow-xs active:bg-surface-2">
                  <span className="flex size-11 items-center justify-center rounded-lg bg-positive-50 font-mono text-sm font-bold text-positive-700 dark:bg-positive-500/10">{a.code}</span>
                  <span className="min-w-0 flex-1">
                    <span className="block truncate text-sm font-semibold">{a.name}</span>
                    <span className="flex items-center gap-2 text-2xs text-fg-muted">
                      <Users className="size-3" /> up to {a.maxGuests} · {a.bedrooms || "studio"} · {a.pricing.nights} night{a.pricing.nights > 1 ? "s" : ""}
                    </span>
                  </span>
                  {perms.money ? <span className="text-sm font-semibold tabular">{fmtMoney(a.pricing.subtotal, currency, { whole: true })}</span> : null}
                  <ChevronRight className="size-4 text-fg-subtle" />
                </Link>
              </li>
            ))}
            {items.filter((a) => !fits(a)).length ? <li className="px-1 pt-1 text-2xs text-fg-subtle">{items.filter((a) => !a.available).length} unavailable · {items.filter((a) => a.available && a.maxGuests < guests).length} too small</li> : null}
          </ul>
        )
      ) : null}
    </div>
  );
}
