// Woodbury Resident Portal — shared data, header, toast, modal helpers.
(function () {
  window.WBR = {
    resident: {
      name: "Kofi Mensah", first: "Kofi", email: "kofi.mensah@yahoo.com", phone: "+233 20 887 3341",
      avatar: "../../assets/images/av-kofi.jpg", property: "Lashibi Townhouses", unit: "House 1",
      emergency: "Akosua Mensah · +233 24 118 0092", moveIn: "01 Jun 2024", leaseEnds: "28 May 2026", leaseLeft: 28, term: "12 months",
    },
    lease: {
      ref: "WB-LSE-2024-0417", type: "Assured Shorthold Tenancy", term: "12 months", bedrooms: 3,
      start: "01 Jun 2024", end: "28 May 2026", left: 28, total: 365,
      landlord: "Woodbury Properties Ltd", manager: "Lashibi Townhouses Office",
      terms: [
        { icon: "calendar-days", label: "Tenancy term", value: "12 months (renewable)" },
        { icon: "home", label: "Property", value: "Lashibi Townhouses · House 1" },
        { icon: "bed", label: "Bedrooms", value: "3-bedroom townhouse" },
        { icon: "paw-print", label: "Pets", value: "By written permission" },
        { icon: "users", label: "Occupancy", value: "Up to 5 residents" },
        { icon: "wrench", label: "Maintenance", value: "Landlord-covered (structural)" },
      ],
    },
    notifications: [
      { id: "n1", icon: "user-check", tone: "accent", title: "Vendor assigned", body: "AirCool HVAC will attend your AC request (MR-2041).", time: "2h ago", unread: true, go: ["Requests", "MR-2041"] },
      { id: "n2", icon: "droplet", tone: "accent", title: "Water maintenance", body: "Supply interrupted tomorrow 9am–12pm.", time: "5h ago", unread: true, go: ["Announcements"] },
      { id: "n3", icon: "calendar", tone: "brand", title: "Inspection scheduled", body: "Routine unit inspection on 22 Aug, 11:00.", time: "1d ago", unread: true, go: ["Announcements"] },
      { id: "n4", icon: "check-check", tone: "success", title: "Request resolved", body: "Your Wi-Fi router replacement is complete.", time: "3d ago", unread: false, go: ["Requests", "MR-1975"] },
    ],
    requests: [
      { id: "MR-2041", title: "AC not cooling", cat: "HVAC / Cooling", icon: "wind", stage: 1, priority: "Urgent", tone: "danger",
        desc: "Unit making a loud grinding noise and not cooling. Started overnight.", vendor: "AirCool HVAC Services", reported: "Today · 09:12",
        log: [ { icon: "user-check", tone: "accent", title: "Vendor assigned", body: "AirCool HVAC Services assigned.", time: "Today · 09:40" },
               { icon: "wrench", tone: "danger", title: "Request submitted", body: "You reported this issue.", time: "Today · 09:12" } ] },
      { id: "MR-1998", title: "Repaint living room wall", cat: "General", icon: "paintbrush", stage: 4, priority: "Low", tone: "success",
        desc: "Scuff marks on the north wall.", vendor: "Woodbury Facilities", reported: "08 Mar",
        log: [ { icon: "check-check", tone: "success", title: "Resolved", body: "Repaint completed and signed off.", time: "12 Mar · 16:40" },
               { icon: "wrench", tone: "brand", title: "Request submitted", body: "You reported this issue.", time: "08 Mar · 10:00" } ] },
      { id: "MR-1975", title: "Wi-Fi router replacement", cat: "Appliances", icon: "wifi", stage: 4, priority: "Medium", tone: "success",
        desc: "Router not holding connection.", vendor: "Accra Electricals Ltd", reported: "31 Jan",
        log: [ { icon: "check-check", tone: "success", title: "Resolved", body: "New router installed.", time: "02 Feb · 14:20" } ] },
    ],
    stages: ["Submitted", "Assigned", "Scheduled", "In Progress", "Resolved"],
    announcements: [
      { id: "a1", icon: "droplet", tone: "accent", title: "Scheduled water maintenance", body: "Water supply interrupted tomorrow 9am–12pm for pipe maintenance.", time: "2h ago", unread: true },
      { id: "a2", icon: "shield-check", tone: "success", title: "Gate access upgrade complete", body: "Your new gate remote code is active. Contact the office for a physical fob.", time: "3d ago", unread: false },
      { id: "a3", icon: "calendar", tone: "brand", title: "Quarterly inspection", body: "Routine unit inspection scheduled for 22 Aug, 11:00. No action needed.", time: "5d ago", unread: false },
    ],
    documents: [
      { name: "Signed Tenancy Agreement.pdf", meta: "248 KB · Signed 12 Apr", tag: "Lease", tone: "brand" },
      { name: "House Rules & Community Guide.pdf", meta: "1.2 MB · Updated Jan 2026", tag: "Guide", tone: "neutral" },
      { name: "ID Verification.pdf", meta: "512 KB · Verified 10 Apr", tag: "Screening", tone: "success" },
      { name: "Move-in Inspection Report.pdf", meta: "890 KB · 01 Jun 2024", tag: "Inspection", tone: "accent" },
    ],
    messages: [
      { me: false, text: "Akwaaba Kofi! This is the Lashibi Townhouses office. How can we help?", time: "09:00" },
      { me: true, text: "Hi, the AC in my unit is making a loud noise and not cooling.", time: "09:12" },
      { me: false, text: "Sorry to hear that — I've logged it as urgent and assigned AirCool HVAC. You can track progress under Requests.", time: "09:31" },
    ],
  };

  // ==========================================================================
  // DEV BACKEND WIRING (WOO-19) — hydrate the resident portal from wb-dev-api.
  // Same-origin GET /api/resident/bootstrap (Caddy proxies /api/* -> :8090).
  // Synchronous so server data is in place before any screen renders; falls
  // back SILENTLY to the inline seed above if the API is unreachable.
  // ==========================================================================
  (function wireDevApi() {
    window.WBR_API_BASE = "/api/resident";
    try {
      var xhr = new XMLHttpRequest();
      xhr.open("GET", window.WBR_API_BASE + "/bootstrap", false); // sync: block until seeded
      xhr.withCredentials = true;
      xhr.send(null);
      if (xhr.status !== 200) throw new Error("HTTP " + xhr.status);
      var B = JSON.parse(xhr.responseText);
      var R = window.WBR;
      if (B.resident) R.resident = B.resident;
      if (B.lease) R.lease = B.lease;
      if (B.notifications) R.notifications = B.notifications;
      if (B.requests) R.requests = B.requests;
      if (B.stages) R.stages = B.stages;
      if (B.announcements) R.announcements = B.announcements;
      if (B.documents) R.documents = B.documents;
      if (B.messages) R.messages = B.messages;
      window.WBR_DATA_SOURCE = "dev.api";
    } catch (e) {
      window.WBR_DATA_SOURCE = "inline-fallback";
      if (window.console && console.warn) console.warn("[WOO-19] dev.api resident bootstrap unavailable — using inline seed:", e && e.message);
    }

    // Write-through: a submitted maintenance request also POSTs to dev.api,
    // where it surfaces to the operator portal (resident -> operator bridge).
    window.WBRsubmitRequest = function (payload) {
      try {
        var x = new XMLHttpRequest();
        x.open("POST", window.WBR_API_BASE + "/requests", true);
        x.withCredentials = true;
        x.setRequestHeader("Content-Type", "application/json");
        x.send(JSON.stringify(payload || {}));
      } catch (e) {}
    };
  })();

  window.WBRHeader = function ({ eyebrow, title, sub, actions }) {
    return (
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 24, flexWrap: "wrap" }}>
        <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
          {eyebrow && <span style={{ fontFamily: "var(--font-sans)", fontWeight: 700, fontSize: 12, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--terracotta-600)" }}>{eyebrow}</span>}
          <h1 style={{ margin: 0, fontFamily: "var(--font-serif)", fontWeight: 700, fontSize: 36, lineHeight: 1.05, color: "var(--text-heading)", whiteSpace: "pre-line" }}>{title}</h1>
          {sub && <p style={{ margin: 0, fontSize: 15, color: "var(--text-body)", maxWidth: 560 }}>{sub}</p>}
        </div>
        {actions && <div style={{ display: "flex", gap: 12, flexShrink: 0 }}>{actions}</div>}
      </div>
    );
  };

  window.WBRToast = function (msg, tone) {
    let host = document.getElementById("wbr-toast-host");
    if (!host) { host = document.createElement("div"); host.id = "wbr-toast-host"; host.style.cssText = "position:fixed;right:24px;bottom:24px;z-index:2000;display:flex;flex-direction:column;gap:10px;align-items:flex-end"; document.body.appendChild(host); }
    const el = document.createElement("div");
    const bg = tone === "danger" ? "#B00320" : tone === "accent" ? "#A66533" : "#38230F";
    el.style.cssText = "display:flex;align-items:center;gap:10px;padding:13px 18px;border-radius:12px;background:" + bg + ";color:#FAF9F6;font-family:'Plus Jakarta Sans',sans-serif;font-size:14px;font-weight:600;box-shadow:0 14px 34px -12px rgba(58,36,16,.5);opacity:0;transform:translateY(8px);transition:all .18s cubic-bezier(.22,1,.36,1);max-width:360px";
    el.textContent = "✓  " + msg;
    host.appendChild(el);
    requestAnimationFrame(() => { el.style.opacity = "1"; el.style.transform = "none"; });
    setTimeout(() => { el.style.opacity = "0"; el.style.transform = "translateY(8px)"; setTimeout(() => el.remove(), 220); }, 2600);
  };

  window.WBRuseMedia = function () {
    const get = () => ({ mobile: window.matchMedia("(max-width: 767px)").matches });
    const [m, setM] = React.useState(get);
    React.useEffect(() => { const on = () => setM(get()); window.addEventListener("resize", on); return () => window.removeEventListener("resize", on); }, []);
    return m;
  };

  // Brief loading state on first mount (drives skeletons).
  window.WBRuseLoad = function (ms) {
    const [loading, setLoading] = React.useState(true);
    React.useEffect(() => { const t = setTimeout(() => setLoading(false), ms || 550); return () => clearTimeout(t); }, []);
    return loading;
  };

  window.WBREmpty = function ({ icon, title, message, action }) {
    return (
      <div style={{ display: "flex", flexDirection: "column", alignItems: "center", textAlign: "center", padding: "48px 24px", gap: 6 }}>
        <div style={{ width: 56, height: 56, borderRadius: "var(--radius-lg)", background: "var(--cream-100)", display: "flex", alignItems: "center", justifyContent: "center", marginBottom: 6 }}>
          <span className="wb-ico" style={{ width: 26, height: 26, color: "var(--text-muted)" }}><i data-lucide={icon || "inbox"}></i></span>
        </div>
        <div style={{ fontFamily: "var(--font-serif)", fontWeight: 700, fontSize: 18, color: "var(--text-heading)" }}>{title}</div>
        {message && <p style={{ margin: 0, fontSize: 14, color: "var(--text-muted)", maxWidth: 320, lineHeight: 1.5 }}>{message}</p>}
        {action && <div style={{ marginTop: 10 }}>{action}</div>}
      </div>
    );
  };

  window.WBRSkeleton = function ({ rows }) {
    rows = rows || 3;
    return (
      <div>
        <style>{"@keyframes wbrShimmer{0%{opacity:.5}50%{opacity:1}100%{opacity:.5}}"}</style>
        {Array.from({ length: rows }).map((_, r) => (
          <div key={r} style={{ display: "flex", alignItems: "center", gap: 14, padding: "18px 24px", borderTop: r ? "1px solid var(--border)" : "none" }}>
            <div style={{ width: 42, height: 42, borderRadius: "var(--radius-md)", background: "var(--cream-200)", flexShrink: 0, animation: "wbrShimmer 1.3s ease-in-out infinite" }} />
            <div style={{ flex: 1, display: "flex", flexDirection: "column", gap: 8 }}>
              <div style={{ height: 12, width: "45%", borderRadius: 6, background: "var(--cream-200)", animation: "wbrShimmer 1.3s ease-in-out infinite", animationDelay: (r * 0.08) + "s" }} />
              <div style={{ height: 10, width: "70%", borderRadius: 6, background: "var(--cream-200)", animation: "wbrShimmer 1.3s ease-in-out infinite", animationDelay: (r * 0.08 + 0.1) + "s" }} />
            </div>
            <div style={{ height: 20, width: 64, borderRadius: 9999, background: "var(--cream-200)", animation: "wbrShimmer 1.3s ease-in-out infinite" }} />
          </div>
        ))}
      </div>
    );
  };

  // Image upload dropzone with live previews (self-contained for the resident portal).
  window.WBImageUpload = function ({ label }) {
    const [imgs, setImgs] = React.useState([]);
    const ref = React.useRef(null);
    const onFiles = (e) => { const urls = Array.from(e.target.files || []).map((f) => URL.createObjectURL(f)); setImgs((s) => [...s, ...urls]); if (urls.length) window.WBRToast(urls.length + " photo" + (urls.length === 1 ? "" : "s") + " added"); };
    return (
      <div>
        {label && <div style={{ fontFamily: "var(--font-sans)", fontWeight: 700, fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--text-muted)", marginBottom: 8 }}>{label}</div>}
        <div onClick={() => ref.current && ref.current.click()} style={{ border: "2px dashed var(--border-strong)", borderRadius: "var(--radius-lg)", padding: "22px", textAlign: "center", background: "var(--cream-50)", cursor: "pointer" }}>
          <span className="wb-ico" style={{ width: 26, height: 26, color: "var(--text-muted)", display: "inline-flex" }}><i data-lucide="image-plus"></i></span>
          <div style={{ fontWeight: 600, fontSize: 14, color: "var(--text-heading)", marginTop: 8 }}>Click to upload photos</div>
        </div>
        <input ref={ref} type="file" accept="image/*" multiple onChange={onFiles} style={{ display: "none" }} />
        {imgs.length > 0 && <div style={{ display: "flex", gap: 10, flexWrap: "wrap", marginTop: 12 }}>{imgs.map((u) => <div key={u} style={{ width: 70, height: 70, borderRadius: "var(--radius-md)", overflow: "hidden", boxShadow: "inset 0 0 0 1px var(--border)" }}><img src={u} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} /></div>)}</div>}
      </div>
    );
  };
})();
