"use client";

import { useEffect, useMemo, useState } from "react";
import AdminShell from "@/shared/AdminShell";
import {
  useListReservationsQuery,
  useUpdateReservationMutation,
  useDeleteReservationMutation,
  type Reservation,
  type ReservationStatus,
} from "@/services/reservation-service";
import { getApiErrorMessage } from "@/utils/apiError";

const STATUS_OPTIONS: ReservationStatus[] = [
  "new",
  "confirmed",
  "completed",
  "cancelled",
];

const STATUS_STYLES: Record<ReservationStatus, string> = {
  new: "bg-blue-50 text-blue-700 border-blue-200",
  confirmed: "bg-green-50 text-green-700 border-green-200",
  completed: "bg-gray-100 text-gray-700 border-gray-200",
  cancelled: "bg-red-50 text-red-700 border-red-200",
};

function formatDate(value: string): string {
  if (!value) return "";
  const d = new Date(value);
  if (Number.isNaN(d.getTime())) return value;
  return d.toLocaleDateString("en-US", {
    year: "numeric",
    month: "short",
    day: "numeric",
  });
}

export default function AdminReservationsPage() {
  const [statusFilter, setStatusFilter] = useState<ReservationStatus | "">("");
  const [q, setQ] = useState("");
  const [debouncedQ, setDebouncedQ] = useState("");
  const [page, setPage] = useState(1);
  const [actionError, setActionError] = useState("");
  const [activeId, setActiveId] = useState<number | null>(null);

  useEffect(() => {
    const t = setTimeout(() => setDebouncedQ(q.trim()), 350);
    return () => clearTimeout(t);
  }, [q]);

  const { data, error, isFetching } = useListReservationsQuery({
    page,
    limit: 20,
    status: statusFilter || undefined,
    q: debouncedQ || undefined,
  });
  const [updateReservation] = useUpdateReservationMutation();
  const [deleteReservation] = useDeleteReservationMutation();

  const fetchErrorMsg = error ? getApiErrorMessage(error, "Failed to load reservations") : "";

  const totalPages = useMemo(
    () => (data ? Math.max(1, Math.ceil(data.total / data.limit)) : 1),
    [data],
  );

  const handleStatusChange = async (id: number, newStatus: ReservationStatus) => {
    setActionError("");
    try {
      await updateReservation({ id, status: newStatus }).unwrap();
    } catch (err) {
      setActionError(getApiErrorMessage(err, "Status update failed"));
    }
  };

  const handleDelete = async (id: number) => {
    if (!confirm("Delete this reservation? This cannot be undone.")) return;
    setActionError("");
    try {
      await deleteReservation(id).unwrap();
      if (activeId === id) setActiveId(null);
    } catch (err) {
      setActionError(getApiErrorMessage(err, "Delete failed"));
    }
  };

  return (
    <AdminShell>
      <div className="mb-8 flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
        <div>
          <p className="text-[10px] uppercase tracking-[0.3em] text-[#d6ac63]">
            Manage
          </p>
          <h1 className="mt-2 text-2xl lg:text-3xl font-light text-black">
            Reservations
          </h1>
          <p className="mt-2 text-sm text-gray-600 font-light">
            {data ? `${data.total} reservation${data.total === 1 ? "" : "s"}` : ""}
          </p>
        </div>
        <div className="flex flex-col gap-3 sm:flex-row">
          <input
            type="search"
            placeholder="Search name, email, property…"
            value={q}
            onChange={(e) => {
              setPage(1);
              setQ(e.target.value);
            }}
            className="border border-[#d6ac63]/30 bg-white px-4 py-2.5 text-sm focus:border-[#d6ac63] focus:outline-none w-full sm:w-72"
          />
          <select
            value={statusFilter}
            onChange={(e) => {
              setPage(1);
              setStatusFilter(e.target.value as ReservationStatus | "");
            }}
            className="border border-[#d6ac63]/30 bg-white px-4 py-2.5 text-sm uppercase tracking-wide text-gray-700 focus:border-[#d6ac63] focus:outline-none"
          >
            <option value="">All statuses</option>
            {STATUS_OPTIONS.map((s) => (
              <option key={s} value={s}>
                {s}
              </option>
            ))}
          </select>
        </div>
      </div>

      {(fetchErrorMsg || actionError) ? (
        <p className="mb-4 text-sm text-red-500">{fetchErrorMsg || actionError}</p>
      ) : null}

      <div className="border border-[#d6ac63]/15 bg-white overflow-x-auto">
        <table className="min-w-full text-sm">
          <thead className="bg-[#fbf7f0] text-[10px] uppercase tracking-[0.2em] text-gray-600">
            <tr>
              <th className="px-4 py-3 text-left">Guest</th>
              <th className="px-4 py-3 text-left">Property</th>
              <th className="px-4 py-3 text-left">Dates</th>
              <th className="px-4 py-3 text-left">Guests</th>
              <th className="px-4 py-3 text-left">Status</th>
              <th className="px-4 py-3 text-left">Created</th>
              <th className="px-4 py-3 text-right">Actions</th>
            </tr>
          </thead>
          <tbody>
            {isFetching ? (
              <tr>
                <td colSpan={7} className="px-4 py-10 text-center text-gray-500">
                  Loading…
                </td>
              </tr>
            ) : !data || data.reservations.length === 0 ? (
              <tr>
                <td colSpan={7} className="px-4 py-10 text-center text-gray-500">
                  No reservations found.
                </td>
              </tr>
            ) : (
              data.reservations.map((r) => (
                <ReservationRow
                  key={r.id}
                  reservation={r}
                  isOpen={activeId === r.id}
                  onToggle={() => setActiveId((prev) => (prev === r.id ? null : r.id))}
                  onChangeStatus={(s) => handleStatusChange(r.id, s)}
                  onDelete={() => handleDelete(r.id)}
                />
              ))
            )}
          </tbody>
        </table>
      </div>

      {data && data.total > data.limit ? (
        <div className="mt-6 flex items-center justify-between text-xs text-gray-600">
          <span>
            Page {data.page} of {totalPages}
          </span>
          <div className="flex gap-2">
            <button
              type="button"
              disabled={data.page <= 1}
              onClick={() => setPage((p) => Math.max(1, p - 1))}
              className="border border-[#d6ac63]/30 px-4 py-2 uppercase tracking-wide disabled:opacity-40"
            >
              Prev
            </button>
            <button
              type="button"
              disabled={data.page >= totalPages}
              onClick={() => setPage((p) => p + 1)}
              className="border border-[#d6ac63]/30 px-4 py-2 uppercase tracking-wide disabled:opacity-40"
            >
              Next
            </button>
          </div>
        </div>
      ) : null}
    </AdminShell>
  );
}

function ReservationRow({
  reservation: r,
  isOpen,
  onToggle,
  onChangeStatus,
  onDelete,
}: {
  reservation: Reservation;
  isOpen: boolean;
  onToggle: () => void;
  onChangeStatus: (s: ReservationStatus) => void;
  onDelete: () => void;
}) {
  return (
    <>
      <tr className="border-t border-[#d6ac63]/10 hover:bg-[#fbf7f0]/50">
        <td className="px-4 py-3">
          <p className="font-light text-black">{r.full_name}</p>
          <p className="text-xs text-gray-500">{r.email}</p>
        </td>
        <td className="px-4 py-3 text-gray-700">{r.property}</td>
        <td className="px-4 py-3 text-gray-700 whitespace-nowrap">
          {formatDate(r.check_in)} – {formatDate(r.check_out)}
        </td>
        <td className="px-4 py-3 text-gray-700">{r.guests}</td>
        <td className="px-4 py-3">
          <span
            className={`inline-flex items-center border px-2.5 py-1 text-[10px] uppercase tracking-[0.15em] ${STATUS_STYLES[r.status]}`}
          >
            {r.status}
          </span>
        </td>
        <td className="px-4 py-3 text-gray-500 text-xs whitespace-nowrap">
          {formatDate(r.created_at)}
        </td>
        <td className="px-4 py-3 text-right">
          <button
            type="button"
            onClick={onToggle}
            className="text-[10px] uppercase tracking-[0.2em] text-[#d6ac63] hover:underline"
          >
            {isOpen ? "Hide" : "Manage"}
          </button>
        </td>
      </tr>
      {isOpen ? (
        <tr className="border-t border-[#d6ac63]/10 bg-[#fbf7f0]/30">
          <td colSpan={7} className="px-4 py-5">
            <div className="grid gap-4 lg:grid-cols-3">
              <div>
                <p className="text-[10px] uppercase tracking-[0.2em] text-gray-500">Contact</p>
                <p className="mt-1 text-sm">{r.email}</p>
                <p className="text-sm">{r.phone}</p>
              </div>
              <div className="lg:col-span-2">
                <p className="text-[10px] uppercase tracking-[0.2em] text-gray-500">Message</p>
                <p className="mt-1 text-sm whitespace-pre-wrap text-gray-700">
                  {r.message?.trim() || "—"}
                </p>
              </div>
            </div>
            <div className="mt-5 flex flex-wrap items-center gap-3">
              <label className="text-[10px] uppercase tracking-[0.2em] text-gray-500">
                Set status
              </label>
              <select
                value={r.status}
                onChange={(e) => onChangeStatus(e.target.value as ReservationStatus)}
                className="border border-[#d6ac63]/30 bg-white px-3 py-2 text-xs uppercase tracking-wide"
              >
                {STATUS_OPTIONS.map((s) => (
                  <option key={s} value={s}>
                    {s}
                  </option>
                ))}
              </select>
              <button
                type="button"
                onClick={onDelete}
                className="ml-auto text-[10px] uppercase tracking-[0.2em] text-red-600 hover:text-red-700"
              >
                Delete
              </button>
            </div>
          </td>
        </tr>
      ) : null}
    </>
  );
}
