/* global React, Icon */
const { useState, useEffect, useRef, useCallback } = React;

const ROUTES = [
{ key: "home", label: "Home", path: "/" },
{ key: "about", label: "About", path: "/about" },
{ key: "philosophy", label: "I.O.U. Philosophy", path: "/philosophy" },
{ key: "services", label: "Services", path: "/services" },
{ key: "contact", label: "Contact", path: "/contact" },
{ key: "disclaimer", label: "Disclaimer", path: "/disclaimer" },
{ key: "privacy", label: "Privacy Policy", path: "/privacy" },
{ key: "terms", label: "Terms of Use", path: "/terms" },
{ key: "hipaa", label: "Notice of Privacy Practices", path: "/hipaa" },
{ key: "gfe", label: "Good Faith Estimate", path: "/good-faith-estimate" },
{ key: "accessibility", label: "Accessibility", path: "/accessibility" }];

// Legal/utility routes that should NEVER appear in the main nav (still routable + footer-linked)
const LEGAL_KEYS = new Set(["disclaimer", "privacy", "terms", "hipaa", "gfe", "accessibility"]);


// ── Mini hash-router ──────────────────────────────────────────────
function useHashRoute() {
  const getRoute = () => {
    const hash = window.location.hash.replace(/^#/, "") || "/";
    const path = hash.split("?")[0]; // strip query (e.g. ?focus=slug)
    const r = ROUTES.find((r) => r.path === path);
    return r ? r.key : "home";
  };
  const [route, setRoute] = useState(getRoute);
  useEffect(() => {
    const handler = () => {
      setRoute(getRoute());
      // Skip top-scroll when navigating to a deep-linked section so the
      // services page can smooth-scroll to the focus target instead.
      const hasQuery = window.location.hash.includes("?");
      if (!hasQuery) {
        window.scrollTo({ top: 0, behavior: "instant" });
      }
    };
    window.addEventListener("hashchange", handler);
    return () => window.removeEventListener("hashchange", handler);
  }, []);
  const navigate = useCallback((path) => {
    window.location.hash = path;
  }, []);
  return [route, navigate];
}

// ── Reveal-on-scroll observer ─────────────────────────────────────
// Walks the DOM under `el`, splitting every text node into <span class="word">
// chunks while leaving inline element children (em, strong, span) alone.
// Each word gets --i set so CSS can stagger transition-delay.
function splitIntoWords(el) {
  if (el.dataset.wordsSplit === "true") return;
  let i = 0;
  const walk = (node) => {
    if (node.nodeType === Node.TEXT_NODE) {
      const parts = node.textContent.split(/(\s+)/);
      const frag = document.createDocumentFragment();
      parts.forEach((p) => {
        if (p.length === 0) return;
        if (/^\s+$/.test(p)) {
          frag.appendChild(document.createTextNode(p));
        } else {
          const w = document.createElement("span");
          w.className = "word";
          w.style.setProperty("--i", i++);
          w.textContent = p;
          frag.appendChild(w);
        }
      });
      node.replaceWith(frag);
    } else if (node.nodeType === Node.ELEMENT_NODE) {
      // Recurse into inline children so <em>, <span>, <strong> still split
      Array.from(node.childNodes).forEach(walk);
    }
  };
  Array.from(el.childNodes).forEach(walk);
  el.dataset.wordsSplit = "true";
}

function useReveal() {
  useEffect(() => {
    // Pre-process word-reveal elements so each word is its own span
    document.querySelectorAll("[data-reveal-words]").forEach(splitIntoWords);

    const sectionTargets = document.querySelectorAll(".reveal:not(.is-in)");
    const wordTargets = document.querySelectorAll("[data-reveal-words]:not(.is-revealed)");

    if (!("IntersectionObserver" in window)) {
      sectionTargets.forEach((t) => t.classList.add("is-in"));
      wordTargets.forEach((t) => t.classList.add("is-revealed"));
      return;
    }
    const obs = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          if (e.target.matches("[data-reveal-words]")) {
            e.target.classList.add("is-revealed");
          } else {
            e.target.classList.add("is-in");
          }
          obs.unobserve(e.target);
        }
      });
    }, { rootMargin: "-8% 0px -10% 0px", threshold: 0.05 });
    sectionTargets.forEach((t) => obs.observe(t));
    wordTargets.forEach((t) => obs.observe(t));
    return () => obs.disconnect();
  });
}

// ── Nav bar ───────────────────────────────────────────────────────
// Cubic-bezier helper for path morph easing. Matches the curve-menu
// transform ease so the path animates in lockstep with the slide.
function cubicBezier(p1x, p1y, p2x, p2y){
  // Solve cubic-bezier(t) for given x using Newton-Raphson.
  return function(x){
    let t = x;
    for (let i = 0; i < 8; i++){
      const cx = 3 * (1 - t) * (1 - t) * t * p1x + 3 * (1 - t) * t * t * p2x + t * t * t;
      const dx = 3 * (1 - t) * (1 - t) * (p1x) + 6 * (1 - t) * t * (p2x - p1x) + 3 * t * t * (1 - p2x);
      if (Math.abs(dx) < 1e-6) break;
      t = t - (cx - x) / dx;
      t = Math.max(0, Math.min(1, t));
    }
    return 3 * (1 - t) * (1 - t) * t * p1y + 3 * (1 - t) * t * t * p2y + t * t * t;
  };
}
const CURVE_EASE = cubicBezier(0.76, 0, 0.24, 1);

function Nav({ route, navigate, dark }) {
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  const pathRef = useRef(null);
  const animRef = useRef(0);

  // Animate SVG curve path on open/close. Bowed-out (closed) ↔ flat (open).
  useEffect(() => {
    const path = pathRef.current;
    if (!path) return;
    // Path uses the SVG's own viewBox units (100 × 1000), independent
    // of window height, preserveAspectRatio="none" stretches vertically.
    // Closed: control point pulled LEFT (-100), bowed outward (sweeps in).
    // Open: control point at 100, flat against the panel edge.
    const fromCx = open ? -100 : 100;
    const toCx   = open ? 100  : -100;
    const buildD = (cx) => `M100 0 L100 1000 Q${cx} 500 100 0 Z`;

    cancelAnimationFrame(animRef.current);
    const start = performance.now();
    const dur = 600;
    const tick = (now) => {
      const t = Math.min(1, (now - start) / dur);
      const e = CURVE_EASE(t);
      const cx = fromCx + (toCx - fromCx) * e;
      path.setAttribute("d", buildD(cx));
      if (t < 1) animRef.current = requestAnimationFrame(tick);
    };
    animRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(animRef.current);
  }, [open]);

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 24);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  useEffect(() => {setOpen(false);}, [route]);

  // Body scroll lock + ESC close when mobile menu open
  useEffect(() => {
    if (open) {
      document.body.classList.add("is-nav-open");
    } else {
      document.body.classList.remove("is-nav-open");
    }
    const onKey = (e) => { if (e.key === "Escape") setOpen(false); };
    if (open) window.addEventListener("keydown", onKey);
    return () => {
      document.body.classList.remove("is-nav-open");
      window.removeEventListener("keydown", onKey);
    };
  }, [open]);

  const cls = [
  "nav",
  scrolled && "is-scrolled",
  dark && "is-dark",
  open && "is-open"].
  filter(Boolean).join(" ");

  const handleNav = (e, path) => {
    e.preventDefault();
    navigate(path);
  };

  return (
    <header className={cls}>
      <div className="nav__inner">
        <a className="nav__brand" href="#/" onClick={(e) => handleNav(e, "/")}>
          <span style={{ color: "var(--sage-600)" }}>
            <Icon.Logo size={36} color="currentColor" />
          </span>
          <span className="nav__brand-name">I.O.U. COUNSELING SERVICES</span>
        </a>

        <nav className="nav__links">
          {ROUTES.filter((r) => !LEGAL_KEYS.has(r.key)).map((r) =>
          <a
            key={r.key}
            href={`#${r.path}`}
            className={`nav__link ${route === r.key ? "is-active" : ""}`}
            onClick={(e) => handleNav(e, r.path)}>
            {r.label}</a>
          )}
        </nav>

        <a
          className="btn btn-primary btn-sm nav__cta"
          href="#/contact"
          onClick={(e) => handleNav(e, "/contact")}>
          New Patient Inquiry</a>

        <button
          className="nav__hamburger"
          onClick={() => setOpen((o) => !o)}
          aria-label={open ? "Close menu" : "Open menu"}
          aria-expanded={open}
          aria-controls="mobile-menu">
          <span /><span /><span />
        </button>
      </div>

      {/* Curve drawer rendered to <body> via portal so the nav's
           backdrop-filter doesn't trap its position:fixed. */}
      {ReactDOM.createPortal(
      <div
        id="mobile-menu"
        className={`curve-menu${open ? " is-open" : ""}`}
        role="dialog"
        aria-modal="true"
        aria-label="Site navigation"
        aria-hidden={!open}>
        {/* SVG curve edge */}
        <svg
          className="curve-menu__svg"
          viewBox="0 0 100 1000"
          preserveAspectRatio="none"
          aria-hidden="true">
          <path
            ref={pathRef}
            className="curve-menu__path"
            d="M100 0 L100 1000 Q-100 500 100 0 Z" />
        </svg>

        {/* Inner content */}
        <div className="curve-menu__inner">
          <div className="curve-menu__head">
            <a
              className="curve-menu__brand"
              href="#/"
              onClick={(e) => handleNav(e, "/")}>
              <Icon.Logo size={36} invert />
              <span>I.O.U. COUNSELING SERVICES</span>
            </a>
            <button
              className="curve-menu__close"
              onClick={() => setOpen(false)}
              aria-label="Close menu">
              <svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round">
                <path d="M5 5l14 14M19 5L5 19" />
              </svg>
            </button>
          </div>

          <nav className="curve-menu__nav" aria-label="Primary">
            {ROUTES.filter((r) => !LEGAL_KEYS.has(r.key)).map((r, i) =>
            <a
              key={r.key}
              href={`#${r.path}`}
              className={`curve-menu__link ${route === r.key ? "is-active" : ""}`}
              onClick={(e) => handleNav(e, r.path)}
              style={{ transitionDelay: open ? `${0.12 + i * 0.04}s` : "0s" }}>
              <span className="curve-menu__num">{String(i + 1).padStart(2, "0")}</span>
              <span className="curve-menu__label">
                {r.label.split("").map((ch, j) =>
                  <span key={j} className="curve-menu__char" style={{ "--d": `${j * 0.025}s` }}>
                    {ch === " " ? "\u00A0" : ch}
                  </span>
                )}
              </span>
            </a>
            )}
          </nav>

          <div className="curve-menu__foot">
            <div className="curve-menu__contact">
              <a href="tel:+14438005555">443.800.5555</a>
              <a href="mailto:hello@ioucounseling.com">hello@ioucounseling.com</a>
            </div>
            <div className="curve-menu__legal">
              {ROUTES.filter((r) => LEGAL_KEYS.has(r.key)).map((r) =>
              <a
                key={r.key}
                href={`#${r.path}`}
                className={`curve-menu__legal-link ${route === r.key ? "is-active" : ""}`}
                onClick={(e) => handleNav(e, r.path)}>
                {r.label}
              </a>
              )}
            </div>
          </div>
        </div>
      </div>,
      document.body
      )}
    </header>);

}

// ── Footer ────────────────────────────────────────────────────────
function Footer({ navigate }) {
  const handle = (e, p) => {e.preventDefault();navigate(p);};

  return (
    <footer className="footer">
      <div className="footer__grain" />
      <div className="footer__inner">
        {/* Brand */}
        <div className="footer__brand-col">
          <a className="footer__brand" href="#/" onClick={(e) => handle(e, "/")}>
            <Icon.Logo size={56} invert />
            <span className="footer__brand-name">I.O.U. COUNSELING SERVICES</span>
          </a>
          <p className="footer__tag">
            Counseling guided by InnerStanding, OverStanding, and UnderStanding.
          </p>
          <div className="footer__social">
            <a href="#" aria-label="Instagram" onClick={(e) => e.preventDefault()}>
              <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="1.4">
                <rect x="3" y="3" width="18" height="18" rx="5" /><circle cx="12" cy="12" r="4" /><circle cx="17.5" cy="6.5" r=".7" fill="currentColor" />
              </svg>
            </a>
            <a href="#" aria-label="Facebook" onClick={(e) => e.preventDefault()}>
              <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="1.4">
                <path d="M14 8h2.5V5H14c-1.7 0-3 1.3-3 3v2H9v3h2v8h3v-8h2.5l.5-3H14V8z" fill="currentColor" stroke="none" />
              </svg>
            </a>
            <a href="#" aria-label="YouTube" onClick={(e) => e.preventDefault()}>
              <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="1.4">
                <rect x="3" y="6" width="18" height="12" rx="3" /><path d="M11 9l4 3-4 3z" fill="currentColor" stroke="none" />
              </svg>
            </a>
          </div>
        </div>

        {/* Main Page links */}
        <div className="footer__col">
          <h4>Main Page</h4>
          <ul>
            <li><a href="#/" onClick={(e) => handle(e, "/")}>Home</a></li>
            <li><a href="#/about" onClick={(e) => handle(e, "/about")}>About</a></li>
            <li><a href="#/philosophy" onClick={(e) => handle(e, "/philosophy")}>I.O.U. Philosophy</a></li>
            <li><a href="#/services" onClick={(e) => handle(e, "/services")}>Services</a></li>
            <li><a href="#/contact" onClick={(e) => handle(e, "/contact")}>Contact</a></li>
          </ul>
        </div>

        {/* Contact column */}
        <div className="footer__col">
          <h4>Contact</h4>
          <ul className="footer__contact">
            <li><span className="footer__lbl">Email:</span> gene.groves@ioucounselingservices.com</li>
            <li><span className="footer__lbl">Phone:</span> 202-286-8811</li>
            <li><span className="footer__lbl">Location:</span> Telehealth services for clients located in Maryland. Services in Washington, D.C. anticipated September 2026.</li>
          </ul>
        </div>

        {/* Legal links */}
        <div className="footer__col">
          <h4>Legal Links</h4>
          <ul>
            <li><a href="#/good-faith-estimate" onClick={(e) => handle(e, "/good-faith-estimate")}>Good Faith Estimate</a></li>
            <li><a href="#/privacy" onClick={(e) => handle(e, "/privacy")}>Privacy Policy</a></li>
            <li><a href="#/terms" onClick={(e) => handle(e, "/terms")}>Terms of Use</a></li>
            <li><a href="#/hipaa" onClick={(e) => handle(e, "/hipaa")}>Notice of Privacy Practices</a></li>
            <li><a href="#/disclaimer" onClick={(e) => handle(e, "/disclaimer")}>Disclaimer</a></li>
            <li><a href="#/accessibility" onClick={(e) => handle(e, "/accessibility")}>Accessibility</a></li>
          </ul>
        </div>
      </div>

      <div className="footer__bottom">
        <p className="footer__copyright">
          © {new Date().getFullYear()} I.O.U. Counseling Services. All rights reserved. Unauthorized
          use, reproduction, or distribution of any content on this site without written permission
          is prohibited.
        </p>
        <p className="footer__emergency">
          <span className="footer__emergency-tag">Attention</span>
          I.O.U. Counseling Services does not provide emergency or crisis services through this
          website. If you are experiencing a mental health emergency, call <strong>911</strong>, go
          to your nearest emergency room, or call/text <strong>988</strong> for the Suicide &amp;
          Crisis Lifeline. <a href="#/disclaimer" onClick={(e) => handle(e, "/disclaimer")}>Read full disclaimers →</a>
        </p>
      </div>
    </footer>);

}

// ── CTA used at bottom of pages ───────────────────────────────────
function BeginCTA({ navigate, title = "Begin Your Counseling Journey", body = "Whether you are seeking clarity, healing, or a deeper alignment with your life, I.O.U. Counseling Services offers a structured and meaningful path forward." }) {
  return (
    <section className="cta-dark">
      <div className="cta-dark__inner">
        <div className="reveal">
          <h2>{title}</h2>
          <p style={{ maxWidth: "60ch", color: "rgba(255,255,255,.78)", fontSize: 18, lineHeight: 1.6, marginTop: 24 }}>
            {body}
          </p>
          <a
            className="btn btn-primary mt-32"
            href="#/contact"
            onClick={(e) => {e.preventDefault();navigate("/contact");}}>
            New Patient Inquiry</a>
        </div>
      </div>
    </section>);

}

window.Nav = Nav;
window.Footer = Footer;
window.BeginCTA = BeginCTA;
window.useHashRoute = useHashRoute;
window.useReveal = useReveal;
window.ROUTES = ROUTES;