// PHYSIO SAMOS — Services page
const ServicesHero = () => {
  const { useRef } = React;
  const [t] = useT();
  const headingRef = useRef(null);
  return (
    <section className="page-hero">
      <HeroAurora />
      {/* One centred column. The <br /> that used to split the heading is gone: a hard break
          fixes the line count, and the point is that the line count follows the width.
          `.page-hero__title`'s ch-based max-width does that instead. */}
      <div className="wrap page-hero__inner">
        <span className="eyebrow">{t.nav.services}</span>
        <h1 ref={headingRef} className="page-hero__title">
          <window.VariableProximity label={t.services.title_a} containerRef={headingRef} {...window.PS.PROX} />{" "}
          <span className="serif" style={{ color: "var(--sage-dark)" }}>
            <window.VariableProximity label={t.services.title_b} containerRef={headingRef} {...window.PS.PROX} />
          </span>
        </h1>
        <p className="page-hero__lead">{t.services.lead}</p>
        <div className="page-hero__actions">
          <button className="btn btn-primary" onClick={() => window.PS.openBooking()}>
            {t.nav.book}<span className="arrow">→</span>
          </button>
          <a href="tel:+302273078420" className="btn btn-ghost">
            <Icon name="phone" size={14} /> 22730 78420
          </a>
        </div>
      </div>
    </section>
  );
};

const ServicesSpotlight = () => {
  const [t, lang] = useT();
  // These tiles are tall and narrow, so each one carries the object-position that keeps
  // its subject inside the crop.
  const spotlights = [
    { idx: 0, src: "rehab-leg-raise", pos: "40% center" },
    { idx: 1, src: "pilates-mat-class", pos: "33% center" },
    { idx: 2, src: "womens-health-treatment", pos: "62% center" },
  ];
  // No inline padding-bottom: it was a hardcoded 80px, well short of the `--section-y` step
  // every other section closes on (139px at 1547). It only passed unnoticed while the marquee
  // sat underneath and supplied the rest of the gap; with the band gone this section closes
  // the slab itself, so it takes the real step — the same one the clinic page's rooms section
  // uses. The 40px top stays: it overrides the halved `section + section` rule on purpose, to
  // sit the tiles close under the hero.
  return (
    <section style={{ paddingTop: 40 }}>
      <div className="wrap-wide">
        <div className="g g--spotlight" style={{ "--cols": "1.4fr 1fr 1fr", gap: 16, height: 480 }}>
          {spotlights.map((s, i) => {
            const item = t.services.items[s.idx];
            return (
              <a key={i} href="#services-list" className="img-overlay" style={{
                position: "relative", borderRadius: "var(--radius-lg)", overflow: "hidden",
                background: "var(--bg-2)", cursor: "pointer", display: "block",
              }}>
                <window.Img name={s.src} w={1200} sizes="(max-width: 900px) 100vw, 33vw"
                            position={s.pos} alt={item.title} className="spotlight-img"
                            style={{ width: "100%", height: "100%", objectFit: "cover", transition: "transform 600ms ease" }} />
                {/* The first spotlight is twice the width of the other two, so it takes the
                    larger step of the shared caption; the format itself is the same. */}
                <window.PhotoCaption size={i === 0 ? "lg" : "md"}
                                     title={item.title} sub={item.subtitle} />
              </a>
            );
          })}
        </div>
      </div>
    </section>
  );
};

const PricingBand = () => {
  const [t, lang] = useT();
  const items = t.pricing.items;
  return (
    <section style={{ background: "var(--bg-2)" }}>
      <div className="wrap">
        <div className="sec-head">
          <span className="eyebrow">{t.pricing.eyebrow}</span>
          <h2 className="sec-head__title">
            <window.BlurText text={t.pricing.title_a} />{" "}
            <span className="serif" style={{ color: "var(--sage-dark)" }}><window.BlurText text={t.pricing.title_b} /></span>
          </h2>
          <p className="sec-head__lead">{t.pricing.lead}</p>
        </div>
        <div style={{ borderTop: "1px solid var(--line-2)" }}>
          {items.map((it, i) => (
            <div key={i} style={{
              padding: "32px 0", borderBottom: "1px solid var(--line-2)",
              "--cols": "1.4fr 1.2fr 1fr", gap: 32, alignItems: "center",
            }} className="g g--price">
              <div style={{ fontFamily: "var(--font-display)", fontSize: 26, fontWeight: 500, letterSpacing: "-0.01em" }}>{it.k}</div>
              <div style={{ color: "var(--ink-3)", fontSize: 14 }}>{it.note}</div>
              <div style={{ fontFamily: "var(--font-display)", fontSize: 26, fontWeight: 600, color: "var(--sage-dark)", textAlign: "right" }}>{it.v}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

// One card per service, stacked by ScrollStack. The grounds and glyphs are the home services
// carousel's, deliberately: same `SVC_ACCENTS` mixed the same 55% into `--ink` (the seven raw
// accents measure 2.40:1 to 4.43:1 against cream and every one of them fails), same
// `SVC_ICONS` in dictionary order, same oversized glyph turned on all three axes. A visitor
// moving from the home page to this one should recognise the same object.
//
// There is no photography on these cards, and that is a content limit rather than a taste
// call: two of the seven services — the orthotics scan and the acupuncture — have no
// photograph of themselves in `media-src`, and a card whose picture shows a different
// treatment claims something untrue about the one it names.
const SVC_STACK_ACCENTS = ["#5F9A94", "#C08552", "#A9827C", "#8A9A5B", "#B49B57", "#547671", "#7C8FA6"];
const SVC_STACK_ICONS = ["svcOrtho", "svcExercise", "svcWomens", "svcFoot",
                         "svcMassage", "svcAcupuncture", "svcModalities"];

const ServiceStackCard = ({ item, index }) => {
  const [t] = useT();
  const accent = SVC_STACK_ACCENTS[index % SVC_STACK_ACCENTS.length];
  const icon = SVC_STACK_ICONS[index % SVC_STACK_ICONS.length];
  // Every service carries exactly one of these two: a flat list of conditions, or named
  // subgroups with a line of copy each. Both are the owner's words.
  const bullets = Array.isArray(item.bullets) ? item.bullets : [];
  const groups = Array.isArray(item.subgroups) ? item.subgroups : [];
  // The anchor id is keyed to the DICTIONARY index, not the display position: `stackOrder`
  // reorders the cards for display, and a link written against the display order would point
  // at whichever service happened to be sitting there.
  return (
    <window.ScrollStackItem itemClassName="svc-stack" id={`service-${index}`}>
      <window.SpotlightCard className="svc-stack__card" style={{ "--svc": accent }}>
        <span className="svc-stack__mark" aria-hidden="true">
          <window.Icon name={icon} size={420} />
        </span>
        <div className="svc-stack__body">
          {/* The home cards' construction: a short accent tick, then the glyph in its chip.
              No category badge — the title says what the service is, and the badge was a
              third label competing with the title and the italic subtitle under it. */}
          <div className="svc-stack__head">
            <span className="svc-stack__tick" aria-hidden="true" />
            <span className="svc-stack__icon"><window.Icon name={icon} size={22} /></span>
          </div>
          <h3 className="svc-stack__title">{item.title}</h3>
          <p className="svc-stack__sub">{item.subtitle}</p>
          <p className="svc-stack__text">{item.body}</p>
          <button className="btn btn-primary svc-stack__cta"
                  onClick={() => window.PS.openBooking()}>
            {t.ui.book_short}
          </button>
        </div>
        <div className="svc-stack__aside">
          {groups.length ? (
            <ul className="svc-stack__groups">
              {groups.map((g, i) => (
                <li key={i}>
                  <b>{g.title}</b>
                  <span>{g.body}</span>
                </li>
              ))}
            </ul>
          ) : (
            <ul className="svc-stack__tags">
              {bullets.map((b, i) => <li key={i}>{b}</li>)}
            </ul>
          )}
        </div>
      </window.SpotlightCard>
    </window.ScrollStackItem>
  );
};

// Φυσικά Μέσα leads the stack; everything else keeps dictionary order.
//
// The lead is named by its glyph rather than written as a literal index, and `index` below
// stays the item's *dictionary* position rather than its position in the stack. Both matter:
// `SVC_STACK_ICONS` and `SVC_STACK_ACCENTS` are positional against `CONTENT.services.items`,
// so ordering the cards by display position would hand every service the glyph and accent of
// whichever one used to sit there. This way the reorder is display-only and each service keeps
// its own colour and icon.

// Display order lives in components.jsx (`PS.SVC_ORDER`) so this page and the home carousel
// cannot drift apart. It used to be "the modalities card leads, the rest keep dictionary
// order"; it is now an explicit sequence, owner's call 2026-09-01.
const stackOrder = (items) => window.PS.svcOrder(items, SVC_STACK_ICONS);

const ServicesPageStack = () => {
  const { useRef, useEffect } = React;
  const [t] = useT();
  const stackTo = useRef(null);
  const order = stackOrder(t.services.items);

  // `/services#service-3` should land on that service's card, not merely somewhere in
  // the section. A native anchor jump cannot: the browser scrolls to the element's *current*
  // rect, and ScrollStack has already translated the cards, so it lands short or long by
  // however much that card happens to be offset. `scrollToRef` scrolls to the card's layout
  // position minus its own pin offset, which is exactly where it becomes the front card.
  //
  // The wait is for the fonts: card heights decide the pin offsets, and the webfont changes
  // them. Runs once on mount rather than on every hash change — these links arrive as
  // navigations from the home page, not as in-page jumps.
  useEffect(() => {
    const m = /^#service-(\d+)$/.exec(location.hash || "");
    if (!m) return;
    const src = Number(m[1]);
    const pos = order.indexOf(src);
    if (pos < 0) return;
    let cancelled = false;
    const go = () => { if (!cancelled && stackTo.current) stackTo.current(pos); };
    const ready = document.fonts && document.fonts.ready ? document.fonts.ready : Promise.resolve();
    ready.then(() => { if (cancelled) return; requestAnimationFrame(() => setTimeout(go, 60)); });
    return () => { cancelled = true; };
  }, []);

  return (
    <section id="services-list">
      <div className="wrap">
        {/* The site's standard section head — same construction as the clinic page's rooms
            and motion blocks — rather than a bare left-aligned h2 with an inline font size.

            The strings are its own. This block used to render `services.eyebrow` +
            `services.title_a`/`title_b`, which are exactly what the page hero above it sets
            as its eyebrow and h1, so the page said "Υπηρεσίες / Τι κάνουμε για εσάς" twice
            within one screen. `list_eyebrow` and `list_title_*` name the list instead.

            No `.sec-head__lead`: the hero's lead already introduces these services, and a
            second paragraph directly above the cards would put the duplication back. */}
        <div className="sec-head">
          <span className="eyebrow">{t.services.list_eyebrow}</span>
          <h2 className="sec-head__title">
            <window.BlurText text={t.services.list_title_a} />{" "}
            <span className="serif" style={{ color: "var(--sage-dark)" }}>
              <window.BlurText text={t.services.list_title_b} />
            </span>
          </h2>
        </div>
      </div>
      <div className="wrap">
        <window.ScrollStack itemDistance={72} itemScale={0.02} itemStackDistance={26}
                            stackPosition="18%" scaleEndPosition="8%" baseScale={0.88}
                            blurAmount={3} scrollToRef={stackTo}>
          {order.map((srcIndex) => (
            <ServiceStackCard key={t.services.items[srcIndex].title}
                              item={t.services.items[srcIndex]} index={srcIndex} />
          ))}
        </window.ScrollStack>
      </div>
    </section>
  );
};

const ProcessSection = () => {
  const [t, lang] = useT();
  const steps = t.process.steps;
  return (
    <section data-screen-label="Process">
      <div className="wrap">
        {/* `.sec-head` like every other section head on the site.

            It keeps its `<br />` and widens the cap to 25ch, where the other heads run at 20.
            This heading is a two-part statement and the break belongs at the roman/serif
            join; at 20ch the balancer put it mid-phrase instead ("Από το πρώτο / τηλέφωνο
            στην / πλήρη αποκατάσταση."), which reads as three fragments. 25ch is measured:
            the longest half in any of the five languages is 24 characters (Greek "στην πλήρη
            αποκατάσταση." and German "bis zur vollen Genesung."), so every language lands on
            two lines. `ch` scales with the clamped font size, so it needs no breakpoint. */}
        <div className="sec-head">
          <span className="eyebrow">{t.process.eyebrow}</span>
          <h2 className="sec-head__title" style={{ maxWidth: "25ch" }}>
            <window.BlurText text={t.process.title_a} /><br />
            <span className="serif" style={{ color: "var(--sage-dark)" }}>
              <window.BlurText text={t.process.title_b} />
            </span>
          </h2>
        </div>
        {/* This block used to be a dark --band section. The slab it sits in owns the ground
            now, so every colour here had to come back to the light-side tokens — a section
            that keeps `color: var(--on-band)` after the level takes its background away
            renders cream text on cream. */}
        <div className="g g--rule" style={{ "--cols": "repeat(4, 1fr)", gap: 0 }}>
          {steps.map((s, i) => (
            <div key={i} style={{
              padding: "0 28px 0 0",
              paddingLeft: i > 0 ? 28 : 0,
              borderLeft: i > 0 ? "1px solid var(--line)" : "none",
            }}>
              <div style={{ fontFamily: "var(--font-mono)", fontSize: 13, color: "var(--terra)",
                            letterSpacing: "0.1em", marginBottom: 24 }}>{s.n}</div>
              <h3 style={{ fontSize: 26, marginBottom: 14 }}>{s.t}</h3>
              <p style={{ color: "var(--ink-3)", fontSize: 15, lineHeight: 1.55 }}>{s.d}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

const App = () => {
  window.PS.useReveal();
  return (
    <>
      <PageBackdrop />
      <Nav current="services" />
      {/* No Marquee here. It still closes the home page's first slab, but on this page it
          listed the same treatments the stack below spells out in full, one screen later —
          the services page is the one page where that band says nothing new. Owner's call,
          2026-08-31. The slab now closes on the spotlight; the band was never what gave it
          its edge (the level's own rounded corner is), so nothing else has to change. */}
      <Level at="above"><ServicesHero /><ServicesSpotlight /></Level>
      <Level at="below"><ServicesPageStack /></Level>
      <Level at="above"><ProcessSection /></Level>
      <Level at="below"><Footer /></Level>
      <BookingModal />
    </>
  );
};
window.ServicesApp = App;
