// PHYSIO SAMOS — Legal page (Νομικά: στοιχεία επιχείρησης, πολιτική απορρήτου, cookies, όροι χρήσης)
//
// A document, not a marketing page. It keeps the site's page-hero shape so it reads as one of
// the family, then drops into one measured reading column with a sticky contents list. The
// section heads are plain h2s rather than BlurText — a privacy notice that sweeps in letter by
// letter would be theatre — and every word comes from `CONTENT[lang].legal`, with the business
// rows read from window.PS.CLINIC so the facts live once.
//
// The Greek text is the binding one (legal.binding says so on the page); the other four are
// courtesy translations. Copy changes go in the dictionaries, then `node tools/build-seo.js`.

const LegalHero = () => {
  const { useRef } = React;
  const [t, lang] = useT();
  const headingRef = useRef(null);
  // One ISO date in PS.CLINIC, formatted in the active language — no five-way translation of
  // "5 Σεπτεμβρίου 2026" to keep in step. The T00:00:00 keeps it a local date, not UTC.
  const updated = new Intl.DateTimeFormat(lang, { day: "numeric", month: "long", year: "numeric" })
    .format(new Date(window.PS.CLINIC.legalUpdated + "T00:00:00"));
  return (
    <section className="page-hero" data-screen-label="Legal hero">
      <HeroAurora />
      <div className="wrap page-hero__inner">
        <span className="eyebrow">{t.legal.eyebrow}</span>
        <h1 ref={headingRef} className="page-hero__title">
          <window.VariableProximity label={t.legal.title_a.replace(/[,.]\s*$/, "")}
                                    containerRef={headingRef} {...window.PS.PROX} />{" "}
          <span className="serif" style={{ color: "var(--sage-dark)" }}>
            <window.VariableProximity label={t.legal.title_b.replace(/\.\s*$/, "") + "."}
                                      containerRef={headingRef} {...window.PS.PROX} />
          </span>
        </h1>
        <p className="page-hero__lead">{t.legal.lead}</p>
        <p className="legal-meta mono">{t.legal.updated}: {updated}</p>
      </div>
    </section>
  );
};

// The business-details rows. A row whose value is empty is not rendered at all, so the fields
// the owner has not supplied yet (ΔΟΥ, licence) leave no placeholder behind.
const CompanyRows = () => {
  const [t] = useT();
  const C = window.PS.CLINIC;
  const f = t.legal.fields;
  const phoneHref = "tel:+30" + t.contact.phone_value.replace(/\D/g, "");
  const rows = [
    [f.name, C.legalName],
    [f.trade, C.tradeName],
    [f.form, t.legal.legalFormValue],
    [f.address, `${t.contact.address_line1}, ${t.contact.address_line2}, ${t.contact.address_line3}`],
    [f.phone, <a href={phoneHref}>+30 {t.contact.phone_value}</a>],
    [f.email, <a href={`mailto:${C.email}`}>{C.email}</a>],
    [f.vat, C.vat],
    [f.taxOffice, C.taxOffice],
    [f.gemi, C.gemi],
    [f.body, t.legal.bodyValue],
    [f.licence, C.licence],
    [f.hosting, t.legal.hostingValue],
  ].filter(([, v]) => v);
  return (
    <dl className="legal-dl">
      {rows.map(([k, v], i) => (
        <React.Fragment key={i}><dt>{k}</dt><dd>{v}</dd></React.Fragment>
      ))}
    </dl>
  );
};

// A section body is an array of strings with two markers: "## " opens an h3, "• " is a list
// item (consecutive items share one list), anything else is a paragraph. Kept this small on
// purpose — it is the whole markup vocabulary the dictionaries need for legal text.
const Body = ({ items }) => {
  const blocks = [];
  let list = null;
  items.forEach((s) => {
    if (s.startsWith("• ")) {
      if (!list) { list = []; blocks.push(list); }
      list.push(s.slice(2));
      return;
    }
    list = null;
    blocks.push(s.startsWith("## ") ? { h: s.slice(3) } : s);
  });
  return blocks.map((b, i) =>
    Array.isArray(b) ? <ul key={i}>{b.map((li, j) => <li key={j}>{li}</li>)}</ul>
    : b.h ? <h3 key={i}>{b.h}</h3>
    : <p key={i}>{b}</p>
  );
};

// Which section the reader is in: the last one whose top has passed a line a third of the way
// down the viewport. rAF-throttled on scroll and resize, the site's usual pattern, and measured
// once on mount for a deep link that lands mid-document. It drives the contents list's active
// entry (LineSidebar's `activeIndex`), so the list tells the reader where they are.
const useActiveSection = (ids) => {
  const { useState, useEffect } = React;
  const [active, setActive] = useState(0);
  const key = ids.join(",");
  useEffect(() => {
    let raf = null;
    const measure = () => {
      raf = null;
      const line = window.innerHeight * 0.35;
      let best = 0;
      ids.forEach((id, i) => {
        const el = document.getElementById(id);
        if (el && el.getBoundingClientRect().top <= line) best = i;
      });
      setActive(best);
    };
    const onScroll = () => { if (raf == null) raf = requestAnimationFrame(measure); };
    measure();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
      if (raf != null) cancelAnimationFrame(raf);
    };
  }, [key]);
  return active;
};

const LegalDocument = () => {
  const [t] = useT();
  const titles = { company: t.legal.company, privacy: t.legal.privacy, cookies: t.legal.cookies, terms: t.legal.terms };
  const ids = ["company", ...t.legal.sections.map((s) => s.id)];
  const active = useActiveSection(ids);
  return (
    <section className="legal" data-screen-label="Legal document">
      <div className="wrap legal__wrap">
        <div className="legal__toc">
          <span className="eyebrow">{t.legal.contents}</span>
          {/* React Bits LineSidebar (line-sidebar.jsx): entries lean toward the pointer, the
              current section is marked. Tuned for a 220px column: short markers, a small shift, no numbering, one entry at a
              time (snap), static ticks, a 30ms ease (owner's call, 2026-09-05: the first cut felt
              slow and busy).
              Every colour is a token; the anchors are real links, so the browser handles the
              jump and smooth-scroll.js re-syncs after it. */}
          <window.LineSidebar ariaLabel={t.legal.contents} activeIndex={active} showIndex={false}
                              items={ids.map((id) => ({ label: titles[id], href: `#${id}` }))}
                              snap scaleTick={false}
                              markerLength={28} markerGap={12} tickScale={0.5} maxShift={10}
                              itemGap={14} fontSize={0.875} smoothing={30} />
        </div>
        <article className="legal__doc">
          <section id="company">
            <h2>{t.legal.company}</h2>
            <CompanyRows />
          </section>
          {t.legal.sections.map((s) => (
            <section key={s.id} id={s.id}>
              <h2>{titles[s.id]}</h2>
              <Body items={s.body} />
            </section>
          ))}
          <p className="legal__binding">{t.legal.binding}</p>
        </article>
      </div>
    </section>
  );
};

const App = () => {
  window.PS.useReveal();
  return (
    <>
      <PageBackdrop />
      <Nav current="legal" />
      <Level at="above"><LegalHero /><LegalDocument /></Level>
      <Level at="below"><Footer /></Level>
      <BookingModal />
    </>
  );
};
window.LegalApp = App;
