// ФриТаун — main app
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ---------- Data ----------
const PROJECTS = [
  { id: 1, name: "Алгол", type: "Кирпич", area: 142, floors: 2, beds: 4, price: 5.8, tag: "Хит" },
  { id: 2, name: "Вега", type: "Блок", area: 96, floors: 1, beds: 3, price: 3.2, tag: null },
  { id: 3, name: "Денеб", type: "Кирпич", area: 218, floors: 2, beds: 5, price: 9.4, tag: "Премиум" },
  { id: 4, name: "Сириус", type: "Блок", area: 78, floors: 1, beds: 2, price: 2.1, tag: "Эконом" },
  { id: 5, name: "Капелла", type: "Кирпич", area: 165, floors: 2, beds: 4, price: 6.6, tag: null },
  { id: 6, name: "Полярная", type: "Блок", area: 124, floors: 2, beds: 3, price: 4.4, tag: null },
  { id: 7, name: "Антарес", type: "Кирпич", area: 280, floors: 3, beds: 6, price: 13.2, tag: "Премиум" },
  { id: 8, name: "Бетельгейзе", type: "Блок", area: 110, floors: 1, beds: 3, price: 3.8, tag: null },
  { id: 9, name: "Ригель", type: "Кирпич", area: 188, floors: 2, beds: 5, price: 7.9, tag: "Хит" },
];

const PACKAGES = [
  { name: "Косметический", desc: "Покраска, обои, мелкий ремонт — за 2-3 недели.", from: 6500 },
  { name: "Капитальный", desc: "Полная замена коммуникаций, выравнивание, отделка под ключ.", from: 12500 },
  { name: "Премиум", desc: "Авторский дизайн-проект, дорогие материалы, мебель.", from: 22000 },
  { name: "Дизайн-проект", desc: "3D-визуализация, чертежи, спецификации, авторский надзор.", from: 1800 },
];

const WORKS = [
  { name: "Дом на Софийской", year: "2025", type: "Кирпичный дом, 165 м²" },
  { name: "Квартира на Псковской", year: "2024", type: "Капитальный ремонт, 92 м²" },
  { name: "Усадьба под Шимском", year: "2025", type: "Блочный дом, 220 м²" },
  { name: "Лофт на Большой С-П", year: "2024", type: "Премиум-ремонт, 110 м²" },
  { name: "Семейный дом, Деревяницы", year: "2025", type: "Кирпичный дом, 142 м²" },
  { name: "Дача на Ильмене", year: "2024", type: "Блочный дом, 96 м²" },
];

const STEPS = [
  { n: "01", t: "Заявка", d: "Звоните или оставляете заявку. Перезваниваем в течение 30 минут." },
  { n: "02", t: "Замер и смета", d: "Бесплатный выезд инженера. Точная смета без скрытых работ." },
  { n: "03", t: "Договор", d: "Фиксируем цену и срок. Аванс — 30%, остальное по этапам." },
  { n: "04", t: "Сдача под ключ", d: "Гарантия 5 лет на строительство, 2 года на ремонт." },
];

// ---------- Featured project card ----------
function FeaturedProject() {
  const data = useSiteData();
  const f = data.featured;
  const featRef = useRef(null);
  useEffect(() => {
    const el = featRef.current;
    if (!el) return;
    const t = setTimeout(() => el.classList.add("feat-landed"), 600);
    return () => clearTimeout(t);
  }, []);
  return (
    <aside className="feat feat-fly" ref={featRef}>
      <div className="feat-tag-row">
        <span className="feat-tag">
          <span className="feat-dot"></span>
          {f.tag}
        </span>
      </div>

      <div className="feat-img-wrap">
        <span className="feat-ribbon">{f.ribbon}</span>
        {(data.images || {}).featured ? (
          <div style={{ width: "100%", aspectRatio: "4 / 3", borderRadius: "var(--radius)", border: "1px solid var(--line)", overflow: "hidden" }}>
            <img src={(data.images || {}).featured} alt={f.title} style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
          </div>
        ) : (
          <image-slot
            id="hero-featured"
            shape="rounded"
            radius="8"
            placeholder="Загрузите фото в админке «Объект недели»"
            style={{ width: "100%", aspectRatio: "4 / 3", borderRadius: "var(--radius)", border: "1px solid var(--line)", overflow: "hidden" }}
          ></image-slot>
        )}
      </div>

      <div className="feat-body">
        <div className="feat-title-row">
          <h3 className="feat-title">{f.title}</h3>
          <span className="feat-area mono">{f.area}</span>
        </div>
        <div className="feat-meta">
          {f.meta}
        </div>

        <div className="feat-progress">
          {f.stages.map((s, i) => (
            <div
              className={`feat-stage ${s.done ? "done" : ""} ${s.current ? "current" : ""}`}
              key={i}
            >
              <div className="feat-stage-bar"></div>
              <div className="feat-stage-label">{s.k}</div>
            </div>
          ))}
        </div>

        <div className="feat-foot">
          <div className="feat-foot-l">
            <span className="feat-foot-eyebrow mono">До сдачи</span>
            <span className="feat-foot-val">{f.deadline}</span>
          </div>
          <div className="feat-foot-r">
            <span className="feat-foot-eyebrow mono">Бюджет</span>
            <span className="feat-foot-val">{f.budget}</span>
          </div>
        </div>
      </div>
    </aside>
  );
}

// ---------- Logo ----------
function Logo() {
  const data = useSiteData();
  const logo = (data.images || {}).logo;
  return (
    <a href="#top" className="logo">
      <span className="logo-mark">
        {logo ? (
          <img src={logo} alt={data.meta.brand} style={{ width: "100%", height: "100%", objectFit: "contain", display: "block" }} />
        ) : (
          <svg viewBox="0 0 28 28" fill="none">
            <path d="M4 13 L14 4 L24 13" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="miter" />
            <rect x="6" y="13" width="16" height="11" stroke="currentColor" strokeWidth="1.6" fill="none" />
            <rect x="12" y="17" width="4" height="7" fill="currentColor" />
          </svg>
        )}
      </span>
      <span>{data.meta.brand}</span>
    </a>
  );
}

// ---------- Navbar ----------
function Navbar({ onOpenForm }) {
  const [scrolled, setScrolled] = useState(false);
  const tabsRef = useRef(null);
  const cursorRef = useRef(null);

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

  const moveCursor = useCallback((el) => {
    if (!cursorRef.current || !tabsRef.current) return;
    const tr = tabsRef.current.getBoundingClientRect();
    const er = el.getBoundingClientRect();
    cursorRef.current.style.left = (er.left - tr.left) + "px";
    cursorRef.current.style.width = er.width + "px";
    cursorRef.current.style.opacity = "1";
  }, []);

  const hideCursor = useCallback(() => {
    if (cursorRef.current) cursorRef.current.style.opacity = "0";
  }, []);

  const navLinks = [
    { id: "proekty", label: "Проекты" },
    { id: "v-prodazhe", label: "В продаже" },
    { id: "uslugi", label: "Услуги" },
    { id: "raboty", label: "Наши работы" },
  ];

  return (
    <header className={`nav ${scrolled ? "nav--scrolled" : ""}`}>
      <div className="container nav-inner">
        <Logo />
        <ul className="nav-tabs" ref={tabsRef} onMouseLeave={hideCursor}>
          {navLinks.map(l => (
            <li key={l.id} className="nav-tab">
              <a
                href={`#${l.id}`}
                className="nav-tab-link"
                onMouseEnter={e => moveCursor(e.currentTarget)}
              >
                {l.label}
              </a>
            </li>
          ))}
          <li className="nav-cursor" ref={cursorRef}></li>
        </ul>
        <button className="nav-cta" onClick={onOpenForm}>
          <span className="shiny-text">Связаться с нами</span>
        </button>
      </div>
    </header>
  );
}

// ---------- Hero ----------
function Hero({ onOpenForm, parallax }) {
  const data = useSiteData();
  const h = data.hero;
  const bg = (data.images || {}).heroBg;
  const bgMode = h.bgMode || (bg ? "soft" : "off");
  const bgOpacity = typeof h.bgOpacity === "number" ? h.bgOpacity : 35;
  const bgPosition = h.bgPosition || "center";
  const bgBlur = Number(h.bgBlur) || 0;
  const bgTint = h.bgTint || "warm";
  const showBg = bg && bgMode !== "off";
  const brand = data.meta.brand || "";
  // Сокращение бренда: сперва ищем все заглавные буквы (включая внутренние,
  // как «Т» в «ФриТаун»). Если их меньше двух — берём первые буквы слов.
  // Если и это даёт одну букву — отдаём первые два символа слова.
  const brandShort = (() => {
    const s = brand.trim();
    if (!s) return "ФТ";
    const caps = s.match(/[A-ZА-ЯЁ]/g) || [];
    if (caps.length >= 2) return caps.slice(0, 3).join("");
    const words = s.split(/\s+/).filter(Boolean);
    if (words.length >= 2) return words.slice(0, 3).map(w => w[0]).join("").toUpperCase();
    return s.slice(0, 2).toUpperCase();
  })();
  return (
    <section
      className={`hero ${showBg ? `hero--bg hero--bg-${bgMode}` : ""}`}
      data-bg-tint={showBg ? bgTint : undefined}
      id="top"
    >
      {showBg && (
        <div className="hero-bg" aria-hidden="true">
          <div
            className="hero-bg-img"
            style={{
              backgroundImage: `url(${bg})`,
              backgroundPosition: bgPosition,
              opacity: Math.max(0, Math.min(100, bgOpacity)) / 100,
              filter: bgBlur > 0 ? `blur(${bgBlur}px)` : undefined,
            }}
          ></div>
          <div className="hero-bg-veil"></div>
        </div>
      )}
      <div className="container">
        <div className="hero-grid">
          <div>
            <h1 className="h-display hero-title hero-split">
              {renderHeroTitle(h.title)}
            </h1>
            <p className="hero-sub">{h.sub}</p>
            <div className="hero-actions">
              <button className="btn btn-primary btn-lg" onClick={onOpenForm}>
                {h.ctaPrimary}
                <span className="arrow">→</span>
              </button>
              <a className="btn btn-ghost btn-lg" href="#proekty">
                {h.ctaSecondary}
              </a>
            </div>
            <div className="spin-badge">
              <svg viewBox="0 0 200 200" className="spin-badge-svg">
                <defs>
                  <path id="circlePath" d="M100,100 m-78,0 a78,78 0 1,1 156,0 a78,78 0 1,1 -156,0" />
                </defs>
                <text>
                  <textPath href="#circlePath" textLength="490">
                    {h.spinText}
                  </textPath>
                </text>
              </svg>
              <span className="spin-badge-center">{brandShort}</span>
            </div>
          </div>
          <div className="hero-side">
            <FeaturedProject />
          </div>
        </div>

        <div className="hero-stats">
          {h.stats.map((s, i) => (
            <div className="stat" key={i}>
              <div className="stat-num">{s.num}</div>
              <div className="stat-label">{s.label}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ---------- Marquee ----------
function Marquee() {
  const data = useSiteData();
  const items = data.marquee && data.marquee.length ? data.marquee : [""];
  const full = [...items, ...items];
  return (
    <div className="marquee">
      <div className="marquee-track">
        {full.map((s, i) => (
          <span className="marquee-item" key={i}>{s}</span>
        ))}
      </div>
    </div>
  );
}

// ---------- Catalog → Проекты ----------
function Catalog({ onOpenForm }) {
  const data = useSiteData();
  const projects = data.projects || [];
  const types = data.projectTypes || [];
  const head = data.sectionTitles.projects || data.sectionTitles.catalog || { eyebrow: "01 · Проекты", title: "Проекты", sub: "" };
  const [type, setType] = useState("Все");
  const [maxArea, setMaxArea] = useState(300);
  const [activeProject, setActiveProject] = useState(null);
  const filtered = useMemo(() => {
    return projects.filter(p => (type === "Все" || p.type === type) && p.area <= maxArea);
  }, [type, maxArea, projects]);

  return (
    <section className="section" id="proekty">
      <div className="container">
        <div className="sec-head">
          <div className="lhs">
            <span className="eyebrow">{head.eyebrow}</span>
            <h2 className="h-section reveal">{head.title}</h2>
            <p>{head.sub}</p>
          </div>
          <div className="pill mono">{filtered.length} / {projects.length} проектов</div>
        </div>

        <div className="filters">
          {["Все", ...types].map(t => (
            <button key={t} className={`filter ${type === t ? "active" : ""}`} onClick={() => setType(t)}>
              {t}
            </button>
          ))}
          <div className="filter-range">
            <span className="mono">До</span>
            <input type="range" min="60" max="300" step="10" value={maxArea} onChange={e => setMaxArea(+e.target.value)} />
            <span className="mono nowrap" style={{ color: "var(--ink)", minWidth: 70 }}>{maxArea} м²</span>
          </div>
        </div>

        <div className="catalog-grid">
          {filtered.length === 0 && <div className="empty-state">— Под фильтр ничего не подходит, попробуйте расширить —</div>}
          {filtered.map((p, idx) => {
            // Считаем порядковый номер в полном списке (с учётом всех проектов, не отфильтрованных)
            const fullIdx = projects.findIndex(x => x.id === p.id);
            const numShown = (fullIdx >= 0 ? fullIdx : idx) + 1;
            return (
              <ProjectCard key={p.id} p={p} num={numShown} onOpen={() => setActiveProject(p)} />
            );
          })}
        </div>
      </div>
      <ProjectDetailsModal
        project={activeProject}
        index={activeProject ? (projects.findIndex(x => x.id === activeProject.id) + 1) : 0}
        onClose={() => setActiveProject(null)}
        onCTA={() => { setActiveProject(null); onOpenForm && onOpenForm(); }}
      />
    </section>
  );
}

// Возвращает все картинки проекта/объекта: image (главная) + gallery.
function getAllImages(p) {
  const list = [];
  if (p && p.image) list.push(p.image);
  if (p && Array.isArray(p.gallery)) {
    p.gallery.forEach(g => { if (g) list.push(g); });
  }
  return list;
}

function ProjectCard({ p, num, onOpen }) {
  const images = getAllImages(p);
  const cover = images[0];
  const numLabel = "#" + String(num).padStart(2, "0");
  return (
    <article className="card">
      <div className="card-img" onClick={onOpen} style={{ cursor: "pointer" }}>
        {cover ? (
          <img src={cover} alt={p.name} style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />
        ) : (
          <div className="ph">{p.name} · {p.type} · {p.area} м²</div>
        )}
        {p.tag && <span className="card-tag">{p.tag}</span>}
        {images.length > 1 && <span className="card-photos mono">◙ {images.length}</span>}
        <span className="card-num mono">{numLabel}</span>
      </div>
      <div className="card-body">
        <h3 className="card-title">«{p.name}»</h3>
        <div className="card-specs">
          <span>◧ {p.area} м²</span>
          <span>▢ {p.floors} эт.</span>
          <span>◉ {p.beds} спальни</span>
        </div>
        <div className="card-foot">
          <div className="card-price">
            <span className="card-price-from">От</span>
            <span className="card-price-num">{p.price.toFixed(1)} млн ₽</span>
          </div>
          <button
            type="button"
            className="card-link"
            onClick={onOpen}
            style={{ background: "transparent", border: 0, padding: 0, borderBottom: "1px solid var(--line-strong)", cursor: "pointer", font: "inherit", color: "inherit" }}
          >
            Подробнее <span className="arrow">→</span>
          </button>
        </div>
      </div>
    </article>
  );
}

// ---------- Gallery (используется в модалках) ----------
function Gallery({ images, alt, fallback }) {
  const [idx, setIdx] = React.useState(0);
  React.useEffect(() => { setIdx(0); }, [(images || []).join("|")]);
  const list = images || [];
  if (!list.length) {
    return <div className="pd-ph">{fallback}</div>;
  }
  const cur = list[idx];
  return (
    <div className="gal">
      <div className="gal-main">
        <img src={cur} alt={alt} />
        {list.length > 1 && (
          <>
            <button type="button" className="gal-nav left" onClick={() => setIdx(i => (i - 1 + list.length) % list.length)} aria-label="Назад">‹</button>
            <button type="button" className="gal-nav right" onClick={() => setIdx(i => (i + 1) % list.length)} aria-label="Вперёд">›</button>
            <span className="gal-count mono">{idx + 1} / {list.length}</span>
          </>
        )}
      </div>
      {list.length > 1 && (
        <div className="gal-thumbs">
          {list.map((src, i) => (
            <button
              key={i}
              type="button"
              className={`gal-thumb ${i === idx ? "on" : ""}`}
              onClick={() => setIdx(i)}
              aria-label={`Фото ${i + 1}`}
            >
              <img src={src} alt="" />
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// ---------- Project details modal ----------
function ProjectDetailsModal({ project, index, onClose, onCTA }) {
  React.useEffect(() => {
    if (!project) return;
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = prev;
    };
  }, [project, onClose]);

  if (!project) return null;
  const p = project;
  const features = Array.isArray(p.features) ? p.features : [];
  const breakdown = Array.isArray(p.breakdown) ? p.breakdown : [];
  const images = getAllImages(p);
  const numLabel = "#" + String(index || 1).padStart(2, "0");

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal pd-modal" onClick={(e) => e.stopPropagation()}>
        <button className="modal-close" onClick={onClose} aria-label="Закрыть">×</button>
        <div className="pd-grid">
          <div className="pd-img">
            <Gallery images={images} alt={p.name} fallback={`${p.name} · ${p.type} · ${p.area} м²`} />
            {p.tag && <span className="pd-tag">{p.tag}</span>}
            <span className="pd-num mono">{numLabel}</span>
          </div>
          <div className="pd-body">
            <div className="pd-eye mono">Проект · {p.type}</div>
            <h3 className="pd-title">«{p.name}»</h3>
            <div className="pd-specs">
              <div className="pd-spec"><span className="pd-spec-label mono">Площадь</span><span className="pd-spec-val">{p.area} м²</span></div>
              <div className="pd-spec"><span className="pd-spec-label mono">Этажей</span><span className="pd-spec-val">{p.floors}</span></div>
              <div className="pd-spec"><span className="pd-spec-label mono">Спален</span><span className="pd-spec-val">{p.beds}</span></div>
              <div className="pd-spec"><span className="pd-spec-label mono">Цена от</span><span className="pd-spec-val">{Number(p.price).toFixed(1)} млн ₽</span></div>
            </div>
            {p.description && <p className="pd-desc">{p.description}</p>}

            {breakdown.length > 0 && (
              <div className="pd-breakdown">
                <div className="pd-breakdown-head mono">Смета по этапам</div>
                <ul className="pd-breakdown-list">
                  {breakdown.map((b, i) => (
                    <li key={i}>
                      <span className="pd-breakdown-k">{b.k}</span>
                      <span className="pd-breakdown-dots" aria-hidden="true"></span>
                      <span className="pd-breakdown-v mono">{b.price}</span>
                    </li>
                  ))}
                </ul>
              </div>
            )}

            {features.length > 0 && (
              <ul className="pd-features">
                {features.map((f, i) => (
                  <li key={i}>{f}</li>
                ))}
              </ul>
            )}
            <div className="pd-actions">
              <button className="btn btn-primary btn-lg" onClick={onCTA}>
                Получить расчёт по проекту
                <span className="arrow">→</span>
              </button>
              <button className="btn btn-ghost" onClick={onClose}>
                Закрыть
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Navbar, Hero, Marquee, Catalog, Logo, FeaturedProject, ProjectDetailsModal, Gallery, getAllImages, PROJECTS, PACKAGES, WORKS, STEPS });
