"use client";

import { useState, useEffect, ReactNode } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import StatusBadge from "@/components/StatusBadge";
import VerificationStamp from "@/components/VerificationStamp";
import { useToast, useConfirm, MessageThread } from "@/components/SharedUI";
import { formatPrice } from "@/lib/mock-data";
import { HomeIcon, BookmarkIcon, SearchIcon, MessageIcon, UserIcon } from "@/components/Icons";
import TablePagination, { usePagination } from "@/components/TablePagination";
import type { Property, RecentSearch, AccommodationBooking, ViewingRequest as ApiViewingRequest, Paginated } from "@/lib/types";
import ReviewsSection from "@/components/ReviewsSection";
import { clientExecute } from "@/lib/api/client";
import { ApiError } from "@/lib/api/shared";
import { useAuth } from "@/lib/auth-context";
import { Spinner } from "@/components/Loading";

// ─── Types ────────────────────────────────────────────────────────────────────
type Section = "overview" | "bookings" | "saved" | "searches" | "messages" | "profile";

interface ViewingRequest {
  id: string;
  propertyId: string;
  propertyTitle: string;
  address: string;
  status: "pending" | "confirmed" | "declined";
  date: string;
}

// Recent-search rows come back from the API with a `createdAt` timestamp;
// map to the display shape the UI expects.
function mapSearch(s: { id: string; term: string; filters?: string; results?: number; createdAt?: string }): RecentSearch {
  return {
    id: s.id,
    term: s.term,
    filters: s.filters ?? "",
    results: s.results ?? 0,
    date: s.createdAt ? new Date(s.createdAt).toLocaleDateString() : "",
  };
}

// ─── Primitives ───────────────────────────────────────────────────────────────
function SectionTitle({ children }: { children: ReactNode }) {
  return <h2 className="font-display font-semibold text-xl text-forest-deep mb-1">{children}</h2>;
}

function Card({ children, className = "" }: { children: ReactNode; className?: string }) {
  return <div className={`bg-white border border-mist rounded-md overflow-hidden ${className}`}>{children}</div>;
}

function CardHeader({ title, action }: { title: string; action?: ReactNode }) {
  return (
    <div className="flex flex-wrap justify-between items-center gap-3 px-5 py-4 border-b border-mist">
      <h3 className="font-display font-semibold text-lg">{title}</h3>
      {action}
    </div>
  );
}

function Btn({ children, onClick, variant = "primary", className = "" }: {
  children: ReactNode; onClick?: () => void;
  variant?: "primary" | "ghost" | "danger"; className?: string;
}) {
  const styles = {
    primary: "bg-forest text-white hover:bg-forest-deep",
    ghost: "border border-mist text-forest hover:bg-forest hover:border-forest hover:text-white",
    danger: "border border-clay text-clay hover:bg-clay hover:text-white",
  };
  return (
    <button onClick={onClick}
      className={`inline-flex items-center justify-center font-semibold text-sm rounded-pill transition-colors px-5 py-2 whitespace-nowrap ${styles[variant]} ${className}`}>
      {children}
    </button>
  );
}

// ─── Saved properties section ─────────────────────────────────────────────────
function SavedSection({ saved, onUnsave, onRequestViewing }: {
  saved: Property[];
  onUnsave: (id: string) => void;
  onRequestViewing: (p: Property) => void;
}) {
  return (
    <div>
      <div className="flex justify-between items-center mb-4">
        <SectionTitle>Saved properties</SectionTitle>
        <Link href="/listings" className="text-sm text-forest font-semibold hover:underline">+ Browse more</Link>
      </div>
      {saved.length === 0 ? (
        <Card>
          <div className="text-center py-16 px-5">
            <BookmarkIcon className="w-10 h-10 text-mist mx-auto mb-4" />
            <h3 className="font-display font-semibold text-lg text-forest-deep mb-2">No saved properties yet</h3>
            <p className="text-sm text-ink-soft mb-6 max-w-[36ch] mx-auto">
              You haven&apos;t saved any homes yet. Tap Save on a listing to keep it here.
            </p>
            <Link href="/listings" className="inline-flex items-center justify-center font-semibold text-sm px-6 py-3 rounded-pill bg-forest text-white hover:bg-forest-deep transition-colors">
              Browse houses
            </Link>
          </div>
        </Card>
      ) : (
        <div className="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-5">
          {saved.map((property) => (
            <div key={property.id} className="bg-white rounded-lg border border-mist shadow-card overflow-hidden flex flex-col">
              <div className="relative h-40 bg-gradient-to-br from-mist to-sage flex items-center justify-center font-mono text-xs uppercase tracking-wider text-ink-soft">
                Property photo
                {property.status === "verified" && (
                  <VerificationStamp variant="property" size={52} className="absolute top-3 right-3" />
                )}
              </div>
              <div className="p-4 flex flex-col flex-1">
                <div className="font-display font-semibold text-forest-deep mb-0.5">{property.title}</div>
                <div className="text-xs text-ink-soft mb-2">{property.address}</div>
                <div className="font-mono text-sm font-semibold text-forest mb-3">
                  {formatPrice(property.price)} <span className="text-xs font-normal text-ink-soft uppercase">/ month</span>
                </div>
                <div className="mt-auto flex flex-col gap-2">
                  <StatusBadge status={property.status} />
                  <div className="flex gap-2 mt-1">
                    <Link href={`/listings/${property.id}`} className="flex-1 text-center text-xs font-semibold py-2 rounded-pill border border-mist text-forest hover:bg-forest hover:border-forest hover:text-white transition-colors">
                      View
                    </Link>
                    {property.status === "verified" && (
                      <button onClick={() => onRequestViewing(property)}
                        className="flex-1 text-xs font-semibold py-2 rounded-pill bg-forest text-white hover:bg-forest-deep transition-colors">
                        Request viewing
                      </button>
                    )}
                    <button onClick={() => onUnsave(property.id)}
                      className="text-xs font-semibold px-3 py-2 rounded-pill border border-clay text-clay hover:bg-clay hover:text-white transition-colors"
                      title="Remove from saved">
                      ✕
                    </button>
                  </div>
                </div>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ─── Searches section ─────────────────────────────────────────────────────────
function SearchesSection({ searches, onDelete, onRunAgain }: {
  searches: RecentSearch[];
  onDelete: (id: string) => void;
  onRunAgain: (term: string) => void;
}) {
  const { paged, page, totalPages, goTo, total } = usePagination(searches, 5);
  return (
    <div>
      <SectionTitle>Recent searches</SectionTitle>
      <p className="text-sm text-ink-soft mb-4">Your last saved searches — run them again or clear ones you no longer need.</p>
      {searches.length === 0 ? (
        <Card>
          <div className="text-center py-16 px-5">
            <SearchIcon className="w-10 h-10 text-mist mx-auto mb-4" />
            <h3 className="font-display font-semibold text-lg text-forest-deep mb-2">No recent searches</h3>
            <p className="text-sm text-ink-soft mb-6">Searches you run will appear here for easy access.</p>
            <Link href="/listings" className="inline-flex items-center justify-center font-semibold text-sm px-6 py-3 rounded-pill bg-forest text-white hover:bg-forest-deep transition-colors">
              Start searching
            </Link>
          </div>
        </Card>
      ) : (
        <Card>
          <div className="overflow-x-auto">
            <table className="w-full border-collapse">
              <thead>
                <tr className="bg-sage">
                  {["Search", "Filters", "Results", "When", ""].map((h) => (
                    <th key={h} className="text-left font-mono text-[11px] uppercase tracking-widest text-ink-soft px-5 py-3 border-b border-mist whitespace-nowrap">{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {paged.map((s) => (
                  <tr key={s.id} className="border-b border-mist last:border-b-0 hover:bg-sage/50 transition-colors">
                    <td className="px-5 py-4 font-display font-semibold text-forest-deep whitespace-nowrap">{s.term}</td>
                    <td className="px-5 py-4 text-sm text-ink-soft whitespace-nowrap">{s.filters}</td>
                    <td className="px-5 py-4 text-sm whitespace-nowrap">{s.results} houses</td>
                    <td className="px-5 py-4 text-sm text-ink-soft whitespace-nowrap">{s.date}</td>
                    <td className="px-5 py-4">
                      <div className="flex gap-2 justify-end">
                        <Btn variant="ghost" onClick={() => onRunAgain(s.term)}>Run again</Btn>
                        <Btn variant="danger" onClick={() => onDelete(s.id)}>Delete</Btn>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <TablePagination page={page} totalPages={totalPages} total={total} perPage={5} onPage={goTo} label="search" />
        </Card>
      )}
    </div>
  );
}

// ─── Viewing requests ─────────────────────────────────────────────────────────
function ViewingRequests({ requests, onCancel }: {
  requests: ViewingRequest[];
  onCancel: (id: string) => void;
}) {
  const statusStyle = {
    pending: "bg-[#FBF1E1] text-gold-deep border border-gold",
    confirmed: "bg-[#E8F2EC] text-forest border border-forest",
    declined: "bg-[#F5EAE6] text-clay border border-clay",
  };
  return (
    <Card>
      <CardHeader title="Viewing requests" action={<span className="text-xs text-ink-soft">{requests.length} total</span>} />
      {requests.length === 0 ? (
        <div className="text-center py-10 text-sm text-ink-soft">No viewing requests yet.</div>
      ) : (
        <div className="divide-y divide-mist">
          {requests.map((r) => (
            <div key={r.id} className="flex flex-wrap items-center justify-between gap-3 px-5 py-4">
              <div>
                <div className="font-display font-semibold text-forest-deep">{r.propertyTitle}</div>
                <div className="text-xs text-ink-soft">{r.address}</div>
                <div className="text-xs text-ink-soft mt-0.5">Requested {r.date}</div>
              </div>
              <div className="flex items-center gap-3">
                <span className={`font-mono text-xs uppercase tracking-wider px-3 py-1.5 rounded-pill ${statusStyle[r.status]}`}>
                  {r.status}
                </span>
                {r.status === "pending" && (
                  <Btn variant="danger" onClick={() => onCancel(r.id)}>Cancel</Btn>
                )}
              </div>
            </div>
          ))}
        </div>
      )}
    </Card>
  );
}

// ─── Profile section ──────────────────────────────────────────────────────────
function ProfileSection({ profile, onSave, onPasswordSave }: {
  profile: { name: string; email: string; phone: string };
  onSave: (p: { name: string; email: string; phone: string }) => Promise<void> | void;
  onPasswordSave: (pw: { current: string; next: string; confirm: string }) => Promise<void>;
}) {
  const [form, setForm] = useState(profile);
  const [editing, setEditing] = useState(false);
  const [savingProfile, setSavingProfile] = useState(false);

  async function saveProfile() {
    setSavingProfile(true);
    try {
      await onSave(form);
      setEditing(false);
    } finally {
      setSavingProfile(false);
    }
  }
  const [pwForm, setPwForm] = useState({ current: "", next: "", confirm: "" });
  const [showPw, setShowPw] = useState(false);
  const [pwError, setPwError] = useState<string | null>(null);
  const [pwBusy, setPwBusy] = useState(false);

  // Keep the form in sync with the async-loaded profile while not editing.
  useEffect(() => { if (!editing) setForm(profile); }, [profile, editing]);

  const fieldCls = "w-full border border-mist rounded-sm px-4 py-3 text-sm bg-white text-ink focus:outline-2 focus:outline-gold focus:border-forest disabled:bg-sage disabled:text-ink-soft";

  async function savePw() {
    if (!pwForm.current) { setPwError("Enter your current password"); return; }
    if (pwForm.next !== pwForm.confirm) { setPwError("New passwords do not match"); return; }
    if (pwForm.next.length < 6) { setPwError("Password must be at least 6 characters"); return; }
    setPwError(null);
    setPwBusy(true);
    try {
      await onPasswordSave(pwForm);
      setPwForm({ current: "", next: "", confirm: "" });
      setShowPw(false);
    } catch (e) {
      setPwError(e instanceof ApiError ? e.message : "Couldn't update password.");
    } finally {
      setPwBusy(false);
    }
  }

  return (
    <div>
      <SectionTitle>Profile settings</SectionTitle>
      <p className="text-sm text-ink-soft mb-5">Update your name, contact details, and password.</p>

      <Card className="mb-5">
        <CardHeader title="Personal details" action={
          !editing
            ? <Btn variant="ghost" onClick={() => { setForm(profile); setEditing(true); }}>Edit</Btn>
            : <div className="flex gap-2">
                <Btn variant="ghost" onClick={() => setEditing(false)}>Cancel</Btn>
                <Btn variant="primary" onClick={saveProfile}>{savingProfile ? <span className="inline-flex items-center gap-2"><Spinner size="sm" />Saving…</span> : "Save changes"}</Btn>
              </div>
        } />
        <div className="p-5 grid grid-cols-1 sm:grid-cols-2 gap-4">
          {(["name", "email", "phone"] as const).map((field) => (
            <div key={field} className={field === "email" ? "sm:col-span-2" : ""}>
              <label className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-2">
                {field === "name" ? "Full name" : field === "email" ? "Email address" : "Phone number"}
              </label>
              <input type={field === "email" ? "email" : "text"} disabled={!editing}
                value={form[field]} onChange={(e) => setForm((f) => ({ ...f, [field]: e.target.value }))}
                className={fieldCls} />
            </div>
          ))}
        </div>
      </Card>

      <Card>
        <CardHeader title="Change password"
          action={<button onClick={() => setShowPw((s) => !s)} className="text-sm text-forest font-semibold hover:underline">{showPw ? "Hide" : "Change"}</button>} />
        {showPw && (
          <div className="p-5 grid grid-cols-1 sm:grid-cols-2 gap-4">
            {[["current", "Current password", "sm:col-span-2"], ["next", "New password", ""], ["confirm", "Confirm new password", ""]].map(([k, label, col]) => (
              <div key={k} className={col as string}>
                <label className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-2">{label}</label>
                <input type="password" placeholder="••••••••" value={pwForm[k as keyof typeof pwForm]}
                  onChange={(e) => setPwForm((p) => ({ ...p, [k]: e.target.value }))} className={fieldCls} />
              </div>
            ))}
            {pwError && <p className="sm:col-span-2 text-sm text-red-600">{pwError}</p>}
            <div className="sm:col-span-2 flex gap-3">
              <Btn variant="primary" onClick={savePw}>{pwBusy ? "Updating…" : "Update password"}</Btn>
              <Btn variant="ghost" onClick={() => { setPwForm({ current: "", next: "", confirm: "" }); setShowPw(false); setPwError(null); }}>Cancel</Btn>
            </div>
          </div>
        )}
      </Card>
    </div>
  );
}

// ─── Main dashboard ───────────────────────────────────────────────────────────
export default function DashboardPage() {
  const router = useRouter();
  const { user, logout } = useAuth();

  const [section, setSection] = useState<Section>("overview");
  const [savedIds, setSavedIds] = useState<string[]>([]);
  const [savedProperties, setSavedProperties] = useState<Property[]>([]);
  const [searches, setSearches] = useState<RecentSearch[]>([]);
  const [viewingRequests, setViewingRequests] = useState<ViewingRequest[]>([]);
  const [msgUnread, setMsgUnread] = useState(0);
  const [msgTotal, setMsgTotal] = useState(0);
  const [guestBookings, setGuestBookings] = useState<AccommodationBooking[]>([]);
  const [profile, setProfile] = useState({ name: "", email: "", phone: "" });
  const [reviewingBooking, setReviewingBooking] = useState<string | null>(null);

  const { show: showToast, node: toastNode } = useToast();
  const { confirm, node: confirmNode } = useConfirm();

  const unreadCount = msgUnread;

  // Load tenant data from the API on mount.
  useEffect(() => {
    (async () => {
      try {
        const p = await clientExecute<{ name: string; email: string; phone: string }>("user.get-profile");
        setProfile({ name: p.name ?? "", email: p.email ?? "", phone: p.phone ?? "" });
      } catch { /* ignore */ }
      try {
        const b = await clientExecute<Paginated<AccommodationBooking>>("booking.find-by-guest", { limit: 50 });
        setGuestBookings(b.items);
      } catch { /* ignore */ }
      try {
        const v = await clientExecute<Paginated<ApiViewingRequest>>("viewing-request.find-by-tenant", { limit: 50 });
        setViewingRequests(v.items.map((r) => ({
          id: r.id, propertyId: r.propertyId, propertyTitle: r.propertyTitle, address: r.address,
          status: (r.status === "cancelled" ? "declined" : r.status) as ViewingRequest["status"], date: r.date,
        })));
      } catch { /* ignore */ }
      try {
        const c = await clientExecute<{ items: { unread: number }[]; total: number }>("message.list-conversations", { limit: 100 });
        setMsgUnread(c.items.filter((x) => x.unread > 0).length);
        setMsgTotal(c.total);
      } catch { /* ignore */ }
    })();

    // Saved properties + recent searches from the API.
    clientExecute<{ items: Property[] }>("saved-property.list")
      .then((res) => { setSavedProperties(res.items); setSavedIds(res.items.map((p) => p.id)); })
      .catch(() => { /* ignore */ });
    clientExecute<{ items: Parameters<typeof mapSearch>[0][] }>("recent-search.list")
      .then((res) => setSearches(res.items.map(mapSearch)))
      .catch(() => { /* ignore */ });
  }, []);

  const bookingsPag = usePagination(guestBookings, 5);

  // ── Actions ──
  async function handleUnsave(id: string) {
    const prop = savedProperties.find((p) => p.id === id);
    const ok = await confirm({
      title: "Remove saved property?",
      body: `Remove "${prop?.title}" from your saved list? You can always save it again from the listing.`,
      confirmLabel: "Remove",
      danger: true,
    });
    if (ok) {
      try {
        await clientExecute("saved-property.toggle", { propertyId: id });
        setSavedIds((prev) => prev.filter((i) => i !== id));
        setSavedProperties((ps) => ps.filter((p) => p.id !== id));
        showToast("Property removed from saved");
      } catch (e) {
        showToast(e instanceof ApiError ? e.message : "Couldn't update your saved list.", "error");
      }
    }
  }

  async function handleRequestViewing(property: Property) {
    if (viewingRequests.some((r) => r.propertyId === property.id)) {
      showToast("You already have a viewing request for this property", "info");
      return;
    }
    try {
      const today = new Date().toISOString().slice(0, 10);
      const created = await clientExecute<ApiViewingRequest>("viewing-request.create", {
        propertyId: property.id, preferredDate: today,
      });
      setViewingRequests((prev) => [{
        id: created.id, propertyId: property.id, propertyTitle: property.title,
        address: property.address, status: "pending", date: created.date ?? "Today",
      }, ...prev]);
      showToast(`Viewing requested for ${property.title}. The landlord will respond within Villa.`);
    } catch (e) {
      showToast(e instanceof ApiError ? e.message : "Couldn't request viewing.", "error");
    }
  }

  async function handleCancelViewing(id: string) {
    const req = viewingRequests.find((r) => r.id === id);
    const ok = await confirm({
      title: "Cancel viewing request?",
      body: `Cancel your viewing request for "${req?.propertyTitle}"? The landlord will be notified.`,
      confirmLabel: "Yes, cancel",
      danger: true,
    });
    if (ok) {
      try {
        await clientExecute("viewing-request.cancel", { id });
        setViewingRequests((prev) => prev.filter((r) => r.id !== id));
        showToast("Viewing request cancelled");
      } catch (e) {
        showToast(e instanceof ApiError ? e.message : "Couldn't cancel.", "error");
      }
    }
  }

  async function handleDeleteSearch(id: string) {
    const search = searches.find((s) => s.id === id);
    const ok = await confirm({
      title: "Delete this search?",
      body: `Remove "${search?.term}" from your recent searches?`,
      confirmLabel: "Delete",
      danger: true,
    });
    if (ok) {
      try {
        await clientExecute("recent-search.delete", { id });
        setSearches((prev) => prev.filter((r) => r.id !== id));
        showToast("Search removed");
      } catch (e) {
        showToast(e instanceof ApiError ? e.message : "Couldn't remove the search.", "error");
      }
    }
  }

  function handleRunAgain(term: string) {
    showToast(`Running search for "${term}"…`);
    setTimeout(() => { window.location.href = `/listings?q=${encodeURIComponent(term)}`; }, 600);
  }

  async function handleSaveProfile(p: typeof profile) {
    try {
      const updated = await clientExecute<{ name: string; email: string; phone: string }>("user.update-profile", p);
      setProfile({ name: updated.name, email: updated.email, phone: updated.phone });
      showToast("Profile updated successfully");
    } catch (e) {
      showToast(e instanceof ApiError ? e.message : "Couldn't update profile.", "error");
    }
  }

  async function handlePasswordSave(pw: { current: string; next: string; confirm: string }) {
    // Throws on failure so ProfileSection surfaces the error inline.
    await clientExecute("auth.change-password", pw);
    showToast("Password updated successfully");
  }

  async function handleLogout() {
    await logout();
    router.push("/");
    router.refresh();
  }

  const navItems: { id: Section; icon: ReactNode; label: string; badge?: number }[] = [
    { id: "overview",  icon: <HomeIcon />,     label: "Overview" },
    { id: "bookings",  icon: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="w-[18px] h-[18px]"><path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/><path d="M9 22V12h6v10" strokeLinecap="round"/></svg>, label: "My bookings", badge: guestBookings.filter(b => b.status === "pending" || b.status === "confirmed").length },
    { id: "saved",     icon: <BookmarkIcon />, label: "Saved properties", badge: savedIds.length },
    { id: "searches",  icon: <SearchIcon />,   label: "Recent searches" },
    { id: "messages",  icon: <MessageIcon />,  label: "Messages", badge: unreadCount },
    { id: "profile",   icon: <UserIcon />,     label: "Profile settings" },
  ];

  return (
    <div className="max-w-6xl mx-auto px-6 py-8">
      <div className="grid grid-cols-1 lg:grid-cols-[240px_1fr] gap-8 items-start">

        {/* Sidebar */}
        <aside className="bg-white border border-mist rounded-md p-5 lg:sticky lg:top-[96px]">
          <div className="mb-5 pb-5 border-b border-mist">
            <div className="font-display font-semibold text-lg">{profile.name}</div>
            <div className="font-mono text-xs uppercase tracking-widest text-ink-soft">Tenant</div>
          </div>
          <nav className="flex flex-col gap-1">
            {navItems.map(({ id, icon, label, badge }) => (
              <button key={id} onClick={() => setSection(id)}
                className={`flex items-center gap-3 px-3 py-2.5 rounded-sm text-sm font-medium transition-colors text-left w-full ${
                  section === id ? "bg-forest text-white" : "text-ink-soft hover:bg-sage hover:text-forest"
                }`}>
                <span className="w-[18px] h-[18px] shrink-0">{icon}</span>
                <span className="flex-1">{label}</span>
                {badge !== undefined && badge > 0 && (
                  <span className={`inline-flex items-center justify-center min-w-[18px] h-[18px] rounded-full text-[11px] font-bold px-1 ${
                    section === id ? "bg-white text-forest" : "bg-gold text-forest-deep"
                  }`}>{badge}</span>
                )}
              </button>
            ))}
          </nav>
          <div className="mt-5 pt-5 border-t border-mist">
            <button onClick={handleLogout} className="text-sm text-ink-soft hover:text-clay transition-colors">Log out</button>
          </div>
        </aside>

        {/* Main */}
        <div>

          {/* Overview */}
          {section === "overview" && (
            <div>
              <div className="flex flex-wrap justify-between items-end gap-3 mb-6">
                <div>
                  <h1 className="font-display font-semibold text-2xl lg:text-3xl text-forest-deep">
                    Welcome back, {profile.name.split(" ")[0]}
                  </h1>
                  <p className="text-sm text-ink-soft">Here&apos;s what&apos;s new with your saved homes and searches.</p>
                </div>
                <Link href="/listings" className="inline-flex items-center justify-center font-semibold text-sm px-6 py-3 rounded-pill bg-forest text-white hover:bg-forest-deep transition-colors">
                  Browse houses
                </Link>
              </div>

              <div className="grid grid-cols-2 sm:grid-cols-4 gap-4 mb-8">
                {[
                  { label: "My bookings", value: String(guestBookings.length), change: `${guestBookings.filter(b => b.status === "confirmed").length} confirmed`, action: () => setSection("bookings") },
                  { label: "Saved properties", value: String(savedIds.length), change: "Click to manage", action: () => setSection("saved") },
                  { label: "Viewing requests", value: String(viewingRequests.length), change: `${viewingRequests.filter((r) => r.status === "pending").length} awaiting response`, action: () => setSection("saved") },
                  { label: "Unread messages", value: String(unreadCount), change: `${msgTotal} conversation${msgTotal !== 1 ? "s" : ""}`, action: () => setSection("messages") },
                ].map(({ label, value, change, action }) => (
                  <button key={label} onClick={action}
                    className="bg-white border border-mist rounded-md p-5 text-left hover:border-forest hover:shadow-card transition-all group">
                    <div className="font-mono text-xs uppercase tracking-widest text-ink-soft mb-2">{label}</div>
                    <div className="font-display text-3xl font-semibold text-forest-deep group-hover:text-forest transition-colors">{value}</div>
                    <div className="text-xs mt-1 text-forest">{change}</div>
                  </button>
                ))}
              </div>

              {/* Recent bookings preview */}
              {guestBookings.length > 0 && (
                <Card className="mb-6">
                  <CardHeader title="Recent bookings" action={<Btn variant="ghost" onClick={() => setSection("bookings")}>See all</Btn>} />
                  <div className="divide-y divide-mist">
                    {guestBookings.slice(0, 2).map((b) => {
                      const statusCfg: Record<string, { label: string; cls: string }> = {
                        pending:   { label: "Pending",   cls: "bg-[#FBF1E1] text-gold-deep border-gold" },
                        confirmed: { label: "Confirmed", cls: "bg-[#E8F2EC] text-forest border-forest" },
                        completed: { label: "Completed", cls: "bg-mist text-ink-soft border-mist" },
                        declined:  { label: "Declined",  cls: "bg-[#F5EAE6] text-clay border-clay" },
                        cancelled: { label: "Cancelled", cls: "bg-[#F5EAE6] text-clay border-clay" },
                        "checked-in": { label: "Checked in", cls: "bg-[#E8F2EC] text-forest border-forest" },
                      };
                      const { label, cls } = statusCfg[b.status] ?? statusCfg.pending;
                      return (
                        <div key={b.id} className="flex flex-wrap items-center justify-between gap-3 px-5 py-4">
                          <div>
                            <div className="font-semibold text-forest-deep">{b.accommodationName}</div>
                            <div className="text-sm text-ink-soft">{b.roomTypeName} · {b.checkIn} → {b.checkOut}</div>
                          </div>
                          <div className="flex items-center gap-3">
                            <span className={`inline-flex items-center gap-1 font-mono text-[10px] uppercase tracking-wider px-2.5 py-1 rounded-pill border ${cls}`}>
                              <span className="w-1.5 h-1.5 rounded-full bg-current" />{label}
                            </span>
                            <span className="font-mono font-semibold text-forest text-sm">GH₵ {b.totalPrice.toLocaleString()}</span>
                          </div>
                        </div>
                      );
                    })}
                  </div>
                </Card>
              )}

              <div className="mb-6">
                <ViewingRequests requests={viewingRequests} onCancel={handleCancelViewing} />
              </div>

              <Card>
                <CardHeader title="Saved properties" action={<Btn variant="ghost" onClick={() => setSection("saved")}>See all</Btn>} />
                <div className="p-5">
                  {savedIds.length === 0 ? (
                    <p className="text-sm text-ink-soft text-center py-6">You haven&apos;t saved any homes yet.</p>
                  ) : (
                    <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
                      {savedProperties.slice(0, 3).map((p) => (
                        <div key={p.id} className="border border-mist rounded-md overflow-hidden">
                          <div className="h-24 bg-gradient-to-br from-mist to-sage flex items-center justify-center text-xs font-mono text-ink-soft">
                            Property photo
                          </div>
                          <div className="p-3">
                            <div className="font-display font-semibold text-sm text-forest-deep">{p.title}</div>
                            <div className="text-xs text-ink-soft mb-2">{p.town}</div>
                            <div className="flex justify-between items-center">
                              <StatusBadge status={p.status} />
                              <Link href={`/listings/${p.id}`} className="text-xs text-forest font-semibold hover:underline">View →</Link>
                            </div>
                          </div>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              </Card>
            </div>
          )}

          {/* Bookings */}
          {section === "bookings" && (
            <div>
              <h2 className="font-display font-semibold text-xl text-forest-deep mb-5">My bookings</h2>
              {guestBookings.length === 0 ? (
                <div className="bg-white border border-mist rounded-md py-16 text-center">
                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" className="w-12 h-12 text-mist mx-auto mb-4">
                    <path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/><path d="M9 22V12h6v10" strokeLinecap="round"/>
                  </svg>
                  <h3 className="font-display font-semibold text-lg text-forest-deep mb-2">No bookings yet</h3>
                  <p className="text-sm text-ink-soft mb-6">Browse Villa Stay to find hotels and guesthouses to book.</p>
                  <Link href="/stay" className="inline-flex items-center justify-center font-semibold text-sm px-6 py-3 rounded-pill bg-forest text-white hover:bg-forest-deep transition-colors">
                    Browse Villa Stay
                  </Link>
                </div>
              ) : (
                <div className="flex flex-col gap-4">
                  {bookingsPag.paged.map((b) => {
                    const statusCfg: Record<string, { label: string; cls: string }> = {
                      pending:      { label: "Pending",    cls: "bg-[#FBF1E1] text-gold-deep border-gold" },
                      confirmed:    { label: "Confirmed",  cls: "bg-[#E8F2EC] text-forest border-forest" },
                      declined:     { label: "Declined",   cls: "bg-[#F5EAE6] text-clay border-clay" },
                      "checked-in": { label: "Checked in", cls: "bg-[#E8F2EC] text-forest border-forest" },
                      completed:    { label: "Completed",  cls: "bg-mist text-ink-soft border-mist" },
                      cancelled:    { label: "Cancelled",  cls: "bg-[#F5EAE6] text-clay border-clay" },
                    };
                    const { label, cls } = statusCfg[b.status] ?? statusCfg.pending;
                    return (
                      <div key={b.id} className="bg-white border border-mist rounded-md overflow-hidden hover:border-forest transition-colors">
                        {/* Header bar */}
                        <div className="flex flex-wrap items-center justify-between gap-3 px-5 py-3 border-b border-mist bg-sage/30">
                          <div className="flex items-center gap-3">
                            <span className="font-mono text-xs font-bold text-forest-deep">{b.id.toUpperCase()}</span>
                            <span className={`inline-flex items-center gap-1 font-mono text-[10px] uppercase tracking-wider px-2.5 py-1 rounded-pill border font-medium ${cls}`}>
                              <span className="w-1.5 h-1.5 rounded-full bg-current" />{label}
                            </span>
                          </div>
                          <span className="text-xs text-ink-soft">Booked {b.bookedDate}</span>
                        </div>

                        {/* Body */}
                        <div className="px-5 py-4 flex flex-wrap items-start justify-between gap-4">
                          <div className="flex gap-4">
                            {/* Accommodation icon */}
                            <div className="w-14 h-14 rounded-md bg-gradient-to-br from-[#1E3A30] to-[#2A5244] flex items-center justify-center shrink-0">
                              <svg viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="1.4" className="w-7 h-7 opacity-60">
                                <path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/><path d="M9 22V12h6v10" strokeLinecap="round"/>
                              </svg>
                            </div>
                            <div>
                              <div className="font-display font-semibold text-forest-deep">{b.accommodationName}</div>
                              <div className="text-sm text-ink-soft">{b.roomTypeName}</div>
                              <div className="text-sm text-ink-soft mt-1">
                                {b.checkIn} → {b.checkOut} · {b.nights} night{b.nights !== 1 ? "s" : ""} · {b.guests} guest{b.guests !== 1 ? "s" : ""}
                              </div>
                              {b.specialRequests && (
                                <div className="text-xs text-gold-deep mt-1">"{b.specialRequests}"</div>
                              )}
                            </div>
                          </div>

                          {/* Price + payment */}
                          <div className="text-right">
                            <div className="font-mono font-bold text-xl text-forest">GH₵ {b.totalPrice.toLocaleString()}</div>
                            <div className="text-xs text-ink-soft capitalize mt-0.5">
                              {b.paymentMethod === "mobile-money" ? "Mobile money" : "Cash on arrival"}
                            </div>
                            {b.paymentReference && (
                              <div className="font-mono text-xs text-ink-soft mt-0.5">Ref: {b.paymentReference}</div>
                            )}
                            <div className="text-xs text-ink-soft mt-0.5">
                              Deposit: GH₵ {b.depositAmount.toLocaleString()}
                            </div>
                          </div>
                        </div>

                        {/* Footer actions */}
                        <div className="px-5 py-3 border-t border-mist flex items-center justify-between gap-3 bg-sage/20">
                          <Link href={`/stay/${b.accommodationId}`}
                            className="text-sm font-semibold text-forest hover:underline">
                            View property →
                          </Link>
                          {(b.status === "confirmed" || b.status === "pending") && (
                            <span className="text-xs text-ink-soft">
                              Check-in: <strong className="text-ink">{b.checkIn}</strong>
                            </span>
                          )}
                          {b.status === "completed" && (
                            <button
                              onClick={() => setReviewingBooking(reviewingBooking === b.id ? null : b.id)}
                              className="text-sm font-semibold text-forest hover:underline">
                              {reviewingBooking === b.id ? "Close review" : "Leave a review"}
                            </button>
                          )}
                        </div>

                        {/* Inline review section for completed bookings */}
                        {reviewingBooking === b.id && (
                          <div className="border-t border-mist px-5 py-5">
                            <ReviewsSection
                              targetId={b.accommodationId}
                              targetName={b.accommodationName}
                              targetType="accommodation"
                              initialReviews={[]}
                              averageRating={0}
                              showWriteReview={true}
                            />
                          </div>
                        )}
                      </div>
                    );
                  })}
                  <TablePagination page={bookingsPag.page} totalPages={bookingsPag.totalPages} total={guestBookings.length} perPage={5} onPage={bookingsPag.goTo} label="booking" />
                </div>
              )}
            </div>
          )}

          {/* Saved */}
          {section === "saved" && (
            <SavedSection saved={savedProperties} onUnsave={handleUnsave} onRequestViewing={handleRequestViewing} />
          )}

          {/* Searches */}
          {section === "searches" && (
            <SearchesSection searches={searches} onDelete={handleDeleteSearch} onRunAgain={handleRunAgain} />
          )}

          {/* Messages — same MessageThread as landlord/admin dashboards */}
          {section === "messages" && (
            <div>
              <h2 className="font-display font-semibold text-xl text-forest-deep mb-4">Messages</h2>
              <MessageThread myName={profile.name || "You"} />
            </div>
          )}

          {/* Profile */}
          {section === "profile" && (
            <ProfileSection profile={profile} onSave={handleSaveProfile} onPasswordSave={handlePasswordSave} />
          )}
        </div>
      </div>

      {confirmNode}
      {toastNode}
    </div>
  );
}
