"use client";

import * as React from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { Check, Play, Sparkles, UserRound } from "lucide-react";
import { cn } from "@/lib/utils";
import { PageHeader } from "@/components/ui/page-header";
import { Button } from "@/components/ui/button";
import { NativeSelect } from "@/components/ui/input";
import { StatusBadge, StatusDot } from "@/components/ui/badge";
import { Card, CardHeader, CardContent } from "@/components/ui/card";
import { EmptyState } from "@/components/ui/states";
import { KpiCard } from "@/components/ui/kpi-card";
import { fmtDate, fmtDateTime, parseDay } from "@/lib/dates";
import { CLEANING_STATUS_META } from "@/lib/domain";
import { setCleaningStatus } from "@/lib/actions/apartments";
import { assignCleaning } from "@/lib/actions/operations";

interface Apt {
  id: string;
  code: string;
  name: string;
  status: string;
  cleaningStatus: string;
  building: string | null;
  next: { checkIn: string; guest: string } | null;
  task: { id: string; status: string; assigneeId: string | null; notes: string | null; reservationCode: string | null; scheduledFor: string | null; startedAt: string | null } | null;
}

export function CleaningBoard({ apartments, staff, upcoming, history, today, canManage, me }: { apartments: Apt[]; staff: { id: string; fullName: string; isCleaner: boolean }[]; upcoming: { id: string; code: string; checkOut: string; apartment: string; name: string; guest: string }[]; history: { id: string; apartment: string; completedAt: string; by: string; notes: string | null }[]; today: string; canManage: boolean; me: string }) {
  const router = useRouter();
  const [busy, setBusy] = React.useState<string | null>(null);
  const needs = apartments.filter((a) => a.cleaningStatus === "NEEDS_CLEANING");
  const inProgress = apartments.filter((a) => a.cleaningStatus === "IN_PROGRESS");
  const ready = apartments.filter((a) => a.cleaningStatus === "READY" || a.cleaningStatus === "CLEAN");
  const arrivingToday = apartments.filter((a) => a.next?.checkIn === today && a.cleaningStatus !== "READY" && a.cleaningStatus !== "CLEAN");

  async function set(a: Apt, status: "IN_PROGRESS" | "READY" | "NEEDS_CLEANING") {
    setBusy(a.id);
    const res = await setCleaningStatus(a.id, status);
    setBusy(null);
    if (!res.ok) return toast.error(res.error);
    toast.success(`${a.code} · ${CLEANING_STATUS_META[status].label}`);
    router.refresh();
  }
  async function assign(a: Apt, userId: string) {
    if (!a.task) return;
    const res = await assignCleaning(a.task.id, userId || null);
    if (!res.ok) return toast.error(res.error);
    toast.success("Assigned");
    router.refresh();
  }

  const Column = ({ title, items, tone, empty }: { title: string; items: Apt[]; tone: "warning" | "info" | "positive"; empty: string }) => (
    <div className="flex flex-col rounded-lg border border-border bg-surface-2/50 p-2">
      <div className="mb-2 flex items-center justify-between px-1">
        <h3 className={cn("flex items-center gap-1.5 text-sm font-semibold", tone === "warning" && "text-warning-700", tone === "info" && "text-info-700", tone === "positive" && "text-positive-700")}>
          <StatusDot status={tone === "warning" ? "NEEDS_CLEANING" : tone === "info" ? "IN_PROGRESS" : "READY"} prefix="CLEAN_" /> {title}
        </h3>
        <span className="text-xs tabular text-fg-muted">{items.length}</span>
      </div>
      <div className="space-y-2">
        {items.length === 0 ? <p className="px-1 py-6 text-center text-xs text-fg-subtle">{empty}</p> : null}
        {items.map((a) => {
          const urgent = a.next?.checkIn === today;
          return (
            <div key={a.id} className={cn("rounded-md border bg-surface p-3 shadow-xs", urgent && a.cleaningStatus !== "READY" ? "border-negative-500/40" : "border-border")}>
              <div className="flex items-start justify-between gap-2">
                <Link href={`/apartments/${a.id}`} className="min-w-0">
                  <span className="flex items-center gap-2">
                    <span className="font-mono text-sm font-bold">{a.code}</span>
                    <span className="truncate text-sm">{a.name}</span>
                  </span>
                  <span className="block text-xs text-fg-muted">{a.building}</span>
                </Link>
                <StatusBadge status={a.status} size="sm" />
              </div>
              {a.task?.reservationCode ? <p className="mt-1.5 text-2xs text-fg-subtle">After {a.task.reservationCode}{a.task.notes ? ` · ${a.task.notes}` : ""}</p> : null}
              {a.next ? (
                <p className={cn("mt-1.5 text-xs", urgent ? "font-medium text-negative-600" : "text-fg-muted")}>
                  Next guest {a.next.checkIn === today ? "today" : fmtDate(parseDay(a.next.checkIn), { style: "weekday" })} · {a.next.guest}
                </p>
              ) : (
                <p className="mt-1.5 text-xs text-fg-subtle">No upcoming arrival</p>
              )}
              {a.task?.startedAt ? <p className="mt-1 text-2xs text-fg-subtle">Started {fmtDateTime(a.task.startedAt)}</p> : null}
              {canManage ? (
                <div className="mt-2.5 flex items-center gap-1.5">
                  {a.task ? (
                    <div className="relative min-w-0 flex-1">
                      <UserRound className="pointer-events-none absolute left-2 top-1/2 size-3.5 -translate-y-1/2 text-fg-subtle" />
                      <NativeSelect value={a.task.assigneeId ?? ""} onChange={(e) => assign(a, e.target.value)} className="h-8 pl-7 text-xs">
                        <option value="">Unassigned</option>
                        {staff.map((s) => (
                          <option key={s.id} value={s.id}>
                            {s.fullName}
                            {s.isCleaner ? " (housekeeping)" : ""}
                          </option>
                        ))}
                      </NativeSelect>
                    </div>
                  ) : (
                    <span className="flex-1" />
                  )}
                  {a.cleaningStatus === "NEEDS_CLEANING" ? (
                    <Button size="sm" variant="secondary" loading={busy === a.id} onClick={() => set(a, "IN_PROGRESS")}>
                      <Play /> Start
                    </Button>
                  ) : null}
                  {a.cleaningStatus === "NEEDS_CLEANING" || a.cleaningStatus === "IN_PROGRESS" ? (
                    <Button size="sm" loading={busy === a.id} onClick={() => set(a, "READY")}>
                      <Check /> Ready
                    </Button>
                  ) : (
                    <Button size="sm" variant="ghost" loading={busy === a.id} onClick={() => set(a, "NEEDS_CLEANING")}>
                      Needs cleaning
                    </Button>
                  )}
                </div>
              ) : null}
            </div>
          );
        })}
      </div>
    </div>
  );

  return (
    <div className="space-y-4">
      <PageHeader title="Cleaning" description="Turnover status of every apartment. Check-outs mark apartments as needing cleaning automatically." />
      <div className="grid grid-cols-2 gap-3 md:grid-cols-4">
        <KpiCard compact label="Needs cleaning" value={needs.length} tone={needs.length ? "warning" : "default"} icon={Sparkles} />
        <KpiCard compact label="In progress" value={inProgress.length} tone="info" />
        <KpiCard compact label="Ready" value={ready.length} tone="positive" />
        <KpiCard compact label="Arriving today, not ready" value={arrivingToday.length} tone={arrivingToday.length ? "negative" : "default"} hint="Apartments with a guest arriving today that are not yet ready." />
      </div>
      <div className="grid gap-3 lg:grid-cols-3">
        <Column title="Needs cleaning" items={needs} tone="warning" empty="All caught up" />
        <Column title="In progress" items={inProgress} tone="info" empty="No cleaning in progress" />
        <Column title="Ready" items={ready} tone="positive" empty="Nothing ready yet" />
      </div>
      <div className="grid gap-4 lg:grid-cols-2">
        <Card>
          <CardHeader title="Upcoming check-outs" description="Next 48 hours — plan turnovers ahead" />
          <CardContent>
            {upcoming.length === 0 ? (
              <EmptyState compact title="No check-outs in the next two days" />
            ) : (
              <ul className="divide-y divide-border">
                {upcoming.map((u) => (
                  <li key={u.id} className="flex items-center gap-3 py-2 text-sm">
                    <span className="w-16 text-xs text-fg-muted">{u.checkOut === today ? "Today" : fmtDate(parseDay(u.checkOut), { style: "weekday" })}</span>
                    <span className="font-mono text-xs font-semibold">{u.apartment}</span>
                    <Link href={`/reservations/${u.id}`} className="min-w-0 flex-1 truncate hover:text-primary">
                      {u.guest} <span className="text-fg-subtle">· {u.code}</span>
                    </Link>
                  </li>
                ))}
              </ul>
            )}
          </CardContent>
        </Card>
        <Card>
          <CardHeader title="Completed this week" />
          <CardContent>
            {history.length === 0 ? (
              <EmptyState compact title="No cleaning completed yet" />
            ) : (
              <ul className="divide-y divide-border">
                {history.map((h) => (
                  <li key={h.id} className="flex items-center gap-3 py-2 text-sm">
                    <span className="font-mono text-xs font-semibold">{h.apartment}</span>
                    <span className="min-w-0 flex-1 truncate text-fg-muted">
                      {h.by}
                      {h.notes ? ` · ${h.notes}` : ""}
                    </span>
                    <span className="text-xs text-fg-subtle">{fmtDateTime(h.completedAt)}</span>
                  </li>
                ))}
              </ul>
            )}
          </CardContent>
        </Card>
      </div>
      <p className="text-2xs text-fg-subtle">Signed in as {staff.find((s) => s.id === me)?.fullName}.</p>
    </div>
  );
}
