"use client";

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

type KYCStatus = "not_started" | "pending" | "approved" | "rejected";

// ─── KYC types & gate ────────────────────────────────────────────────────────
function KYCGate({ status }: { status: KYCStatus }) {
  return (
    <div className="max-w-xl mx-auto py-12 px-6 text-center">
      {status === "not_started" && (
        <>
          <VerificationStamp variant="pending" size={80} className="mx-auto mb-6" />
          <h2 className="font-display font-semibold text-2xl text-forest-deep mb-3">Verify your identity to start listing</h2>
          <p className="text-ink-soft mb-8 max-w-[42ch] mx-auto">
            All landlords and agents on Villa must complete identity verification (KYC) before adding properties. This protects tenants and builds trust across the platform.
          </p>
          <div className="bg-white border border-mist rounded-md p-5 mb-8 text-left">
            {[
              { icon: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="w-5 h-5 text-forest"><rect x="2" y="5" width="20" height="14" rx="2"/><circle cx="8" cy="12" r="2"/><path d="M14 9h4M14 12h4M14 15h2" strokeLinecap="round"/></svg>, label: "Government-issued ID", desc: "Ghana Card, Passport, or Voter's ID" },
              { icon: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="w-5 h-5 text-forest"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>, label: "Selfie with your ID", desc: "A photo of you holding your document" },
              { icon: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="w-5 h-5 text-forest"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2" strokeLinecap="round"/></svg>, label: "1–2 business days", desc: "We'll review and notify you by email" },
            ].map(({ icon, label, desc }) => (
              <div key={label} className="flex items-start gap-4 py-3 border-b border-mist last:border-b-0">
                <div className="shrink-0 mt-0.5">{icon}</div>
                <div>
                  <div className="text-sm font-semibold text-ink">{label}</div>
                  <div className="text-xs text-ink-soft">{desc}</div>
                </div>
              </div>
            ))}
          </div>
          <Link href="/kyc"
            className="inline-flex items-center justify-center font-semibold text-sm px-7 py-3.5 rounded-pill bg-forest text-white hover:bg-forest-deep transition-colors mb-6">
            Start verification now
          </Link>
        </>
      )}

      {status === "pending" && (
        <>
          <VerificationStamp variant="pending" size={80} className="mx-auto mb-6" />
          <h2 className="font-display font-semibold text-2xl text-forest-deep mb-3">Verification under review</h2>
          <p className="text-ink-soft mb-4 max-w-[44ch] mx-auto">
            Your KYC application has been submitted. The Villa team is reviewing your documents — this usually takes <strong>1–2 business days</strong>.
          </p>
          <p className="text-sm text-ink-soft mb-8 max-w-[44ch] mx-auto">
            You&apos;ll receive an email once your account is approved. You can browse the platform while you wait.
          </p>
          <div className="bg-[#FBF1E1] border border-gold rounded-md px-5 py-4 mb-8 text-sm text-gold-deep max-w-sm mx-auto">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="w-4 h-4 inline-block mr-1.5 -mt-0.5 text-gold-deep"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2" strokeLinecap="round"/></svg>Application submitted — awaiting review
          </div>
        </>
      )}

      {status === "rejected" && (
        <>
          <div className="w-16 h-16 rounded-full bg-[#F5EAE6] flex items-center justify-center mx-auto mb-6">
            <svg viewBox="0 0 24 24" fill="none" stroke="#C2613F" strokeWidth="2" className="w-8 h-8">
              <path d="M6 6l12 12M18 6L6 18" strokeLinecap="round" />
            </svg>
          </div>
          <h2 className="font-display font-semibold text-2xl text-forest-deep mb-3">Verification not approved</h2>
          <p className="text-ink-soft mb-4 max-w-[44ch] mx-auto">
            We were unable to verify your identity with the documents provided. Common reasons include blurry photos, expired documents, or a selfie mismatch.
          </p>
          <div className="bg-[#F5EAE6] border border-clay rounded-md px-5 py-4 mb-8 text-sm text-clay max-w-sm mx-auto text-left">
            <strong>Reason:</strong> Document photo was not clear enough to verify.
          </div>
          <Link href="/kyc"
            className="inline-flex items-center justify-center font-semibold text-sm px-7 py-3.5 rounded-pill bg-forest text-white hover:bg-forest-deep transition-colors mb-6">
            Re-submit verification
          </Link>
        </>
      )}
    </div>
  );
}

// ─── Types ────────────────────────────────────────────────────────────────────
type Section = "overview" | "listings" | "add" | "messages" | "profile" | "viewings";

interface EditingListing extends Property {
  dirty: boolean;
}

// ─── Shared primitives ────────────────────────────────────────────────────────
function Btn({ children, onClick, variant = "primary", className = "", disabled = false }: {
  children: ReactNode; onClick?: () => void; variant?: "primary" | "ghost" | "danger" | "gold";
  className?: string; disabled?: boolean;
}) {
  const s = {
    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",
    gold: "bg-gold text-forest-deep hover:bg-gold-deep hover:text-white",
  };
  return (
    <button disabled={disabled} onClick={onClick}
      className={`inline-flex items-center justify-center font-semibold text-sm px-5 py-2 rounded-pill transition-colors whitespace-nowrap disabled:opacity-40 ${s[variant]} ${className}`}>
      {children}
    </button>
  );
}

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, sub, action }: { title: string; sub?: string; action?: ReactNode }) {
  return (
    <div className="flex flex-wrap justify-between items-center gap-3 px-5 py-4 border-b border-mist">
      <div>
        <h3 className="font-display font-semibold text-lg">{title}</h3>
        {sub && <p className="text-xs text-ink-soft mt-0.5">{sub}</p>}
      </div>
      {action}
    </div>
  );
}

function Field({ label, full, children }: { label: string; full?: boolean; children: ReactNode }) {
  return (
    <div className={`flex flex-col gap-2 ${full ? "sm:col-span-2" : ""}`}>
      <label className="font-mono text-xs uppercase tracking-widest text-ink-soft">{label}</label>
      <div className="[&>*]: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">
        {children}
      </div>
    </div>
  );
}

// ─── Edit listing modal ────────────────────────────────────────────────────────
function EditListingModal({ listing, onSave, onClose }: {
  listing: Property; onSave: (updated: Property) => void; onClose: () => void;
}) {
  const [form, setForm] = useState({ ...listing });
  function set(k: keyof Property, v: string | number) { setForm((f) => ({ ...f, [k]: v })); }

  return (
    <div className="fixed inset-0 z-[90] flex items-center justify-center bg-ink/40 backdrop-blur-sm px-4 py-8 overflow-y-auto">
      <div className="bg-white rounded-lg border border-mist shadow-card-hover w-full max-w-xl">
        <div className="flex justify-between items-center px-6 py-4 border-b border-mist">
          <h3 className="font-display font-semibold text-lg text-forest-deep">Edit listing</h3>
          <button onClick={onClose} className="text-ink-soft hover:text-ink text-2xl leading-none">×</button>
        </div>
        <div className="p-6 grid grid-cols-1 sm:grid-cols-2 gap-5">
          <Field label="Title" full>
            <input value={form.title} onChange={(e) => set("title", e.target.value)} />
          </Field>
          <Field label="Price (GH₵ / month)">
            <input type="number" value={form.price} onChange={(e) => set("price", Number(e.target.value))} />
          </Field>
          <Field label="Availability">
            <select value={form.availability} onChange={(e) => set("availability", e.target.value)}>
              <option>Available now</option>
              <option>Currently occupied</option>
              <option>Available from a date</option>
            </select>
          </Field>
          <Field label="Furnishing">
            <select value={form.furnishing} onChange={(e) => set("furnishing", e.target.value)}>
              <option>Unfurnished</option>
              <option>Furnished</option>
              <option>Partly furnished</option>
            </select>
          </Field>
          <Field label="Description" full>
            <textarea className="min-h-[100px] resize-y" value={form.description}
              onChange={(e) => set("description", e.target.value)} />
          </Field>
        </div>
        <div className="px-6 pb-6 flex gap-3 justify-end">
          <Btn variant="ghost" onClick={onClose}>Cancel</Btn>
          <Btn variant="primary" onClick={() => { onSave(form); onClose(); }}>Save changes</Btn>
        </div>
      </div>
    </div>
  );
}

// ─── Photo manager modal ───────────────────────────────────────────────────────
function PhotoManagerModal({ listing, onClose }: { listing: Property; onClose: () => void }) {
  const [photos, setPhotos] = useState(listing.images);

  return (
    <div className="fixed inset-0 z-[90] flex items-center justify-center bg-ink/40 backdrop-blur-sm px-4">
      <div className="bg-white rounded-lg border border-mist shadow-card-hover w-full max-w-lg">
        <div className="flex justify-between items-center px-6 py-4 border-b border-mist">
          <div>
            <h3 className="font-display font-semibold text-lg text-forest-deep">Manage photos</h3>
            <p className="text-xs text-ink-soft">{listing.title}</p>
          </div>
          <button onClick={onClose} className="text-ink-soft hover:text-ink text-2xl leading-none">×</button>
        </div>
        <div className="p-6">
          <div className="grid grid-cols-3 gap-3 mb-5">
            {photos.map((p, i) => (
              <div key={p} className="relative aspect-square rounded-sm bg-gradient-to-br from-mist to-sage flex items-center justify-center text-xs font-mono text-ink-soft">
                {p}
                <button onClick={() => setPhotos((prev) => prev.filter((_, j) => j !== i))}
                  className="absolute top-1 right-1 w-5 h-5 rounded-full bg-white border border-mist text-[11px] leading-none flex items-center justify-center hover:bg-clay hover:text-white transition-colors">
                  ×
                </button>
              </div>
            ))}
            <button onClick={() => setPhotos((prev) => [...prev, `Photo ${prev.length + 1}`])}
              className="aspect-square rounded-sm border-2 border-dashed border-mist flex flex-col items-center justify-center gap-1 text-xs text-ink-soft hover:border-forest transition-colors">
              <PhotoIcon className="w-5 h-5" />
              Add photo
            </button>
          </div>
          <div className="flex justify-end gap-3">
            <Btn variant="ghost" onClick={onClose}>Cancel</Btn>
            <Btn variant="primary" onClick={onClose}>Save photos</Btn>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── Add property form ─────────────────────────────────────────────────────────
interface CreatePropertyPayload {
  title: string; category: string; type: string; town: string; address: string;
  price: number; availability: string; description: string; size?: string; images: string[];
}
function AddPropertySection({ onSubmit }: { onSubmit: (payload: CreatePropertyPayload) => Promise<void> }) {
  const emptyForm = { title: "", category: "residential", type: "2 bedroom", town: "Akim Oda", address: "", price: "", availability: "Available now", description: "", size: "" };
  const [form, setForm] = useState(emptyForm);
  const PROPERTY_TYPES = form.category === "residential" ? ["Single room", "1 bedroom", "2 bedroom", "3 bedroom", "4 bedroom", "Compound house"] : ["Shop", "Office", "Warehouse", "Storage", "Showroom", "Workshop"];
  const [photos, setPhotos] = useState<{ url: string; name: string }[]>([]);
  const [uploading, setUploading] = useState(false);
  const [submitted, setSubmitted] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function handleFiles(files: FileList | null) {
    if (!files?.length) return;
    setUploading(true);
    setError(null);
    try {
      for (const file of Array.from(files)) {
        const up = await uploadFile(file);
        setPhotos((prev) => [...prev, { url: up.url, name: up.filename }]);
      }
    } catch (e) {
      setError(e instanceof ApiError ? e.message : "Upload failed.");
    } finally {
      setUploading(false);
    }
  }

  async function handleSubmit() {
    setSubmitting(true);
    setError(null);
    try {
      await onSubmit({
        title: form.title.trim(), category: form.category, type: form.type, town: form.town,
        address: form.address.trim(), price: Number(form.price), availability: form.availability,
        description: form.description, size: form.size || undefined, images: photos.map((p) => p.url),
      });
      setSubmitted(true);
    } catch (e) {
      setError(e instanceof ApiError ? e.message : "Couldn't submit the listing.");
    } finally {
      setSubmitting(false);
    }
  }

  if (submitted) {
    return (
      <Card>
        <div className="text-center py-16 px-5">
          <VerificationStamp variant="pending" size={72} className="mx-auto mb-5" />
          <h3 className="font-display font-semibold text-xl text-forest-deep mb-2">Listing submitted for review</h3>
          <p className="text-sm text-ink-soft max-w-[40ch] mx-auto mb-6">
            Villa will verify the details and photos, usually within 1–2 days. You&apos;ll be notified once it&apos;s live.
          </p>
          <Btn variant="primary" onClick={() => { setSubmitted(false); setForm(emptyForm); setPhotos([]); }}>
            Add another property
          </Btn>
        </div>
      </Card>
    );
  }

  function set(k: string, v: string) { setForm((f) => ({ ...f, [k]: v })); }
  const isValid = form.title.trim() && form.address.trim() && form.price && photos.length >= 1;

  return (
    <Card>
      <CardHeader title="Add a new listing" sub="Submitted listings go to Villa for review before they appear in search." />
      <div className="p-6 grid grid-cols-1 sm:grid-cols-2 gap-5">

        {/* Listing category toggle */}
        <div className="sm:col-span-2">
          <label className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-2">Listing type</label>
          <div className="grid grid-cols-2 gap-3">
            {(["residential", "commercial"] as const).map((cat) => (
              <button key={cat} type="button"
                onClick={() => setForm((f) => ({ ...f, category: cat, type: cat === "residential" ? "2 bedroom" : "Shop" }))}
                className={`flex items-center gap-3 p-4 border-2 rounded-md text-left transition-colors ${form.category === cat ? "border-forest bg-[#E8F2EC]" : "border-mist bg-white hover:border-forest"}`}>
                {cat === "residential" ? (
                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="w-5 h-5 text-forest shrink-0">
                    <path d="M3 12l9-9 9 9M5 10v10h14V10" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                ) : (
                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="w-5 h-5 text-forest shrink-0">
                    <path d="M3 21h18M3 10h18M3 7l9-4 9 4M4 10v11M20 10v11M8 10v11M12 10v11M16 10v11" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                )}
                <div>
                  <div className="font-semibold text-sm text-forest-deep capitalize">{cat}</div>
                  <div className="text-xs text-ink-soft mt-0.5">{cat === "residential" ? "Houses, rooms, apartments" : "Shops, offices, warehouses, storage"}</div>
                </div>
              </button>
            ))}
          </div>
        </div>

        <Field label="Title" full>
          <input placeholder={form.category === "residential" ? "e.g. 2-Bedroom House" : "e.g. Shop Space, Akim Oda Market"} value={form.title} onChange={(e) => set("title", e.target.value)} />
        </Field>
        <Field label={form.category === "residential" ? "House type" : "Commercial type"}>
          <select value={form.type} onChange={(e) => set("type", e.target.value)}>
            {PROPERTY_TYPES.map((t) => <option key={t}>{t}</option>)}
          </select>
        </Field>
        <Field label="Town">
          <select value={form.town} onChange={(e) => set("town", e.target.value)}>
            <option>Akim Oda</option><option>New Tafo</option><option>Kade</option><option>Asamankese</option>
          </select>
        </Field>
        <Field label="Street / area">
          <input placeholder="e.g. Adweso Road" value={form.address} onChange={(e) => set("address", e.target.value)} />
        </Field>
        <Field label="Price (GH₵ / month)">
          <input type="number" placeholder="e.g. 1200" value={form.price} onChange={(e) => set("price", e.target.value)} />
        </Field>
        {form.category === "commercial" && (
          <Field label="Size (sqm) — optional">
            <input placeholder="e.g. 45 sqm" value={form.size} onChange={(e) => set("size", e.target.value)} />
          </Field>
        )}
        <Field label="Availability" full={form.category === "commercial" && form.size === ""}>
          <select value={form.availability} onChange={(e) => set("availability", e.target.value)}>
            <option>Available now</option><option>Available from a date</option><option>Currently occupied</option>
          </select>
        </Field>
        <Field label="Description" full>
          <textarea className="min-h-[100px] resize-y"
            placeholder={form.category === "residential" ? "Describe the property, compound, water, electricity, and nearby landmarks." : "Describe the space, permitted uses, access hours, power supply, and nearby landmarks."}
            value={form.description} onChange={(e) => set("description", e.target.value)} />
        </Field>
        <div className="sm:col-span-2 flex flex-col gap-2">
          <label className="font-mono text-xs uppercase tracking-widest text-ink-soft">Property photos</label>
          {photos.length < 4 && (
            <div className="bg-[#FBF1E1] border border-gold rounded-sm px-4 py-2 text-xs text-gold-deep">
              Add at least {4 - photos.length} more photo{4 - photos.length !== 1 ? "s" : ""} — Villa needs 4+ photos to verify your listing.
            </div>
          )}
          <label className="border-2 border-dashed border-mist rounded-md p-8 text-center text-sm text-ink-soft hover:border-forest transition-colors cursor-pointer block">
            <input type="file" accept="image/*,application/pdf" multiple className="hidden" onChange={(e) => handleFiles(e.target.files)} />
            {uploading
              ? <span className="flex flex-col items-center gap-2 text-forest"><Spinner size="md" /><strong>Uploading…</strong></span>
              : <><PhotoIcon className="w-8 h-8 mx-auto mb-2 text-ink-soft" /><strong className="text-forest">Click to upload</strong> photos</>}
          </label>
          {photos.length > 0 && (
            <div className="grid grid-cols-4 sm:grid-cols-6 gap-2">
              {photos.map((p, i) => (
                /* eslint-disable-next-line @next/next/no-img-element */
                <div key={p.url} className="relative aspect-square rounded-sm overflow-hidden bg-mist">
                  <img src={p.url} alt={p.name} className="w-full h-full object-cover" />
                  <button onClick={() => setPhotos((prev) => prev.filter((_, j) => j !== i))}
                    className="absolute top-0.5 right-0.5 w-4 h-4 rounded-full bg-white border border-mist text-[10px] flex items-center justify-center hover:bg-clay hover:text-white transition-colors">×</button>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
      {error && <p className="px-6 text-sm text-red-600 mb-2">{error}</p>}
      <div className="px-6 pb-6 flex gap-3">
        <Btn variant="primary" disabled={!isValid || submitting} onClick={handleSubmit}>
          {submitting ? "Submitting…" : "Submit for review"}
        </Btn>
        <Btn variant="ghost" onClick={() => { setForm(emptyForm); setPhotos([]); }}>
          Clear form
        </Btn>
      </div>
    </Card>
  );
}

// ─── Profile section ───────────────────────────────────────────────────────────
function ProfileSection({ profile, onSaveProfile, onPasswordSave }: {
  profile: { name: string; email: string; phone: string };
  onSaveProfile: (p: { name: string; email: string; phone: string }) => Promise<void>;
  onPasswordSave: (pw: { current: string; next: string; confirm: string }) => Promise<void>;
}) {
  const [editing, setEditing] = useState(false);
  const [draft, setDraft] = useState(profile);
  const [showPw, setShowPw] = useState(false);
  const [pw, setPw] = useState({ current: "", next: "", confirm: "" });
  const [pwError, setPwError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  useEffect(() => { if (!editing) setDraft(profile); }, [profile, editing]);

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

  const inputCls = "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";

  return (
    <div>
      <h2 className="font-display font-semibold text-xl text-forest-deep mb-1">Profile &amp; verification</h2>
      <p className="text-sm text-ink-soft mb-5">Manage your landlord profile and account security.</p>

      <Card className="mb-5">
        <CardHeader title="Verification status" />
        <div className="p-5 flex items-center gap-4">
          <VerificationStamp variant="landlord" size={64} />
          <div>
            <div className="font-display font-semibold text-forest-deep mb-1">Verified landlord</div>
            <div className="text-sm text-ink-soft">Your identity and property ownership have been confirmed by Villa.</div>
          </div>
        </div>
      </Card>

      <Card className="mb-5">
        <CardHeader title="Personal details" action={
          !editing
            ? <Btn variant="ghost" onClick={() => { setDraft(profile); setEditing(true); }}>Edit</Btn>
            : <div className="flex gap-2">
                <Btn variant="ghost" onClick={() => setEditing(false)}>Cancel</Btn>
                <Btn variant="primary" onClick={async () => { await onSaveProfile(draft); setEditing(false); }}>Save changes</Btn>
              </div>
        }>
        </CardHeader>
        <div className="p-5 grid grid-cols-1 sm:grid-cols-2 gap-4">
          {(["name", "email", "phone"] as const).map((f) => (
            <div key={f} className={f === "email" ? "sm:col-span-2" : ""}>
              <label className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-2">
                {f === "name" ? "Full name" : f === "email" ? "Email address" : "Phone number"}
              </label>
              <input type={f === "email" ? "email" : "text"} disabled={!editing}
                value={editing ? draft[f] : profile[f]}
                onChange={(e) => setDraft((d) => ({ ...d, [f]: e.target.value }))}
                className={inputCls} />
            </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}>
                <label className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-2">{label}</label>
                <input type="password" placeholder="••••••••" value={pw[k as keyof typeof pw]}
                  onChange={(e) => setPw((p) => ({ ...p, [k]: e.target.value }))} className={inputCls} />
              </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} disabled={busy}>{busy ? <span className="inline-flex items-center gap-2"><Spinner size="sm" />Updating…</span> : "Update password"}</Btn>
              <Btn variant="ghost" onClick={() => { setPw({ current: "", next: "", confirm: "" }); setShowPw(false); setPwError(null); }}>Cancel</Btn>
            </div>
          </div>
        )}
      </Card>
    </div>
  );
}


export default function LandlordDashboardPage() {
  const router = useRouter();
  const { user, logout } = useAuth();

  const [kycStatus, setKycStatus] = useState<KYCStatus>("not_started");
  const [section, setSection] = useState<Section>("overview");
  const [listings, setListings] = useState<Property[]>([]);
  const [viewingRequests, setViewingRequests] = useState<ViewingRequest[]>([]);
  const [msgUnread, setMsgUnread] = useState(0);
  const [msgTotal, setMsgTotal] = useState(0);
  const [profile, setProfile] = useState({ name: "", email: "", phone: "" });
  const [editingListing, setEditingListing] = useState<Property | null>(null);
  const [photoListing, setPhotoListing] = useState<Property | null>(null);
  const { show: showToast, node: toastNode } = useToast();
  const { confirm, node: confirmNode } = useConfirm();

  const unreadMessages = msgUnread;
  const pendingViewings = viewingRequests.filter((r) => r.status === "pending").length;
  const kycApproved = kycStatus === "approved";

  async function loadListings() {
    try {
      const r = await clientExecute<Paginated<Property>>("property.find-by-landlord", { limit: 100 });
      setListings(r.items);
    } catch { /* landlord may have no profile yet */ }
  }
  async function loadViewings() {
    try {
      const r = await clientExecute<Paginated<ViewingRequest>>("viewing-request.find-by-landlord", { limit: 100 });
      setViewingRequests(r.items);
    } catch { /* ignore */ }
  }

  useEffect(() => {
    (async () => {
      try {
        const s = await clientExecute<{ status: KYCStatus }>("kyc.get-status");
        setKycStatus(s.status);
      } catch { /* ignore */ }
      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 { if (user) setProfile({ name: user.name, email: user.email, phone: user.phone }); }
      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 */ }
    })();
    void loadListings();
    void loadViewings();
  }, []);

  async function handleDeleteListing(id: string, title: string) {
    const ok = await confirm({ title: "Delete listing?", body: `"${title}" will be permanently removed and will no longer appear in search. This cannot be undone.`, confirmLabel: "Yes, delete", danger: true });
    if (ok) {
      try {
        await clientExecute("property.delete", { id });
        setListings((l) => l.filter((p) => p.id !== id));
        showToast(`"${title}" deleted`);
      } catch (e) { showToast(e instanceof ApiError ? e.message : "Couldn't delete.", "error"); }
    }
  }

  async function handleToggleAvailability(listing: Property) {
    const next = listing.availability === "Available now" ? "Currently occupied" : "Available now";
    const ok = await confirm({ title: "Change availability?", body: `Mark "${listing.title}" as ${next}?`, confirmLabel: "Yes, update" });
    if (ok) {
      try {
        const updated = await clientExecute<Property>("property.toggle-availability", { id: listing.id });
        setListings((l) => l.map((p) => p.id === listing.id ? updated : p));
        showToast("Availability updated");
      } catch (e) { showToast(e instanceof ApiError ? e.message : "Couldn't update.", "error"); }
    }
  }

  async function handleSaveListing(updated: Property) {
    try {
      const saved = await clientExecute<Property>("property.update", {
        id: updated.id, title: updated.title, price: updated.price,
        availability: updated.availability, furnishing: updated.furnishing, description: updated.description,
      });
      setListings((l) => l.map((p) => p.id === updated.id ? saved : p));
      showToast(`"${saved.title}" updated`);
    } catch (e) { showToast(e instanceof ApiError ? e.message : "Couldn't save.", "error"); }
  }

  async function handleViewingAction(id: string, action: "confirmed" | "declined") {
    const req = viewingRequests.find((r) => r.id === id);
    if (!req) return;
    if (action === "declined") {
      const ok = await confirm({ title: "Decline viewing?", body: `Decline the viewing request from ${req.tenantName} for "${req.propertyTitle}"?`, confirmLabel: "Decline", danger: true });
      if (!ok) return;
    }
    try {
      await clientExecute(action === "confirmed" ? "viewing-request.confirm" : "viewing-request.decline", { id });
      setViewingRequests((prev) => prev.map((r) => r.id === id ? { ...r, status: action } : r));
      showToast(action === "confirmed" ? `Viewing confirmed with ${req.tenantName}` : `Viewing declined`);
    } catch (e) { showToast(e instanceof ApiError ? e.message : "Couldn't update.", "error"); }
  }

  async function handleAddProperty(payload: CreatePropertyPayload) {
    await clientExecute("property.create", payload); // throws → AddPropertySection shows the error
    showToast(`"${payload.title}" submitted for review`);
    void loadListings();
  }

  async function handleSaveProfile(p: { name: string; email: string; phone: string }) {
    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");
    } catch (e) { showToast(e instanceof ApiError ? e.message : "Couldn't update profile.", "error"); }
  }

  async function handlePasswordSave(pw: { current: string; next: string; confirm: string }) {
    await clientExecute("auth.change-password", pw);
    showToast("Password updated successfully");
  }

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

  const listingsPag  = usePagination(listings, 5);
  const viewingsPag  = usePagination(viewingRequests, 5);

  const navItems: { id: Section; icon: ReactNode; label: string; badge?: number; locked?: boolean }[] = [
    { id: "overview", icon: <HomeIcon />, label: "Overview" },
    { id: "listings", icon: <BookmarkIcon />, label: "My listings", badge: listings.length },
    { id: "add", icon: <PlusIcon />, label: "Add property", locked: !kycApproved },
    { id: "viewings", icon: <ApproveIcon />, label: "Viewing requests", badge: pendingViewings },
    { id: "messages", icon: <MessageIcon />, label: "Messages", badge: unreadMessages },
    { id: "profile", icon: <UserIcon />, label: "Profile & verification" },
  ];

  const statusStyle: Record<string, string> = {
    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",
  };

  // Show KYC gate if not yet approved
  if (kycStatus !== "approved") {
    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">
          <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 || "Landlord"}</div>
              <div className="font-mono text-xs uppercase tracking-widest text-ink-soft mb-2">Landlord / Agent</div>
              <span className={`inline-flex items-center gap-1.5 font-mono text-xs uppercase tracking-wider px-3.5 py-1.5 rounded-pill font-medium border ${kycStatus === "rejected" ? "bg-[#F5EAE6] text-clay border-clay" : "bg-[#FBF1E1] text-gold-deep border-gold"}`}>
                <span className="w-1.5 h-1.5 rounded-full bg-current" />
                {kycStatus === "pending" ? "KYC under review" : kycStatus === "rejected" ? "KYC rejected" : "KYC required"}
              </span>
            </div>
            <div className="flex flex-col gap-1 opacity-40 select-none">
              {["Overview", "My listings", "Add property", "Viewing requests", "Messages", "Profile"].map((l) => (
                <div key={l} className="flex items-center gap-3 px-3 py-2.5 rounded-sm text-sm font-medium text-ink-soft">{l}</div>
              ))}
            </div>
            <p className="text-xs text-ink-soft mt-4 pt-4 border-t border-mist">
              Dashboard features unlock after KYC approval.
            </p>
          </aside>
          <KYCGate status={kycStatus} />
        </div>
      </div>
    );
  }

  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 || "Landlord"}</div>
            <div className="font-mono text-xs uppercase tracking-widest text-ink-soft mb-2">Landlord / Agent</div>
            <StatusBadge status="verified" label="Verified landlord" />
          </div>
          <nav className="flex flex-col gap-1">
            {navItems.map(({ id, icon, label, badge, locked }) => (
              <button key={id}
                onClick={() => { if (!locked) setSection(id); else showToast("Complete KYC verification to add properties", "info"); }}
                title={locked ? "KYC verification required to add properties" : undefined}
                className={`flex items-center gap-3 px-3 py-2.5 rounded-sm text-sm font-medium transition-colors text-left w-full ${
                  locked ? "text-ink-soft/50 cursor-not-allowed" :
                  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>
                {locked && (
                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="w-3.5 h-3.5 shrink-0 opacity-50">
                    <rect x="3" y="11" width="18" height="11" rx="2" /><path d="M7 11V7a5 5 0 0110 0v4" strokeLinecap="round" />
                  </svg>
                )}
                {!locked && 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] || "there"}</h1>
                  <p className="text-sm text-ink-soft">Manage your listings and add new properties for review.</p>
                </div>
                {kycApproved ? (
                  <Btn variant="gold" onClick={() => setSection("add")}>+ Add property</Btn>
                ) : (
                  <button
                    onClick={() => showToast("Complete KYC verification before adding properties", "info")}
                    className="inline-flex items-center gap-2 font-semibold text-sm px-6 py-3 rounded-pill border border-mist text-ink-soft cursor-not-allowed opacity-60"
                    title="KYC verification required"
                  >
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="w-4 h-4">
                      <rect x="3" y="11" width="18" height="11" rx="2" /><path d="M7 11V7a5 5 0 0110 0v4" strokeLinecap="round" />
                    </svg>
                    Add property
                  </button>
                )}
              </div>

              <div className="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-8">
                {[
                  { label: "Active listings", value: String(listings.length), change: `${listings.filter((l) => l.status === "verified").length} verified · ${listings.filter((l) => l.status === "pending").length} pending`, action: "listings" as Section },
                  { label: "Viewing requests", value: String(viewingRequests.length), change: `${pendingViewings} awaiting your response`, action: "viewings" as Section },
                  { label: "Unread messages", value: String(unreadMessages), change: `${msgTotal} conversation${msgTotal !== 1 ? "s" : ""}`, action: "messages" as Section },
                ].map(({ label, value, change, action }) => (
                  <button key={label} onClick={() => setSection(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">{value}</div>
                    <div className="text-xs mt-1 text-forest">{change}</div>
                  </button>
                ))}
              </div>

              {/* Recent listings snapshot */}
              <Card className="mb-5">
                <CardHeader title="Recent listings" action={<Btn variant="ghost" onClick={() => setSection("listings")}>See all</Btn>} />
                <div className="overflow-x-auto">
                  <table className="w-full border-collapse">
                    <thead>
                      <tr className="bg-sage">
                        {["Property", "Price", "Status", "Availability"].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">{h}</th>
                        ))}
                      </tr>
                    </thead>
                    <tbody>
                      {listings.slice(0, 3).map((p) => (
                        <tr key={p.id} className="border-b border-mist last:border-b-0 hover:bg-sage/40">
                          <td className="px-5 py-3">
                            <div className="font-display font-semibold text-sm text-forest-deep">{p.title}</div>
                            <div className="text-xs text-ink-soft">{p.town}</div>
                          </td>
                          <td className="px-5 py-3 font-mono text-sm">{formatPrice(p.price)}</td>
                          <td className="px-5 py-3"><StatusBadge status={p.status} /></td>
                          <td className="px-5 py-3 text-sm text-ink-soft">{p.availability}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </Card>

              {/* Pending viewings */}
              {viewingRequests.filter((r) => r.status === "pending").length > 0 && (
                <Card>
                  <CardHeader title="Pending viewing requests" action={<Btn variant="ghost" onClick={() => setSection("viewings")}>See all</Btn>} />
                  <div className="divide-y divide-mist">
                    {viewingRequests.filter((r) => r.status === "pending").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-sm text-forest-deep">{r.tenantName}</div>
                          <div className="text-xs text-ink-soft">{r.propertyTitle} · {r.date}</div>
                        </div>
                        <div className="flex gap-2">
                          <Btn variant="primary" onClick={() => handleViewingAction(r.id, "confirmed")}>Confirm</Btn>
                          <Btn variant="danger" onClick={() => handleViewingAction(r.id, "declined")}>Decline</Btn>
                        </div>
                      </div>
                    ))}
                  </div>
                </Card>
              )}
            </div>
          )}

          {/* ── My listings ── */}
          {section === "listings" && (
            <div>
              <div className="flex justify-between items-center mb-4">
                <h2 className="font-display font-semibold text-xl text-forest-deep">My listings</h2>
                {kycApproved ? (
                  <Btn variant="gold" onClick={() => setSection("add")}>+ Add property</Btn>
                ) : (
                  <button
                    onClick={() => showToast("Complete KYC verification before adding properties", "info")}
                    className="inline-flex items-center gap-2 font-semibold text-sm px-5 py-2.5 rounded-pill border border-mist text-ink-soft cursor-not-allowed opacity-60"
                    title="KYC verification required"
                  >
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="w-4 h-4">
                      <rect x="3" y="11" width="18" height="11" rx="2" /><path d="M7 11V7a5 5 0 0110 0v4" strokeLinecap="round" />
                    </svg>
                    Add property
                  </button>
                )}
              </div>
              <Card>
                <CardHeader title={`${listings.length} listings`} />
                {listings.length === 0 ? (
                  <div className="text-center py-12 text-ink-soft">
                    <p className="mb-4">You have no listings yet.</p>
                    {kycApproved ? (
                      <Btn variant="primary" onClick={() => setSection("add")}>Add your first property</Btn>
                    ) : (
                      <button
                        onClick={() => showToast("Complete KYC verification before adding properties", "info")}
                        className="inline-flex items-center gap-2 font-semibold text-sm px-6 py-3 rounded-pill border border-mist text-ink-soft cursor-not-allowed opacity-60"
                      >
                        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="w-4 h-4">
                          <rect x="3" y="11" width="18" height="11" rx="2" /><path d="M7 11V7a5 5 0 0110 0v4" strokeLinecap="round" />
                        </svg>
                        Add your first property
                      </button>
                    )}
                  </div>
                ) : (
                  <>
                  <div className="overflow-x-auto">
                    <table className="w-full border-collapse">
                      <thead>
                        <tr className="bg-sage">
                          {["Property", "Price", "Status", "Availability", ""].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">{h}</th>
                          ))}
                        </tr>
                      </thead>
                      <tbody>
                        {listingsPag.paged.map((p) => (
                          <tr key={p.id} className="border-b border-mist last:border-b-0 hover:bg-sage/40 transition-colors">
                            <td className="px-5 py-4 whitespace-nowrap">
                              <div className="font-display font-semibold text-forest-deep">{p.title}</div>
                              <div className="text-xs text-ink-soft">{p.address}</div>
                            </td>
                            <td className="px-5 py-4 font-mono text-sm whitespace-nowrap">{formatPrice(p.price)}</td>
                            <td className="px-5 py-4 whitespace-nowrap"><StatusBadge status={p.status} /></td>
                            <td className="px-5 py-4 text-sm whitespace-nowrap">
                              <button onClick={() => handleToggleAvailability(p)}
                                className={`font-mono text-xs px-3 py-1.5 rounded-pill border transition-colors ${p.availability === "Available now" ? "border-forest text-forest hover:bg-forest hover:text-white" : "border-mist text-ink-soft hover:border-forest hover:text-forest"}`}>
                                {p.availability}
                              </button>
                            </td>
                            <td className="px-5 py-4">
                              <div className="flex gap-2">
                                <button onClick={() => setEditingListing(p)}
                                  className="w-8 h-8 rounded-full border border-mist bg-white text-ink-soft flex items-center justify-center hover:border-forest hover:text-forest transition-colors" title="Edit">
                                  <EditIcon className="w-4 h-4" />
                                </button>
                                <button onClick={() => setPhotoListing(p)}
                                  className="w-8 h-8 rounded-full border border-mist bg-white text-ink-soft flex items-center justify-center hover:border-forest hover:text-forest transition-colors" title="Manage photos">
                                  <PhotoIcon className="w-4 h-4" />
                                </button>
                                <button onClick={() => handleDeleteListing(p.id, p.title)}
                                  className="w-8 h-8 rounded-full border border-mist bg-white text-ink-soft flex items-center justify-center hover:border-clay hover:text-clay hover:bg-[#F5EAE6] transition-colors" title="Delete">
                                  <span className="text-sm leading-none">✕</span>
                                </button>
                              </div>
                            </td>
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  </div>
                  <TablePagination page={listingsPag.page} totalPages={listingsPag.totalPages} total={listingsPag.total} perPage={5} onPage={listingsPag.goTo} label="listing" />
                  </>
                )}
              </Card>
            </div>
          )}

          {/* ── Add property ── */}
          {section === "add" && (
            <div>
              {kycApproved ? (
                <>
                  <h2 className="font-display font-semibold text-xl text-forest-deep mb-4">Add a new property</h2>
                  <AddPropertySection onSubmit={handleAddProperty} />
                </>
              ) : (
                <div className="bg-white border border-mist rounded-md p-10 text-center max-w-lg mx-auto">
                  <div className="w-16 h-16 rounded-full bg-[#FBF1E1] flex items-center justify-center mx-auto mb-5">
                    <svg viewBox="0 0 24 24" fill="none" stroke="#B8842A" strokeWidth="1.8" className="w-8 h-8">
                      <rect x="3" y="11" width="18" height="11" rx="2" /><path d="M7 11V7a5 5 0 0110 0v4" strokeLinecap="round" />
                    </svg>
                  </div>
                  <h3 className="font-display font-semibold text-xl text-forest-deep mb-2">
                    KYC verification required
                  </h3>
                  <p className="text-sm text-ink-soft mb-6 max-w-[38ch] mx-auto">
                    You must complete and pass identity verification before you can add properties to Villa. This protects tenants and keeps the platform trustworthy.
                  </p>
                  {kycStatus === "pending" ? (
                    <div className="bg-[#FBF1E1] border border-gold rounded-md px-5 py-4 text-sm text-gold-deep mb-5">
                      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="w-4 h-4 inline-block mr-1.5 -mt-0.5 text-gold-deep"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2" strokeLinecap="round"/></svg>Your KYC application is under review — we&apos;ll notify you by email once it&apos;s approved.
                    </div>
                  ) : kycStatus === "rejected" ? (
                    <div className="bg-[#F5EAE6] border border-clay rounded-md px-5 py-4 text-sm text-clay mb-5">
                      Your verification was not approved. Please re-submit with clearer documents.
                    </div>
                  ) : null}
                  <div className="flex flex-col sm:flex-row gap-3 justify-center">
                    {(kycStatus === "not_started" || kycStatus === "rejected") && (
                      <Link href="/kyc"
                        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">
                        {kycStatus === "rejected" ? "Re-submit verification" : "Start KYC verification"}
                      </Link>
                    )}
                    <button onClick={() => setSection("overview")}
                      className="inline-flex items-center justify-center font-semibold text-sm px-6 py-3 rounded-pill border border-mist text-forest hover:bg-forest hover:border-forest hover:text-white transition-colors">
                      Back to overview
                    </button>
                  </div>
                </div>
              )}
            </div>
          )}

          {/* ── Viewing requests ── */}
          {section === "viewings" && (
            <div>
              <h2 className="font-display font-semibold text-xl text-forest-deep mb-4">Viewing requests</h2>
              <Card>
                <CardHeader title={`${viewingRequests.length} requests`} sub={`${pendingViewings} awaiting your response`} />
                {viewingRequests.length === 0 ? (
                  <div className="text-center py-12 text-sm text-ink-soft">No viewing requests yet.</div>
                ) : (
                  <div className="divide-y divide-mist">
                    {viewingsPag.paged.map((r) => (
                      <div key={r.id} className="flex flex-wrap items-center justify-between gap-4 px-5 py-4">
                        <div>
                          <div className="font-display font-semibold text-forest-deep">{r.tenantName}</div>
                          <div className="font-mono text-xs text-ink-soft">{r.tenantPhone}</div>
                          <div className="text-sm text-ink-soft mt-1">{r.propertyTitle} · {r.address}</div>
                          <div className="text-xs text-ink-soft">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" && (
                            <div className="flex gap-2">
                              <Btn variant="primary" onClick={() => handleViewingAction(r.id, "confirmed")}>Confirm</Btn>
                              <Btn variant="danger" onClick={() => handleViewingAction(r.id, "declined")}>Decline</Btn>
                            </div>
                          )}
                        </div>
                      </div>
                    ))}
                  </div>
                )}
                <TablePagination page={viewingsPag.page} totalPages={viewingsPag.totalPages} total={viewingsPag.total} perPage={5} onPage={viewingsPag.goTo} label="request" />
              </Card>
            </div>
          )}

          {/* ── Messages ── */}
          {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} onSaveProfile={handleSaveProfile} onPasswordSave={handlePasswordSave} />}

        </div>
      </div>

      {editingListing && <EditListingModal listing={editingListing} onSave={handleSaveListing} onClose={() => setEditingListing(null)} />}
      {photoListing && <PhotoManagerModal listing={photoListing} onClose={() => setPhotoListing(null)} />}
      {confirmNode}
      {toastNode}
    </div>
  );
}
