// Hostelova — extra sections (search demo, comparison, testimonials, FAQ, theme, float bar, scroll bar)
const { useState: useStateX, useEffect: useEffectX, useRef: useRefX } = React;

// THEME (useTheme + ThemeToggle) now lives in shared site-chrome.jsx.

// ---------- SCROLL PROGRESS BAR ----------
const ScrollProgress = () => {
  const ref = useRefX(null);
  useEffectX(() => {
    const onScroll = () => {
      const h = document.documentElement;
      const max = h.scrollHeight - window.innerHeight;
      const p = max > 0 ? (h.scrollTop / max) * 100 : 0;
      if (ref.current) ref.current.style.width = p + "%";
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return (
    <div className="scroll-progress">
      <div className="bar" ref={ref}></div>
    </div>
  );
};

// ---------- ANIMATED COUNTER ----------
const Counter = ({ to, suffix = "", duration = 1600, decimals = 0 }) => {
  const [val, setVal] = useStateX(0);
  const ref = useRefX(null);
  const started = useRefX(false);
  useEffectX(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting && !started.current) {
            started.current = true;
            const t0 = performance.now();
            const tick = (t) => {
              const p = Math.min(1, (t - t0) / duration);
              const eased = 1 - Math.pow(1 - p, 3);
              setVal(to * eased);
              if (p < 1) requestAnimationFrame(tick);
            };
            requestAnimationFrame(tick);
          }
        });
      },
      { threshold: 0.3 }
    );
    io.observe(el);
    return () => io.disconnect();
  }, [to, duration]);
  const fmt = (n) => {
    if (decimals > 0) return n.toFixed(decimals);
    if (to >= 1000) return Math.round(n).toLocaleString("en-IN");
    return Math.round(n);
  };
  return (
    <span ref={ref}>{fmt(val)}<span className="unit">{suffix}</span></span>
  );
};

// ---------- LIVE SEARCH ----------
const SUPABASE_URL = "https://vottdedphkmovjkgdukr.supabase.co";
const SUPABASE_PUBLISHABLE_KEY = "sb_publishable_BSTukl9S3dVbtVRmcq-B6Q_dw5DT61W";
const CLAIM_HOSTEL_URL = "https://hostelova.in/claim.html";

const {
  claimStatusConfig,
  normalizeClaimStatus,
  isTrustedClaimStatus,
  ClaimStatusBadge,
  truthy: isTruthy,
} = window.HostelovaBadges;

const buildClaimUrl = (hostel) => {
  const url = new URL(CLAIM_HOSTEL_URL);
  if (hostel && hostel.id) url.searchParams.set("hostel_id", hostel.id);
  if (hostel && hostel.name) url.searchParams.set("hostel", hostel.name);
  return url.toString();
};

const ClaimStatusModal = ({ hostel, onClose }) => {
  useEffectX(() => {
    if (!hostel) return undefined;
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [hostel, onClose]);

  if (!hostel) return null;
  const config = claimStatusConfig(hostel.claimStatus);
  return ReactDOM.createPortal(
    <div className="claim-modal-backdrop" onMouseDown={onClose}>
      <div className="claim-modal" role="dialog" aria-modal="true" aria-labelledby="claim-modal-title" onMouseDown={(e) => e.stopPropagation()}>
        <div className="claim-modal-head">
          <span className={`claim-modal-badge status-${config.tone}`}>{config.label}</span>
          <button type="button" className="claim-modal-close" onClick={onClose} aria-label="Close status details">
            <Icon.X width="16" height="16" />
          </button>
        </div>
        <h3 id="claim-modal-title">{config.title}</h3>
        <p>{config.text}</p>
        {hostel.claimStatus === "unclaimed" && (
          <a className="btn btn-primary claim-modal-cta" href={buildClaimUrl(hostel)} target="_blank" rel="noopener noreferrer">
            Claim this listing <Icon.ArrowRight width="14" height="14" />
          </a>
        )}
      </div>
    </div>,
    document.body
  );
};

const normalizeHostel = (row = {}, i) => {
  const amenities = Array.isArray(row.amenities) ? row.amenities : [];
  const tags = Array.isArray(row.tags) ? row.tags : [];
  const area = row.area || "Lucknow, Uttar Pradesh";
  const room = row.display_room_type || row.room_type || "";
  const college = row.college || "";
  const type = row.type || "coed";
  const rating = Number(row.rating || 0);
  const price = Number(row.price || 0);
  const claimStatus = normalizeClaimStatus(row);
  const claimConfig = claimStatusConfig(claimStatus);
  return {
    id: row.id || row.name || String(i),
    name: row.name || "Hostelova listing",
    area,
    college,
    room,
    price,
    rating,
    reviews: Number(row.reviews || 0),
    type,
    ac: isTruthy(row.ac),
    verified: isTrustedClaimStatus(claimStatus),
    featured: claimStatus === "featured",
    claimStatus,
    claimStatusLabel: claimConfig.label,
    image: row.cover_image_url || "",
    availableRooms: row.available_rooms,
    thumb: ["", "v2", "v3", "v4", "v5"][i % 5],
    searchText: [
      row.name,
      area,
      college,
      room,
      type,
      row.property_type,
      claimConfig.label,
      ...amenities,
      ...tags,
    ].filter(Boolean).join(" ").toLowerCase(),
  };
};

const fetchWebsiteHostels = async () => {
  const query = new URLSearchParams({
    select: "*",
    order: "featured.desc,created_at.desc",
    limit: "50",
  });
  const res = await fetch(`${SUPABASE_URL}/rest/v1/website_hostel_cards?${query.toString()}`, {
    headers: {
      apikey: SUPABASE_PUBLISHABLE_KEY,
      Authorization: `Bearer ${SUPABASE_PUBLISHABLE_KEY}`,
    },
  });
  if (!res.ok) throw new Error(`Hostel fetch failed: ${res.status}`);
  const rows = await res.json();
  return rows.map(normalizeHostel);
};

// ---------- LIVE STATS (real hero / about counters) ----------
// Derives a city name from a messy address ("…, Almas Bagh, Lucknow, Uttar
// Pradesh, 226003" → "lucknow") by dropping pincodes / plus-codes and taking
// the token just before the state.
const cityFromArea = (area) => {
  if (!area) return "";
  const parts = String(area).split(",").map((s) => s.trim()).filter(Boolean);
  const cleaned = parts.filter((p) => !/^\d{4,6}$/.test(p) && !/\+/.test(p));
  if (cleaned.length >= 2) return cleaned[cleaned.length - 2].toLowerCase();
  return (cleaned[cleaned.length - 1] || "").toLowerCase();
};

// Fetched once and shared across the hero + about sections (no double call).
let _statsPromise = null;
const fetchHostelStats = () => {
  if (_statsPromise) return _statsPromise;
  _statsPromise = fetchWebsiteHostels()
    .then((list) => {
      const hostels = list.length;
      const cities = new Set(
        list.map((h) => cityFromArea(h.area)).filter(Boolean)
      ).size;
      const rated = list.map((h) => Number(h.rating)).filter((v) => v > 0);
      const rating = rated.length
        ? rated.reduce((a, b) => a + b, 0) / rated.length
        : 0;
      return { hostels, cities, rating, loaded: true };
    })
    .catch(() => ({ hostels: 0, cities: 0, rating: 0, loaded: false }));
  return _statsPromise;
};

const useHostelStats = () => {
  const [stats, setStats] = useStateX({
    hostels: 0,
    cities: 0,
    rating: 0,
    loaded: false,
  });
  useEffectX(() => {
    let alive = true;
    fetchHostelStats().then((s) => {
      if (alive) setStats(s);
    });
    return () => {
      alive = false;
    };
  }, []);
  return stats;
};

const compactAddress = (value) => {
  if (!value) return "Lucknow";
  return String(value).split(",").slice(0, 2).join(",").trim() || value;
};

const hostelMeta = (h) => {
  const parts = [compactAddress(h.area)];
  if (h.college) parts.push(h.college);
  else if (h.room) parts.push(h.room);
  if (Number.isFinite(h.availableRooms) && h.availableRooms > 0) {
    parts.push(`${h.availableRooms} room${h.availableRooms === 1 ? "" : "s"} left`);
  }
  return parts.join(" · ");
};

const SearchDemo = () => {
  const [q, setQ] = useStateX("");
  const [filters, setFilters] = useStateX({ verified: false, girls: false, boys: false, coed: false, ac: false, under1500: false });
  const [saved, setSaved] = useStateX({});
  const [hostels, setHostels] = useStateX([]);
  const [loading, setLoading] = useStateX(true);
  const [error, setError] = useStateX("");
  const [statusHostel, setStatusHostel] = useStateX(null);

  useEffectX(() => {
    let alive = true;

    const loadHostels = async (silent = false) => {
      if (!silent) setLoading(true);
      try {
        const liveHostels = await fetchWebsiteHostels();
        if (!alive) return;
        setHostels(liveHostels);
        setError("");
      } catch (e) {
        if (!alive) return;
        setError("Live hostel listings could not be loaded right now.");
      } finally {
        if (alive && !silent) setLoading(false);
      }
    };

    loadHostels();
    const timer = window.setInterval(() => loadHostels(true), 60000);
    const onFocus = () => loadHostels(true);
    window.addEventListener("focus", onFocus);

    return () => {
      alive = false;
      window.clearInterval(timer);
      window.removeEventListener("focus", onFocus);
    };
  }, []);

  const toggle = (k) => setFilters((f) => ({ ...f, [k]: !f[k] }));
  const toggleSave = (n) => setSaved((s) => ({ ...s, [n]: !s[n] }));

  const filtered = hostels.filter((h) => {
    if (q) {
      const Q = q.toLowerCase();
      if (!h.searchText.includes(Q)) return false;
    }
    if (filters.verified && !isTrustedClaimStatus(h.claimStatus)) return false;
    const typeFilters = ["girls", "boys", "coed"].filter((t) => filters[t]);
    if (typeFilters.length > 0 && !typeFilters.includes(h.type)) return false;
    if (filters.ac && !h.ac) return false;
    if (filters.under1500 && h.price >= 1500) return false;
    return true;
  });

  const activeFilters = Object.entries(filters).filter(([_, v]) => v);

  const chipDefs = [
    ["verified", "Verified only", Icon.Verified],
    ["girls", "Girls PG", null],
    ["boys", "Boys hostel", null],
    ["coed", "Co-Living", null],
    ["ac", "AC rooms", null],
    ["under1500", "Under ₹1,500", null],
  ];

  return (
    <section className="demo-section" id="features" data-screen-label="06 Live Search Demo">
      <div className="container">
        <div className="section-head" style={{ marginBottom: 28 }}>
          <span className="tag"><Icon.Sparkle width="13" height="13" /> Live demo</span>
          <h2>Try a hostel search right here.</h2>
          <p>Type a college or area, tap a filter — this is exactly how Hostelova feels.</p>
        </div>

        <div className="demo-card">
          <div className="demo-head">
            <div className="lhs">
              <h3>Find a hostel in seconds.</h3>
              <p>Live listings are pulled from Hostelova, with claim status shown clearly on every card.</p>
            </div>
            <div style={{ fontSize: 12.5, color: "var(--muted)", fontWeight: 600, fontFamily: "var(--font-mono)" }}>
              {loading ? "Loading..." : `${filtered.length} match${filtered.length === 1 ? "" : "es"}`}
            </div>
          </div>

          <div className="demo-search">
            <div className="demo-field">
              <Icon.Search />
              <input
                type="text"
                placeholder="Search by college, area, or hostel name…"
                value={q}
                onChange={(e) => setQ(e.target.value)}
              />
            </div>
            <div className="demo-field" style={{ flex: "0 0 auto", color: "var(--muted)" }}>
              <Icon.Pin width="16" height="16" />
              <span style={{ fontSize: 14 }}>Lucknow, UP</span>
            </div>
            <button className="btn btn-primary" onClick={() => {}}>
              Search <Icon.ArrowRight width="14" height="14" />
            </button>
          </div>

          <div className="demo-chips">
            {chipDefs.map(([k, label, I]) => (
              <button
                key={k}
                className={"demo-chip" + (filters[k] ? " on" : "")}
                onClick={() => toggle(k)}
              >
                {I && <I width="13" height="13" />}
                {label}
                {filters[k] && <Icon.X width="11" height="11" className="x" />}
              </button>
            ))}
          </div>

          <div className="demo-results">
            {loading ? (
              <div className="demo-empty">Loading live Hostelova listings...</div>
            ) : error ? (
              <div className="demo-empty">{error}</div>
            ) : filtered.length === 0 ? (
              <div className="demo-empty">No live hostels match your filters. Try clearing one or two.</div>
            ) : (
              filtered.map((h, i) => (
                <div key={h.id} className="result-card">
                  <div
                    className={"result-thumb " + (h.image ? "has-image" : (h.thumb || ""))}
                    style={h.image ? { backgroundImage: `linear-gradient(180deg, rgba(0,0,0,.08), rgba(0,0,0,.38)), url("${h.image}")` } : undefined}
                  >
                    <div className="badges">
                      <ClaimStatusBadge hostel={h} onInfo={setStatusHostel} />
                      {h.ac && <span className="badge dark">AC</span>}
                    </div>
                    <div className={"heart" + (saved[h.name] ? " saved" : "")} onClick={() => toggleSave(h.name)}>
                      <Icon.Heart width="14" height="14" style={{ fill: saved[h.name] ? "currentColor" : "none" }} />
                    </div>
                  </div>
                  <div className="result-body">
                    <div className="result-name">{h.name}</div>
                    <div className="result-meta">{hostelMeta(h)}</div>
                    <div className="result-row">
                      <div className="result-price">{h.price ? `₹${h.price.toLocaleString("en-IN")}` : "Price on request"}<small>{h.price ? " /mo" : ""}</small></div>
                      <div className="result-rating"><Icon.Star /> {h.rating > 0 ? h.rating.toFixed(1) : "New"}</div>
                    </div>
                    <a
                      className="result-book"
                      href={`book.html#/hostel/${encodeURIComponent(h.id)}`}
                      style={{
                        display: "flex", alignItems: "center", justifyContent: "center", gap: 6,
                        marginTop: 12, height: 40, borderRadius: 12, textDecoration: "none",
                        background: "var(--primary)", color: "#fff", fontWeight: 700, fontSize: 13.5,
                        boxShadow: "0 10px 22px -10px var(--primary-glow)",
                      }}
                    >
                      View &amp; book <Icon.ArrowRight width="14" height="14" />
                    </a>
                    {h.claimStatus === "unclaimed" && (
                      <div className="claim-inline">
                        <span>Owner of this hostel?</span>
                        <a href={buildClaimUrl(h)} target="_blank" rel="noopener noreferrer">Claim this listing</a>
                      </div>
                    )}
                  </div>
                </div>
              ))
            )}
          </div>
        </div>
      </div>
      <ClaimStatusModal hostel={statusHostel} onClose={() => setStatusHostel(null)} />
    </section>
  );
};

// ---------- COMPARISON ----------
const CompareSection = () => (
  <section className="compare-section" data-screen-label="07 Compare">
    <div className="container">
      <div className="section-head">
        <span className="tag"><Icon.Sparkle width="13" height="13" /> The difference</span>
        <h2>Hostel hunting, redesigned.</h2>
        <p>What student hostel search usually looks like — vs. what it looks like with Hostelova.</p>
      </div>
      <div className="compare-grid">
        <div className="compare-card bad">
          <div className="compare-head">
            <div className="ico"><Icon.X width="18" height="18" /></div>
            <div>
              <h4>The old way</h4>
              <div className="sub">Random WhatsApp groups, broker calls, shady listings</div>
            </div>
          </div>
          <div className="compare-list">
            {[
              "Hidden monthly rent, surprise deposits, vague photos",
              "No way to verify the owner or the listing",
              "Endless DMs and calls — most go unanswered",
              "Room availability changes hourly, never published",
              "No way to save options or compare side-by-side",
              "Bad listings stay up forever with no reporting flow",
            ].map((t, i) => (
              <div key={i} className="compare-row">
                <span className="mark"><Icon.X width="12" height="12" /></span>
                <span>{t}</span>
              </div>
            ))}
          </div>
        </div>
        <div className="compare-card good">
          <div className="compare-head">
            <div className="ico"><Icon.Check width="18" height="18" /></div>
            <div>
              <h4>With Hostelova</h4>
              <div className="sub">Verified owners, transparent pricing, one clean inquiry flow</div>
            </div>
          </div>
          <div className="compare-list">
            {[
              "Monthly rent + room availability shown upfront",
              "Owner ID & listing verified before going live",
              "Single, structured inquiry — owner replies in-app",
              "Live availability per room type, updated by owner",
              "Save favorites, compare rooms, return when ready",
              "One-tap report flow with admin-reviewed moderation",
            ].map((t, i) => (
              <div key={i} className="compare-row">
                <span className="mark"><Icon.Check width="12" height="12" /></span>
                <span>{t}</span>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  </section>
);

// ---------- TESTIMONIALS ----------
const Stars5 = () => (
  <div className="stars">
    {[0,1,2,3,4].map(i => <Icon.Star key={i} width="14" height="14" />)}
  </div>
);

const TestimonialsSection = () => {
  const items = [
    { q: "Found Sunrise Hostel near Integral University in two days. Verified badge, real photos, and the rent shown was the rent I paid — no broker fees.", n: "Aanya R.", m: "Integral University · 2nd Year", c: "linear-gradient(135deg, #ff8a8a, #c4448a)" },
    { q: "Owner verification, real photos, owner replied within an hour. As a girl moving to Lucknow alone, that's exactly the trust I needed.", n: "Priya M.", m: "Amity Lucknow · 1st Year", c: "linear-gradient(135deg, #f5b769, #c4824f)", big: true },
    { q: "I list two boys hostels on Hostelova. Inquiries are serious, the dashboard shows views and leads cleanly, and the streak feature keeps me responsive.", n: "Umar K.", m: "Hostel Owner · Bakshi Ka Talab", c: "linear-gradient(135deg, #5b85ff, #2547b4)" },
    { q: "Saved 3 hostels, compared rooms, sent one booking inquiry, locked it in. The booking calendar on the Bookings tab is a small thing that really helps.", n: "Karthik S.", m: "BBD University · 3rd Year", c: "linear-gradient(135deg, #6ed3a8, #2b8c5e)" },
    { q: "The filters actually work. 'Girls PG · AC · under ₹1,500 near Gomti Nagar' — three taps and I had matches.", n: "Ananya P.", m: "King George's Medical · Lucknow", c: "linear-gradient(135deg, #c4a8e8, #7547b4)" },
  ];
  return (
    <section className="testimonials-section" data-screen-label="08 Testimonials">
      <div className="container">
        <div className="section-head">
          <span className="tag"><Icon.Quote /> Loved by students</span>
          <h2>12,000 students. One trusted way to find a hostel.</h2>
          <p>Real reviews from real students and hostel owners using Hostelova every day.</p>
        </div>
        <div className="testi-grid">
          {items.map((t, i) => (
            <div key={i} className={"testi-card" + (t.big ? " big" : "")}>
              <Stars5 />
              <p className="testi-quote">"{t.q}"</p>
              <div className="testi-person">
                <div className="person-pic" style={{ background: t.c }}>{t.n[0]}</div>
                <div>
                  <div className="person-name">{t.n}</div>
                  <div className="person-meta">{t.m}</div>
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

// ---------- FAQ ----------
const FAQ_DATA = [
  { q: "Is Hostelova free for students?", a: "Yes. The Hostelova app is completely free for students. There are no fees to search, save, compare, or send inquiries to hostel owners." },
  { q: "What does 'Unclaimed' mean?", a: "Unclaimed means the listing exists on Hostelova, but the owner has not claimed it yet. Details may be incomplete until the owner submits the claim form and our team reviews it." },
  { q: "What does 'Verified' actually mean?", a: "Verified means the owner has submitted identity or ownership proof to Hostelova, and our admin team has reviewed and approved it. Listings show a verified badge only after this step is complete." },
  { q: "How can hostel owners claim a listing?", a: "Owners can open the Claim page, submit contact details, ID proof, and ownership proof. The listing moves from Unclaimed to Claimed during review, then Verified after approval." },
  { q: "Can I book and pay through the app?", a: "Hostelova focuses on discovery and direct inquiries. You send a booking request or inquiry through the app and the owner confirms availability with you. Payment happens directly with the hostel, on your terms." },
  { q: "How is rent shown? Are there hidden fees?", a: "Monthly rent is shown upfront for every room type. Deposits, food, and any additional charges are also listed by the owner on the hostel detail page — so there are no surprises." },
  { q: "What if a listing seems fake or wrong?", a: "Every listing has a Report option. Our admin team reviews flagged listings and removes anything that doesn't meet the verification standard." },
  { q: "Are owners verified too?", a: "Yes. Owners go through identity and ownership verification before a listing receives the verified badge students see on the listing page." },
  { q: "Which cities does Hostelova cover?", a: "Hostelova currently covers Lucknow and is expanding to other major cities and college towns across UP and India. Search your area or college to see what's available today." },
];

const FAQSection = () => {
  const [open, setOpen] = useStateX(0);
  return (
    <section className="faq-section" id="faq" data-screen-label="09 FAQ">
      <div className="container">
        <div className="faq-wrap">
          <div className="faq-side">
            <span className="tag"><Icon.Chat width="14" height="14" /> Common questions</span>
            <h2>Everything you might wonder about.</h2>
            <p>The short answers most students and owners ask before downloading.</p>
            <div className="faq-help">
              <div className="ico"><Icon.Chat /></div>
              <div className="body">
                <div className="t">Still have a question?</div>
                <div className="s">Reach our support team — we reply within a few hours.</div>
              </div>
              <div className="arrow"><Icon.ArrowRight width="14" height="14" /></div>
            </div>
          </div>
          <div className="faq-list">
            {FAQ_DATA.map((f, i) => (
              <div key={i} className={"faq-item" + (open === i ? " open" : "")}>
                <div className="faq-q" onClick={() => setOpen(open === i ? -1 : i)}>
                  <span>{f.q}</span>
                  <span className="chevron"><Icon.Plus /></span>
                </div>
                <div className="faq-a">
                  <div className="faq-a-inner">{f.a}</div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
};

// ---------- FLOATING DOWNLOAD BAR ----------
const FloatBar = () => {
  const [show, setShow] = useStateX(false);
  const [dismissed, setDismissed] = useStateX(false);
  useEffectX(() => {
    const onScroll = () => {
      const y = window.scrollY;
      const max = document.documentElement.scrollHeight - window.innerHeight;
      // show after hero, hide near the very bottom (where main CTA is)
      setShow(y > 700 && y < max - 400);
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  if (dismissed) return null;
  return (
    <div className={"float-bar" + (show ? " show" : "")}>
      <div className="fb-text">
        <span className="pulse"></span>
        <span>Find your hostel in 2 minutes</span>
      </div>
      <a href="#download" className="fb-btn">
        <Icon.Download width="14" height="14" /> Get the app
      </a>
      <button className="fb-close" onClick={() => setDismissed(true)} aria-label="Dismiss">
        <Icon.X />
      </button>
    </div>
  );
};

Object.assign(window, {
  ScrollProgress, Counter,
  SearchDemo, CompareSection, TestimonialsSection, FAQSection, FloatBar,
});
