/* === Shared components for all pages === */

const { useState, useEffect, useRef } = React;

/* ---------- Placeholder ---------- */
function Placeholder({ label, className = "", dark = false, style, src, alt, eager = false }) {
  if (src) {
    return (
      <div className={`placeholder has-image ${className}`} style={style}>
        <img
          src={src}
          alt={alt || label}
          loading={eager ? "eager" : "lazy"}
          decoding="async"
          style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }}
        />
      </div>
    );
  }
  return (
    <div className={`placeholder ${dark ? "dark" : ""} ${className}`} style={style}>
      <div className="placeholder-label">{label}</div>
    </div>
  );
}

/* ---------- Phone (beautiful, consistent) ---------- */
const PhoneIcon = () => (
  <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
    <path d="M3.5 2.5h2.5l1.5 3.5-1.8 1.2a8 8 0 0 0 3.6 3.6l1.2-1.8 3.5 1.5v2.5a1 1 0 0 1-1 1A11 11 0 0 1 2.5 3.5a1 1 0 0 1 1-1z" />
  </svg>
);

function Phone({ number, display, size = "md", light = false, label, sub, kind = "inline" }) {
  const cleanHref = "tel:" + number.replace(/[^\d+]/g, "");
  const sizeCls = size === "xl" ? "phone-xl" : size === "lg" ? "phone-lg" : size === "sm" ? "phone-sm" : "";

  if (kind === "box") {
    return (
      <a href={cleanHref} className="phone-box">
        {label && <div className="phone-box-label">{label}</div>}
        <span className={`phone ${sizeCls} ${light ? "phone-light" : ""}`}>
          <span className="phone-icon"><PhoneIcon /></span>
          <span>{display || number}</span>
        </span>
        {sub && <div className="phone-box-sub">{sub}</div>}
      </a>
    );
  }

  return (
    <a href={cleanHref} className={`phone ${sizeCls} ${light ? "phone-light" : ""}`}>
      <span className="phone-icon"><PhoneIcon /></span>
      <span>{display || number}</span>
    </a>
  );
}

/* ---------- Brand ---------- */
function Brand({ light = false }) {
  return (
    <a href="index.html" className="brand">
      <img
        src="https://pervaya-medklinika.ru/wp-content/uploads/2019/03/logo.png"
        alt="Первая Медицинская Клиника"
        className={`brand-logo ${light ? "brand-logo-light" : ""}`}
      />
      <div>
        <div>Первая Медицинская Клиника</div>
        <div className="brand-meta">Реконструкция позвоночника</div>
      </div>
    </a>
  );
}

/* ---------- Nav ---------- */
function Nav({ active }) {
  const links = [
    { id: "index", label: "Главная", href: "index.html" },
    { id: "method", label: "Метод", href: "method.html" },
    { id: "contact", label: "Запись", href: "contact.html" },
  ];
  return (
    <nav className="nav">
      <div className="container nav-inner">
        <Brand />
        <div className="nav-links">
          {links.map((l) => (
            <a key={l.id} href={l.href} className={active === l.id ? "active" : ""}>
              {l.label}
            </a>
          ))}
        </div>
        <div className="nav-cta">
          <a href="tel:+78129075050" className="nav-phone">+7&nbsp;(812)&nbsp;907-50-50</a>
          <a
            href="tel:+78129075050"
            className="nav-phone-icon"
            aria-label="Позвонить"
          >
            <PhoneIcon />
          </a>
          <button
            type="button"
            className="btn btn-primary"
            onClick={() => window.dispatchEvent(new CustomEvent("open-booking", { detail: { trigger: "default" } }))}
          >
            Записаться
            <span className="arrow">→</span>
          </button>
        </div>
      </div>
    </nav>
  );
}

/* ---------- Footer ---------- */
function Footer() {
  return (
    <footer className="footer">
      <div className="container">
        <div className="footer-grid">
          <div>
            <div className="brand" style={{ color: "var(--bg)", marginBottom: 20 }}>
              <img
                src="https://pervaya-medklinika.ru/wp-content/uploads/2019/03/logo.png"
                alt="Первая Медицинская Клиника"
                className="brand-logo brand-logo-light"
              />
              <div>
                <div>Первая Медицинская Клиника</div>
                <div className="brand-meta" style={{ color: "oklch(0.7 0.012 250)" }}>
                  Реконструкция позвоночника
                </div>
              </div>
            </div>
            <p style={{ fontSize: 14, lineHeight: 1.6, maxWidth: "38ch" }}>
              Безоперационное лечение суставов и позвоночника. Медикаментозная
              реконструкция межпозвонковых дисков под 3D-навигацией.
              Такси в клинику и&nbsp;обратно&nbsp;— бесплатно.*
            </p>
            <button
              type="button"
              className="btn btn-accent"
              style={{ marginTop: 20 }}
              onClick={() => window.dispatchEvent(new CustomEvent("open-booking", { detail: { trigger: "cta" } }))}
            >
              Записаться на консультацию <span className="arrow">→</span>
            </button>
          </div>
          <div>
            <h4>Навигация</h4>
            <ul>
              <li><a href="index.html">Главная</a></li>
              <li><a href="method.html">Метод</a></li>
              <li><a href="contact.html">Запись</a></li>
            </ul>
          </div>
          <div>
            <h4>Контакты</h4>
            <ul style={{ gap: 14 }}>
              <li>
                <a href="tel:+78129075050" className="phone phone-light" style={{ fontSize: 20 }}>
                  <span className="phone-icon"><PhoneIcon /></span>
                  <span>+7&nbsp;(812)&nbsp;907-50-50</span>
                </a>
              </li>
              <li>
                <a href="tel:+79119224424" className="phone phone-sm phone-light">
                  <span className="phone-icon"><PhoneIcon /></span>
                  <span>+7&nbsp;(911)&nbsp;922-44-24</span>
                </a>
              </li>
              <li><a href="mailto:med4424@yandex.ru">med4424@yandex.ru</a></li>
              <li>Снимки и заявки — на e-mail</li>
            </ul>
          </div>
          <div>
            <h4>Адрес и режим</h4>
            <ul>
              <li>190013, Санкт-Петербург</li>
              <li>ул. Рузовская, 29, лит.&nbsp;А</li>
              <li>9:00–20:00, вс — выходной</li>
              <li>Бесплатное такси · гостиница для иногородних</li>
            </ul>
          </div>
        </div>
        {typeof LegalSection !== "undefined" && <LegalSection />}
        <div className="footer-bottom">
          <div>© ООО «Е.М.К.» — Первая Медицинская Клиника</div>
          <a href="https://elektronik-studio.ru" target="_blank" rel="noopener" className="es-credit"
             style={{ display: "inline-flex", alignItems: "center", gap: 9, textDecoration: "none", textTransform: "none", letterSpacing: "normal" }}>
            <span style={{ fontSize: "11.5px", color: "#8C8579" }}>сделано в</span>
            <span className="es-logo"><img src="elektronik-logo.webp" alt="Электроник" /></span>
          </a>
          <div><a href="https://pervaya-medklinika.ru/privacy/" target="_blank" rel="noopener" style={{ color: "inherit" }}>Политика конфиденциальности</a></div>
        </div>
        <p className="footer-fineprint" style={{ fontSize: 12, lineHeight: 1.6, color: "oklch(0.64 0.012 250)", marginTop: 28, maxWidth: "80ch" }}>
          * Льготные категории граждан: жители блокадного Ленинграда, бывшие узники концлагерей, ветераны Великой&nbsp;Отечественной войны.
        </p>
      </div>
    </footer>
  );
}

/* ---------- Marquee strip ---------- */
function ScrollStrip({ items }) {
  return (
    <div className="scroll-strip">
      <span style={{ animation: "marquee 32s linear infinite" }}>
        {items.map((t, i) => (
          <React.Fragment key={i}>
            <i>·</i>
            <span style={{ display: "inline" }}>{t}</span>
          </React.Fragment>
        ))}
        {items.map((t, i) => (
          <React.Fragment key={"b" + i}>
            <i>·</i>
            <span style={{ display: "inline" }}>{t}</span>
          </React.Fragment>
        ))}
      </span>
      <style>{`@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }`}</style>
    </div>
  );
}

/* ---------- Section head ---------- */
function SectionHead({ eyebrow, title, lede }) {
  return (
    <div className="section-head">
      <div>
        <div className="eyebrow">{eyebrow}</div>
        <h2 className="serif" style={{ marginTop: 12 }}>{title}</h2>
      </div>
      {lede && <p className="lede">{lede}</p>}
    </div>
  );
}

/* ---------- Spine illustration (SVG, abstract) ---------- */
function SpineDiagram() {
  // simple, abstract: column of vertebrae shapes
  const segs = Array.from({ length: 12 });
  return (
    <svg className="spine-art" viewBox="0 0 240 400" fill="none" stroke="currentColor">
      <defs>
        <linearGradient id="sg" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0" stopColor="currentColor" stopOpacity="0.2" />
          <stop offset="1" stopColor="currentColor" stopOpacity="0.95" />
        </linearGradient>
      </defs>
      {segs.map((_, i) => {
        const y = 30 + i * 28;
        const w = 70 - Math.abs(i - 5) * 2.5;
        return (
          <g key={i}>
            <rect
              x={120 - w / 2}
              y={y}
              width={w}
              height={18}
              rx={6}
              fill="url(#sg)"
              stroke="currentColor"
              strokeOpacity={0.5}
              strokeWidth={1}
            />
            <circle cx={120} cy={y + 9} r={3} fill="currentColor" opacity={0.7} />
          </g>
        );
      })}
      {/* connector */}
      <path
        d="M 120 30 C 100 100, 140 200, 120 380"
        stroke="currentColor"
        strokeWidth="1"
        opacity="0.35"
        strokeDasharray="2 4"
      />
      {/* labels */}
      <g fontFamily="ui-monospace, monospace" fontSize="9" fill="currentColor" opacity="0.6" letterSpacing="0.06em">
        <text x="14" y="50">C1–C7</text>
        <text x="14" y="160">T1–T12</text>
        <text x="14" y="290">L1–L5</text>
        <text x="14" y="380">S1</text>
        <line x1="60" y1="46" x2="80" y2="46" stroke="currentColor" opacity="0.3" />
        <line x1="60" y1="156" x2="80" y2="156" stroke="currentColor" opacity="0.3" />
        <line x1="60" y1="286" x2="80" y2="286" stroke="currentColor" opacity="0.3" />
        <line x1="60" y1="376" x2="80" y2="376" stroke="currentColor" opacity="0.3" />
      </g>
    </svg>
  );
}

/* ---------- FAQ accordion ---------- */
function Faq({ items }) {
  const [open, setOpen] = useState(0);
  return (
    <div className="faq">
      {items.map((it, i) => (
        <div key={i} className={`faq-item ${open === i ? "open" : ""}`}>
          <button className="faq-q" onClick={() => setOpen(open === i ? -1 : i)}>
            <span>{it.q}</span>
            <span className="faq-q-icon">+</span>
          </button>
          <div className="faq-a">
            <div className="faq-a-inner" dangerouslySetInnerHTML={{ __html: it.a }} />
          </div>
        </div>
      ))}
    </div>
  );
}

/* ---------- Hero (variant-aware) ---------- */
function Hero({ variant = "editorial" }) {
  return (
    <section className={`hero ${variant === "centered" ? "centered" : ""} ${variant === "diagnostic" ? "diagnostic" : ""}`}>
      <div className="container">
        <div className="hero-grid">
          <div>
            <h1 className="hero-title">
              Реконструкция<br />
              позвоночника <em>без</em><br />
              операции.
            </h1>
            <div className="hero-cta">
              <button
                type="button"
                className="btn btn-primary"
                onClick={() => window.dispatchEvent(new CustomEvent("open-booking", { detail: { trigger: "default" } }))}
              >
                Записаться на консультацию
                <span className="arrow">→</span>
              </button>
              <a href="method.html" className="btn btn-ghost">Как проходит процедура</a>
            </div>
          </div>

          <div className="hero-side">
            {variant !== "diagnostic" ? (
              <Placeholder
                src="https://pervaya-medklinika.ru/wp-content/uploads/2020/11/1-3.jpg"
                label="Первая Медицинская Клиника"
                className="hero-image"
              />
            ) : (
              <div className="hero-image" style={{ background: "var(--bg-soft)", border: "1px solid var(--rule)", padding: 24, display: "flex", alignItems: "center", justifyContent: "center" }}>
                <SpineDiagram />
              </div>
            )}
            <div className="hero-benefits">
              <span className="hb">
                <span className="hb-mark" aria-hidden="true">
                  <svg viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M2.5 7.5 L5.8 10.5 L11.5 4" />
                  </svg>
                </span>
                Без операции
              </span>
              <span className="hb">
                <span className="hb-mark" aria-hidden="true">
                  <svg viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M2.5 7.5 L5.8 10.5 L11.5 4" />
                  </svg>
                </span>
                Без госпитализации
              </span>
              <span className="hb">
                <span className="hb-mark" aria-hidden="true">
                  <svg viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M2.5 7.5 L5.8 10.5 L11.5 4" />
                  </svg>
                </span>
                Эффект после первой процедуры
              </span>
              <span className="hb">
                <span className="hb-mark" aria-hidden="true">
                  <svg viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M2.5 7.5 L5.8 10.5 L11.5 4" />
                  </svg>
                </span>
                Бесплатная консультация
              </span>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ---------- Indications grid ---------- */
const INDICATION_DETAILS = {
  "ostex": {
    title: "Остеохондроз позвоночника",
    short: "Дегенеративные изменения дисков шейного, грудного и поясничного отделов.",
    intro: "Дистрофические изменения межпозвонковых дисков — самая распространённая причина боли в спине. Со временем диск теряет влагу и высоту, перестаёт амортизировать нагрузку.",
    bullets: [
      "Боль усиливается после нагрузки или долгого нахождения в одной позе",
      "Скованность в спине утром, проходит после движения",
      "Хруст и щелчки в позвоночнике",
      "Постепенно — снижение подвижности",
    ],
    treatment: "Лекарственный коктейль снимает воспаление и отёк вокруг диска, запускает восстановительные процессы. Эффект — после первой процедуры.",
  },
  "gryzha": {
    title: "Грыжа межпозвонкового диска",
    short: "Шейный, грудной, пояснично-крестцовый отделы. В том числе крупные грыжи.",
    intro: "Часть диска выходит за пределы фиброзного кольца и сдавливает нервный корешок или спинной мозг. Раньше это было показанием к операции — сейчас лечится безоперационно.",
    bullets: [
      "Резкая боль, отдающая в руку или ногу",
      "Прострелы, «электрические» удары",
      "Онемение, покалывание, слабость в&nbsp;конечности",
      "Не помогают обезболивающие или помогают ненадолго",
    ],
    treatment: "Коктейль препаратов прицельно вводится под 3D-навигацией в&nbsp;область диска. Снимается компрессия, уходит воспаление, диск восстанавливается.",
  },
  "sekvestr": {
    title: "Секвестрированная грыжа",
    short: "Фрагмент диска оторвался и сместился в позвоночный канал.",
    intro: "Самая сложная форма грыжи — фрагмент пульпозного ядра отделяется и попадает в&nbsp;спинномозговой канал, давит на нервные структуры.",
    bullets: [
      "Сильная боль, не поддающаяся лекарствам",
      "Серьёзное ограничение движений",
      "Возможны нарушения чувствительности",
      "Раньше — почти всегда операция",
    ],
    treatment: "Даже секвестрированную грыжу часто удаётся лечить без операции. Метод подбирается индивидуально, по результатам МРТ.",
  },
  "protruz": {
    title: "Протрузия диска",
    short: "Ранняя стадия грыжи — выпячивание без разрыва фиброзного кольца.",
    intro: "Диск выпячивается, но фиброзное кольцо ещё цело. Если начать лечение на этой стадии — можно остановить прогрессирование и&nbsp;избежать грыжи.",
    bullets: [
      "Тупая ноющая боль в спине",
      "Усиление боли при наклонах и поворотах",
      "Иногда — лёгкое онемение",
      "Симптомы могут появляться и исчезать",
    ],
    treatment: "Самая благодарная стадия для лечения. Реконструкция возвращает диск к&nbsp;нормальному состоянию, грыжа не развивается.",
  },
  "shmorl": {
    title: "Грыжи Шморля",
    short: "Вдавления диска в тело позвонка. Часто бессимптомны, но могут давать боль.",
    intro: "Особый тип грыж — диск продавливается не в спинномозговой канал, а в&nbsp;тело самого позвонка. Часто обнаруживается случайно на МРТ.",
    bullets: [
      "Боль при долгой статической нагрузке",
      "Снижение роста (в выраженных случаях)",
      "Чувство усталости в спине",
      "Иногда совсем без симптомов",
    ],
    treatment: "Лечение направлено на укрепление костной ткани вокруг вдавления и&nbsp;восстановление диска.",
  },
  "spondilo": {
    title: "Спондилоартроз",
    short: "Артроз межпозвонковых суставов с хронической болью и ограничением подвижности.",
    intro: "Износ мелких суставов позвоночника — фасеточных. Часто идёт вместе с&nbsp;остеохондрозом. Боль локальная, усиливается при определённых движениях.",
    bullets: [
      "Боль при разгибании назад",
      "Скованность по утрам",
      "Хруст при поворотах",
      "Боль усиливается к концу дня",
    ],
    treatment: "Препарат вводится в&nbsp;область поражённых суставов, снимает воспаление и&nbsp;восстанавливает суставной хрящ.",
  },
  "stenoz": {
    title: "Стеноз позвоночного канала",
    short: "Сужение канала с компрессией спинного мозга и корешков.",
    intro: "Спинномозговой канал сужается из-за разрастания костной ткани, грыжи или утолщения связок. Возникает «перемежающаяся хромота» — боль при ходьбе, проходящая в покое.",
    bullets: [
      "Боль и слабость в ногах при ходьбе",
      "Облегчение в наклоне вперёд или сидя",
      "Онемение в стопах",
      "Постепенное сокращение дистанции, которую можно пройти",
    ],
    treatment: "Реконструкция уменьшает компрессию структур канала. Возвращается возможность ходить без боли.",
  },
  "listez": {
    title: "Листез — сдвиг позвонков",
    short: "Смещение позвонка относительно соседнего. Нестабильность, хроническая боль.",
    intro: "Один позвонок «съезжает» относительно другого. Возникает нестабильность сегмента, постоянная боль, иногда корешковый синдром.",
    bullets: [
      "Хроническая боль в пояснице",
      "Усиление боли стоя или при ходьбе",
      "«Ступенька» прощупывается на спине",
      "Чувство, что «спина не держит»",
    ],
    treatment: "Восстановление диска и связочного аппарата стабилизирует сегмент. Боль уходит, позвонок перестаёт смещаться.",
  },
  "radikulit": {
    title: "Радикулит и корешковый синдром",
    short: "Сдавление нерва с прострелами в руку или ногу.",
    intro: "Воспаление или сдавление нервного корешка, выходящего из спинного мозга. Резкая боль распространяется по&nbsp;ходу нерва.",
    bullets: [
      "Острая «стреляющая» боль",
      "Боль отдаёт в конечность по чёткой линии",
      "Онемение, покалывание, иногда слабость",
      "Усиливается при кашле, чихании, натуживании",
    ],
    treatment: "Прицельное введение препарата в&nbsp;зону компрессии корешка снимает воспаление и&nbsp;боль уже в&nbsp;первые часы.",
  },
};

function IndicationsBlock() {
  const order = [
    "ostex", "gryzha", "sekvestr", "protruz",
    "shmorl", "spondilo", "stenoz", "listez", "radikulit",
  ];

  const openDetail = (key) => {
    window.dispatchEvent(new CustomEvent("open-indication", { detail: { key } }));
  };

  return (
    <div className="indications">
      {order.map((key, i) => {
        const it = INDICATION_DETAILS[key];
        return (
          <button
            key={key}
            type="button"
            className="indication"
            onClick={() => openDetail(key)}
            aria-label={`Подробнее: ${it.title}`}
          >
            <div className="indication-num">
              {String(i + 1).padStart(2, "0")} / {String(order.length).padStart(2, "0")}
            </div>
            <div className="indication-title serif">{it.title}</div>
            <div className="indication-desc">{it.short}</div>
            <div className="indication-more">
              Подробнее <span className="arrow">→</span>
            </div>
          </button>
        );
      })}
    </div>
  );
}

/* ---------- Doctor block ---------- */
function DoctorBlock() {
  const openDoctor = () => window.dispatchEvent(new CustomEvent("open-doctor"));
  return (
    <div className="doctor">
      <button
        type="button"
        className="doctor-portrait-btn"
        onClick={openDoctor}
        aria-label="Подробнее о враче"
      >
        <Placeholder
          src="https://pervaya-medklinika.ru/wp-content/uploads/2020/11/00101-931x1024.jpg"
          label="Ястребов Роман Александрович"
          className="doctor-portrait"
        />
        <span className="doctor-portrait-hint">
          Открыть профиль <span className="arrow">→</span>
        </span>
      </button>
      <div>
        <div className="doctor-role">Главный врач клиники · нейрохирург</div>
        <h2 className="doctor-name" style={{ marginTop: 12 }}>
          Ястребов<br />Роман Александрович
        </h2>
        <p className="lede" style={{ marginTop: 16 }}>
          Нейрохирург, вертебролог, артролог, ортопед-травматолог. Высшая
          квалификационная категория, стаж более {new Date().getFullYear() - 2006} лет. Реконструкцию
          межпозвонковых дисков под 3D-навигацией в&nbsp;«Первой Медицинской Клинике»
          проводит лично — таких специалистов в России не много.
        </p>
        <div className="doctor-creds">
          <div className="doctor-cred">
            <div className="doctor-cred-year">Образование</div>
            <div className="doctor-cred-text">
              Медицинский институт ПетрГУ (2001). Ординатура по&nbsp;нейрохирургии
              в&nbsp;РНХИ им.&nbsp;профессора&nbsp;А.&nbsp;Л.&nbsp;Поленова (2006).
            </div>
          </div>
          <div className="doctor-cred">
            <div className="doctor-cred-year">Категория</div>
            <div className="doctor-cred-text">Высшая квалификационная категория. Стаж более {new Date().getFullYear() - 2006} лет.</div>
          </div>
          <div className="doctor-cred">
            <div className="doctor-cred-year">Метод</div>
            <div className="doctor-cred-text">Авторская методика реконструкции межпозвонкового диска под мониторинговой 3D-навигацией</div>
          </div>
        </div>
        <div style={{ marginTop: 24, display: "flex", gap: 12, flexWrap: "wrap" }}>
          <button
            type="button"
            className="btn btn-primary"
            onClick={openDoctor}
          >
            Полный профиль врача
            <span className="arrow">→</span>
          </button>
          <button
            type="button"
            className="btn btn-ghost"
            onClick={() => window.dispatchEvent(new CustomEvent("open-booking", { detail: { trigger: "default" } }))}
          >
            Записаться на приём
          </button>
        </div>
      </div>
    </div>
  );
}

/* ---------- Testimonials ---------- */
/* Реальные отзывы со страницы https://pervaya-medklinika.ru/pervaya-medicinskaya-klinika/otzyvy/ */
function Testimonials() {
  const items = [
    {
      quote: "Проходила курс лечения у главного врача Ястребова Романа Александровича по реконструкции межпозвонковых дисков в поясничном отделе позвоночника. Уже после первой процедуры мне стало значительно легче, я смогла уснуть без боли впервые за долгое время. В течение проводимого курса все боли прошли. Доктор подарил мне вторую жизнь — жизнь без боли.",
      name: "Светлана",
      meta: "Грыжи поясничного отдела · 31.03.2020",
    },
    {
      quote: "19 июня мне должны были делать операцию по грыже. Но я боялась просто ужас. И решила проконсультироваться в «Первой Медицинской клинике». Врач убедил меня начать комплексное лечение. Сейчас на 75% самочувствие лучше — вопрос об операции уже не стоит.",
      name: "Михайлова М. Б.",
      meta: "Грыжа · 19.03.2019",
    },
    {
      quote: "С проблемами спины познакомилась с детства, падение с высоты напоминает о себе уже 26 лет. После первого курса остались очень хорошие впечатления, а главное — результаты. Сейчас закончила второй курс. Клиникой я очень довольна.",
      name: "Пешкова А. А.",
      meta: "Хронические боли в спине · 12.03.2019",
    },
    {
      quote: "Очень благодарна врачам клиники — настоящие помощники, искренне помогающие своим пациентам. Спасибо за внимание и профессионализм на каждом приёме.",
      name: "Валентина С.",
      meta: "Отзыв с сайта клиники · 28.08.2019",
    },
    {
      quote: "Обращалась с болями в тазобедренных суставах, прошла курс лечения. Боль ушла, состояние значительно улучшилось. Буду рекомендовать клинику своим знакомым.",
      name: "Галицына О. А.",
      meta: "Боли в суставах · 01.04.2019",
    },
    {
      quote: "Лечилась по поводу боли в шее. Врач подробно объяснил весь план лечения, всё прошло профессионально. Получила выписку с рекомендациями. Очень довольна результатом.",
      name: "Харатьянова М. С.",
      meta: "Шейный отдел · 17.02.2019",
    },
  ];
  const trackRef = useRef(null);
  const scrollByDir = (dir) => {
    const el = trackRef.current;
    if (!el) return;
    const card = el.querySelector(".testimonial");
    const step = card ? card.offsetWidth + 24 : el.clientWidth * 0.85;
    el.scrollBy({ left: dir * step, behavior: "smooth" });
  };

  // Медленное автодвижение отзывов: плавный дрейф с разворотом у краёв.
  // Пауза при наведении/касании; уважает prefers-reduced-motion.
  useEffect(() => {
    const el = trackRef.current;
    if (!el) return;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;

    const SPEED = 0.4; // px за кадр (~24px/с при 60fps) — медленный дрейф
    let raf = 0;
    let paused = false;
    let driftDir = 1;
    let carry = 0;

    // На время автоскролла гасим snap + smooth, иначе они дёргают дрейф.
    const prevSnap = el.style.scrollSnapType;
    const prevBehavior = el.style.scrollBehavior;
    el.style.scrollSnapType = "none";
    el.style.scrollBehavior = "auto";

    const tick = () => {
      if (!paused && el.scrollWidth > el.clientWidth + 1) {
        carry += driftDir * SPEED;
        const whole = Math.trunc(carry);
        if (whole !== 0) {
          carry -= whole;
          const max = el.scrollWidth - el.clientWidth;
          let next = el.scrollLeft + whole;
          if (next >= max) { next = max; driftDir = -1; carry = 0; }
          else if (next <= 0) { next = 0; driftDir = 1; carry = 0; }
          el.scrollLeft = next;
        }
      }
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);

    const pause = () => { paused = true; };
    const resume = () => { paused = false; };
    el.addEventListener("mouseenter", pause);
    el.addEventListener("mouseleave", resume);
    el.addEventListener("touchstart", pause, { passive: true });
    el.addEventListener("touchend", resume);
    el.addEventListener("pointerdown", pause);
    window.addEventListener("pointerup", resume);

    return () => {
      cancelAnimationFrame(raf);
      el.style.scrollSnapType = prevSnap;
      el.style.scrollBehavior = prevBehavior;
      el.removeEventListener("mouseenter", pause);
      el.removeEventListener("mouseleave", resume);
      el.removeEventListener("touchstart", pause);
      el.removeEventListener("touchend", resume);
      el.removeEventListener("pointerdown", pause);
      window.removeEventListener("pointerup", resume);
    };
  }, []);

  return (
    <div className="testimonials-wrap">
      <div className="testimonials-head">
        <span className="testimonials-hint">Листайте отзывы — свайп или стрелки</span>
        <div className="testimonials-arrows">
          <button type="button" className="t-arrow" onClick={() => scrollByDir(-1)} aria-label="Предыдущий отзыв">←</button>
          <button type="button" className="t-arrow" onClick={() => scrollByDir(1)} aria-label="Следующий отзыв">→</button>
        </div>
      </div>
      <div className="testimonials" ref={trackRef}>
        {items.map((t, i) => (
          <div key={i} className="testimonial">
            <div className="testimonial-quote serif">«{t.quote}»</div>
            <div className="testimonial-author">
              <div
                className="testimonial-avatar"
                style={{
                  background: "var(--accent-soft)",
                  color: "var(--accent-ink)",
                  display: "grid",
                  placeItems: "center",
                  fontFamily: "var(--font-serif)",
                  fontSize: 16,
                }}
              >
                {t.name[0]}
              </div>
              <div>
                <div className="testimonial-name">{t.name}</div>
                <div className="testimonial-meta">{t.meta}</div>
              </div>
            </div>
          </div>
        ))}
        <a
          className="testimonial testimonial-more"
          href="https://pervaya-medklinika.ru/pervaya-medicinskaya-klinika/otzyvy/"
          target="_blank"
          rel="noopener"
        >
          <div className="testimonial-more-plus">+</div>
          <div className="testimonial-more-text serif">Почитать остальные отзывы</div>
          <div className="testimonial-more-sub">Десятки историй пациентов на&nbsp;официальном сайте клиники <span className="arrow">→</span></div>
        </a>
      </div>
    </div>
  );
}

/* ---------- Video testimonials ---------- */
function VideoTestimonials() {
  const [lightbox, setLightbox] = useState(null);

  // Local videos served from /preview/videos/. Posters are stop-frames at t=15s.
  const videos = [
    {
      title: "Лечение грыжи позвоночника",
      author: "Реальный пациент",
      glyph: "Г",
      src: "videos/v1-otzyv-na-sait.mp4",
      poster: "videos/v1-otzyv-na-sait-poster.jpg",
    },
    {
      title: "Возвращение к подвижности",
      author: "Реальный пациент",
      glyph: "В",
      src: "videos/v2-pmk-otzyvy.mp4",
      poster: "videos/v2-pmk-otzyvy-poster.jpg",
    },
    {
      title: "После процедуры — на работе",
      author: "Реальный пациент",
      glyph: "П",
      src: "videos/v3-20240905.mp4",
      poster: "videos/v3-20240905-poster.jpg",
    },
    {
      title: "Лечение без операции",
      author: "Реальный пациент",
      glyph: "Л",
      src: "videos/v4-pmk-video.mov",
      poster: "videos/v4-pmk-video-poster.jpg",
    },
  ];

  return (
    <>
      <div className="video-grid">
        {videos.map((v, i) => (
          <a
            key={i}
            className="video-card"
            href="https://pervaya-medklinika.ru/pervaya-medicinskaya-klinika/otzyvy/"
            target="_blank"
            rel="noopener"
            onClick={(e) => {
              if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) return;
              e.preventDefault();
              setLightbox(v);
            }}
            aria-label={`Видеоотзыв: ${v.title}`}
          >
            {/* Poster frame from t=15s of each clip */}
            <div className="video-thumb" data-glyph={v.glyph} style={{ backgroundImage: `url(${v.poster})`, backgroundSize: "cover", backgroundPosition: "center" }} />
            <div className="video-play" aria-hidden="true">▶</div>
            <div className="video-meta">
              <div className="video-title">{v.title}</div>
              <div className="video-author">{v.author}</div>
            </div>
          </a>
        ))}
      </div>

      <div className="reviews-footer">
        <div className="reviews-footer-text">
          <strong>Полная коллекция видеоотзывов</strong> — на&nbsp;официальном сайте клиники.
          Десятки историй пациентов до&nbsp;и&nbsp;после процедуры.
        </div>
        <a
          href="https://pervaya-medklinika.ru/pervaya-medicinskaya-klinika/otzyvy/"
          target="_blank"
          rel="noopener"
          className="btn btn-ghost"
        >
          Все отзывы на сайте клиники
          <span className="arrow">→</span>
        </a>
      </div>

      {lightbox && (
        <div className="video-lightbox" onClick={(e) => e.target === e.currentTarget && setLightbox(null)}>
          <div className="video-lightbox-frame">
            <button className="video-lightbox-close" onClick={() => setLightbox(null)} aria-label="Закрыть">×</button>
            <video src={lightbox.src} autoPlay controls playsInline />
          </div>
        </div>
      )}
    </>
  );
}
function CtaBanner({ title, lede, btnLabel = "Записаться на консультацию" }) {
  const EMAIL = "med4424@yandex.ru";
  let ledeNode = null;
  if (lede && lede.includes(EMAIL)) {
    const parts = lede.split(EMAIL);
    ledeNode = (
      <p className="body-l" style={{ color: "oklch(0.78 0.012 250)" }}>
        {parts[0]}
        <a
          href={"mailto:" + EMAIL}
          className="uline"
          style={{ color: "var(--bg)" }}
          onClick={(e) => { e.preventDefault(); window.dispatchEvent(new CustomEvent("open-email")); }}
        >{EMAIL}</a>
        {parts.slice(1).join(EMAIL)}
      </p>
    );
  } else if (lede) {
    ledeNode = <p className="body-l" style={{ color: "oklch(0.78 0.012 250)" }}>{lede}</p>;
  }
  return (
    <section className="section dark">
      <div className="container">
        <div className="cta-banner">
          <div>
            <div className="eyebrow">Следующий шаг</div>
            <h2 className="serif" style={{ marginTop: 16, color: "var(--bg)" }}>{title}</h2>
          </div>
          <div className="cta-banner-side">
            {ledeNode}
            <div className="flex-row">
              <button
                type="button"
                className="btn btn-accent"
                onClick={() => window.dispatchEvent(new CustomEvent("open-booking", { detail: { trigger: "cta" } }))}
              >
                {btnLabel} <span className="arrow">→</span>
              </button>
              <a href="tel:+78129075050" className="phone phone-lg phone-light" style={{ marginLeft: 8 }}>
                <span className="phone-icon"><PhoneIcon /></span>
                <span>+7&nbsp;(812)&nbsp;907-50-50</span>
              </a>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ---------- Expose to window ---------- */
Object.assign(window, {
  Placeholder, Brand, Phone, PhoneIcon, Nav, Footer, ScrollStrip, SectionHead,
  SpineDiagram, Faq, Hero, IndicationsBlock, INDICATION_DETAILS, DoctorBlock,
  Testimonials, VideoTestimonials, CtaBanner,
});
