/* eslint-disable no-unused-vars */
/* global React, ReactDOM, Comagic, ym */

// React hooks будут доступны через window.React

// ===================== HELPERS / GLOBALS =====================
// Всё в IIFE, чтобы не мусорить в области видимости, и с идемпотентными проверками.
(() => {
  // Нейтральные заглушки, если аналитика не подключена
  window.ym = window.ym || function () {};

  // Safe WA opener (не упадёт, если трекер не подключён)
  if (typeof window.openWhatsAppTracked !== 'function') {
    window.openWhatsAppTracked = (url, opts = {}) => {
      try {
        // Я.Метрика (если нужна цель)
        if (opts.goal) {
          const counterId = opts.counterId || 104121210;
          window.ym?.(counterId, 'reachGoal', opts.goal);
        }
      } catch (e) {}

      try {
        // UIS трекинг события (но НЕ открываем WhatsApp через UIS)
        if (typeof window.Comagic?.trackEvent === 'function') {
          window.Comagic.trackEvent(
            'Click',
            'WhatsApp',
            `site_${opts.label || 'open'}`,
            '1'
          );
        }
      } catch (e) {}

      // Открываем WhatsApp обычным способом (чтобы сохранить текст)
      window.open(url, '_blank', 'noopener,noreferrer');
    };
  }

  // Удобный синоним (где-то в коде встречается)
  if (typeof window.forwardWA !== 'function') {
    window.forwardWA = (url, opts) =>
      (window.openWhatsAppTracked && window.openWhatsAppTracked(url, opts)) ||
      window.open(url, '_blank');
  }

  // Используем глобальную функцию sendLeadToUIS из index.html
})();

// ===================== HELPERS / GLOBALS =====================
// Safe WA opener (не ломается, если трекер не подключён)
if (!window.openWhatsAppTracked) {
  window.openWhatsAppTracked = (url) => window.open(url, '_blank');
}

// Делает из "Дом 6×4 + веранда — Апрелевка" → "Дом 6×4 — Апрелевка"
function shortTitle(full) {
  if (!full) return '';
  const [leftRaw = '', city = ''] = full.split('—').map((s) => s.trim());
  let left = leftRaw;
  // 1) убираем «+ веранда …» / «вкл. веранду …» / «с верандой …» / «+ терраса …»
  left = left
    .replace(/\s*(?:\+|вкл\.?|с)\s*(?:веранд[ауыой]|террас[ауой])[^—]*/i, '')
    .trim();
  // 2) приводим x к × (опционально, для красоты)
  left = left.replace(/x/g, '×');
  return city ? `${left} — ${city}` : left;
}

/* ===================== КОНТАКТЫ / НАСТРОЙКИ [EDIT_ME] ===================== */
const COMPANY_NAME = 'Конструктивные решения';
const MAIN_PHONE = '+7 (495) 132-38-30';
const MAIN_PHONE_LINK = 'tel:+74951323830';
const WHATSAPP_LINK = 'https://wa.me/79939575790';
const CITY_COVERAGE = 'Москва и область + 250 км от МКАД';

/* ===================== UI CONSTANTS ===================== */
const BTN_WA =
  'inline-flex items-center justify-center rounded-xl bg-emerald-500 text-white font-semibold hover:bg-emerald-400';

/* ===================== ПРАЙСЫ ДЛЯ КАЛЬКУЛЯТОРА [EDIT_ME] =====================
— это примеры для визуализации; подставь свои.
— финальная сумма не показывается клиенту (гейтим).
*/
const PRICE = {
  houses: {
    base: {
      '6x4': 520000,
      '6x6': 690000,
      '6x8': 890000,
      '9x8': 1390000,
    },
    insulation: { 100: 0, 150: 60000, 200: 120000 }, // утепление
    facade: { imit: 0, blockhaus: 50000 }, // отделка
    roof: { proflist: 0, metal: 40000 }, // кровля
    terrace: { none: 0, small: 45000, big: 90000 },
    windowsPVC: 16000, // за шт.
    deliveryPerKm: 0, // доставка индивидуально рассчитывается
    foundation: { blocks: 0, screws_light: 120000, screws_heavy: 180000 },
    assembly: { standard: 0, winter: 45000 },
  },
  cabins: {
    base: { '6x3': 189000, '6x3_pro': 229000 },
    insulation: { 50: 0, 100: 30000 },
    windowsPVC: 12000,
    deliveryPerKm: 0, // доставка индивидуально рассчитывается
    foundation: { blocks: 0, screws_light: 80000 },
  },
  sheds: {
    base: { '2x2': 59000, '3x2': 72000 },
    windowsPVC: 8000,
    deliveryPerKm: 0, // доставка индивидуально рассчитывается
    foundation: { blocks: 0 },
  },
};

/* ===================== УТИЛИТЫ ===================== */

// === [A] МОДЕЛИ: что можно выбирать ===
function getAllowedModelsByType(type) {
  const src =
    type === 'houses'
      ? PRICE.houses.base
      : type === 'cabins'
        ? PRICE.cabins.base
        : PRICE.sheds.base;
  return Object.keys(src || {});
}
function coerceModel(type, model) {
  const allowed = getAllowedModelsByType(type);
  return allowed.includes(model) ? model : allowed[0] || model;
}
function formatModelLabel(type, m) {
  const nice = m.replace('x', '×');
  if (type === 'houses') return `Дом ${nice}`;
  if (type === 'cabins')
    return m === '6x3_pro' ? 'Бытовка 6×3 (усиленная)' : `Бытовка ${nice}`;
  return `Хозблок ${nice}`;
}
function modelArea(m) {
  const [w, l] = (m || '').split('x').map(Number);
  return Number.isFinite(w) && Number.isFinite(l) ? w * l : null;
}
// Понятные подписи для КП
const LABELS = {
  facade: { imit: 'Имитация бруса', blockhaus: 'Блок-хаус' },
  roof: { proflist: 'Профлист', metal: 'Металлочерепица' },
  foundation: {
    blocks: 'Блоки 40×20×20',
    screws_light: 'Сваи (стандарт)',
    screws_heavy: 'Сваи (усиленные)',
  },
  assembly: { standard: 'Обычная', winter: 'Зимняя' },
  terrace: {
    none: 'Без террасы',
    small: 'Терраса (малая)',
    big: 'Терраса (большая)',
  },
};

const PURPOSE_LABELS = {
  summer: 'Летний дачный домик',
  pmzh: 'ПМЖ / зимнее проживание',
  guest: 'Гостевой дом',
  rent: 'Аренда / кемпинг',
  worksite: 'Бытовка для рабочих',
  storage: 'Хозблок / склад',
  other: 'Другое',
};

function readCatalog() {
  const el = document.getElementById('CATALOG');
  try {
    return JSON.parse(el.textContent);
  } catch {
    return { categories: [] };
  }
}

function readUTM() {
  const sp = new URLSearchParams(location.search);
  const utm = {};
  [
    'utm_source',
    'utm_medium',
    'utm_campaign',
    'utm_content',
    'utm_term',
  ].forEach((k) => {
    if (sp.get(k)) utm[k] = sp.get(k);
  });
  utm.referrer = document.referrer || '';
  utm.landing = location.href;
  return utm;
}
const UTM = readUTM();

// ₽ формат
function formatRub(n) {
  if (!Number.isFinite(n)) return null;
  return new Intl.NumberFormat('ru-RU').format(n) + ' ₽';
}

function computeOldPrice(item) {
  const base = Number.isFinite(item.price_from_value)
    ? item.price_from_value
    : Number.isFinite(item.price_value)
      ? item.price_value
      : null;
  if (!base) return null;
  if (Number.isFinite(item.old_price_value)) return item.old_price_value;
  if (item.tags?.includes('sale10')) return Math.round(base * 1.1);
  return null;
}

// ALT для карточек по правилу: Тип + N×M + «КР», Москва +250 км
function computeAltByItem(item) {
  const map = { houses: 'Домик', cabins: 'Бытовка', sheds: 'Хозблок' };
  const type = map[item._cat] || 'Модуль';
  const m = (item.title || '').match(/(\d+[×x]\d+)/i);
  const size = m ? m[1].replace('x', '×') : '';
  return size
    ? `${type} ${size} — «Конструктивные решения», Москва +250 км`
    : `${item.title} — «Конструктивные решения», Москва +250 км`;
}

function buildWA(text) {
  const extras = [];
  // Всегда добавляем пометку о том, что клиент пришел с сайта
  extras.push('🌐 С сайта');
  if (UTM.utm_source) extras.push(`Источник: ${UTM.utm_source}`);
  if (UTM.utm_campaign) extras.push(`Кампания: ${UTM.utm_campaign}`);
  const tail = extras.length ? `\n\n${extras.join(' • ')}` : '';
  return WHATSAPP_LINK + '?text=' + encodeURIComponent(text + tail);
}

function giftDeadlineLabel(days) {
  try {
    if (!Number.isFinite(days)) {
      const el = document.getElementById('SITE_CONFIG');
      if (el && el.textContent) {
        const cfg = JSON.parse(el.textContent);
        days = Number(cfg.giftDays);
      }
    }
  } catch (e) {}
  if (!Number.isFinite(days)) days = 2;
  const d = new Date();
  d.setDate(d.getDate() + days);
  return new Intl.DateTimeFormat('ru-RU', {
    day: 'numeric',
    month: 'long',
  }).format(d);
}

function buildWAGift() {
  return buildWA(
    `Здравствуйте! Хочу забрать акцию: сборка в подарок до ${giftDeadlineLabel()}.`
  );
}

// Удалена дублирующая функция - используем глобальную window.sendLeadToUIS

// ===================== UI BLOCKS =====================
const Badge = ({ children }) => (
  <span className="inline-flex items-center rounded-full border border-white/30 bg-white/10 px-3 py-1 text-xs font-medium text-white backdrop-blur">
    {children}
  </span>
);

const SectionTitle = ({ eyebrow, title, subtitle }) => (
  <div className="mx-auto max-w-4xl text-center">
    {eyebrow && (
      <div className="mb-2 md:mb-3 text-xs md:text-sm font-medium tracking-widest text-white/40 uppercase">
        {eyebrow}
      </div>
    )}
    <h2 className="text-3xl md:text-5xl font-semibold text-white leading-tight">
      {title}
    </h2>
    {subtitle && (
      <p className="mt-2 md:mt-3 text-white/70 text-base md:text-lg">
        {subtitle}
      </p>
    )}
  </div>
);

function useTypograf(rootSelector = '.typo') {
  React.useEffect(() => {
    const RX =
      /(^|[\s(«"„—–-])((?:[вксуоия]|и|а|но|да|же|ли|бы|по|из|не|за|на|от|до|для|под|над|при|без|об|обо|со))\s+/gi;
    const RX_UNITS = /(\d+)\s+(м²|м³|м|км|мм|см|₽|%|день|дня|дней)/gi;
    const RX_NO = /№\s+(\d+)/g;
    const SKIP = new Set([
      'SCRIPT',
      'STYLE',
      'TEXTAREA',
      'INPUT',
      'SELECT',
      'OPTION',
      'PRE',
      'CODE',
    ]);

    const fixNode = (node) => {
      if (node.nodeType === 3) {
        let s = node.nodeValue,
          orig = s;
        s = s.replace(RX, (_, p, w) => p + w + '\u00A0');
        s = s.replace(RX_UNITS, '$1\u00A0$2');
        s = s.replace(RX_NO, '№\u00A0$1');
        if (s !== orig) node.nodeValue = s;
      } else if (node.nodeType === 1 && !SKIP.has(node.tagName)) {
        node.childNodes.forEach(fixNode);
      }
    };

    const run = () => {
      document.querySelectorAll(rootSelector).forEach((el) => fixNode(el));
    };

    let idleId = null;
    const schedule = () => {
      if (idleId !== null) return;
      const cb = () => {
        idleId = null;
        run();
      };
      if ('requestIdleCallback' in window) {
        idleId = requestIdleCallback(cb, { timeout: 500 });
      } else {
        idleId = setTimeout(cb, 120);
      }
    };

    // первый прогон
    schedule();

    const target =
      document.querySelector(rootSelector) ||
      document.querySelector('#root') ||
      document.body;
    const mo = new MutationObserver(schedule);
    mo.observe(target, { childList: true, subtree: true });

    return () => {
      mo.disconnect();
      if (idleId) {
        window.cancelIdleCallback?.(idleId);
        clearTimeout?.(idleId);
      }
    };
  }, [rootSelector]);
}

const Hero = () => {
  return (
    <section className="hero section" data-hero="main">
      <div className="hero__bg" aria-hidden="true"></div>
      <div className="container hero__inner">
        <div className="hero__left">
          <p className="hero__kicker">
            Готовый объект за 1&nbsp;день • Москва +250&nbsp;км • Без предоплаты
          </p>
          <h1 className="hero__title">
            Деревянные домики, бытовки
            <br />и хозблоки <span className="hero__accent">под ключ</span>
          </h1>
          <p className="hero__sub">Домики • бытовки • хозблоки</p>
          <p className="hero__lead">
            Оплата после монтажа. Фиксированная смета и честная комплектация.
            Нестандартные проекты — строим всё из дерева.
          </p>
          <div className="hero__cta">
            <a
              href="#quiz"
              onClick={(e) => {
                e.preventDefault();
                // ТОЛЬКО квиз, никакого WhatsApp
                if (window.openQuiz && typeof window.openQuiz === 'function') {
                  window.openQuiz();
                } else {
                  console.warn('Квиз недоступен');
                }
              }}
              className="hero__btn hero__btn--prime"
              data-ev="cta_quiz"
            >
              Рассчитать стоимость
            </a>
            <a href={MAIN_PHONE_LINK} className="hero__btn hero__btn--call">
              Позвонить
            </a>
          </div>
          <div className="hero__gift xl:hidden">
            <a
              href="#calc"
              className="inline-flex items-center rounded-full px-3 py-2 text-[13px] bg-white/10 ring-1 ring-white/15 text-white/90 hover:bg-white/15"
            >
              <span className="text-lg leading-none">🎁</span>
              <span className="ml-1">
                Сборка в подарок до&nbsp;
                <span className="js-gift-deadline" data-days="2">
                  —
                </span>
              </span>
            </a>
          </div>
          <ul className="hero__trust">
            <li>✅ Оплата после монтажа</li>
            <li>🛠️ Сборка за 1 день</li>
            <li>🛡️ Гарантия 2&nbsp;года</li>
          </ul>
        </div>
      </div>
    </section>
  );
};

/* ==== ProductCard ==== */
const ProductCard = ({ item }) => {
  const handleCalcFromCard = (e) => {
    e.preventDefault();
    const t = item._cat; // 'houses' | 'cabins' | 'sheds'
    const m = (item.title || '')
      .replace('×', 'x')
      .match(/(\d+(?:\.\d+)?)x(\d+(?:\.\d+)?)/i);
    const modelStr = m ? `${m[1]}x${m[2]}` : '';
    window.dispatchEvent(
      new CustomEvent('calc:prefill', {
        detail: { type: t, model: modelStr, fromCard: item.id },
      })
    );
  };

  const oldP = computeOldPrice(item);
  const hasOld = Number.isFinite(oldP);
  const p =
    Number.isFinite(item.price_value) && item.price_value > 0
      ? item.price_value
      : null;
  const pFrom = Number.isFinite(item.price_from_value)
    ? item.price_from_value
    : null;

  return (
    <div className="group rounded-2xl border border-white/10 bg-white/5 overflow-hidden hover:border-white/20 hover:shadow-[0_8px_40px_rgba(0,0,0,.35)] transition transform hover:-translate-y-0.5 flex flex-col h-full">
      <div className="relative aspect-[16/10] bg-neutral-900 rounded-xl overflow-hidden">
        <Img
          src={item.image}
          alt={computeAltByItem(item)}
          className="block h-full w-full object-cover object-center"
          style={item.focus ? { objectPosition: item.focus } : undefined}
        />
        {item.tags?.includes('sale10') && (
          <div className="absolute right-2 top-2 sm:right-3 sm:top-3 rounded-xl bg-rose-500/95 px-3 py-1 text-xs font-bold text-white shadow-[0_2px_12px_rgba(0,0,0,.25)]">
            −10%
          </div>
        )}
        <div className="absolute left-2 top-2 sm:left-3 sm:top-3 rounded-xl bg-white/90 px-3 py-1 text-xs font-medium text-neutral-900 shadow-[0_2px_12px_rgba(0,0,0,.25)]">
          Сборка за 1 день
        </div>
        {(item.tags?.includes('hit') || item.tags?.includes('popular')) && (
          <div className="absolute right-2 bottom-2 sm:right-3 sm:bottom-3 rounded-xl bg-emerald-400/95 px-3 py-1 text-xs font-bold text-neutral-900 shadow-[0_2px_12px_rgba(0,0,0,.25)]">
            Выбор покупателей
          </div>
        )}
        {item.tags?.includes('top') && (
          <div className="absolute left-2 bottom-2 sm:left-3 sm:bottom-3 rounded-xl bg-amber-400/95 px-3 py-1 text-xs font-bold text-neutral-900 shadow-[0_2px_12px_rgba(0,0,0,.25)]">
            Хит продаж
          </div>
        )}
      </div>

      <div className="p-5 flex-1 flex flex-col">
        <div>
          <h3 className="text-white text-lg font-semibold clamp-2">
            {item.title}
          </h3>
          <p className="text-white/70 text-sm mt-1 clamp-2">{item.lead}</p>
        </div>

        {item.specs?.length > 0 && (
          <ul className="mt-2 text-white/70 text-sm space-y-1 list-disc list-inside">
            {item.specs.map((s, i) => (
              <li key={item.id + '-spec-' + i}>{s}</li>
            ))}
          </ul>
        )}

        <div className="mt-auto pt-3">
          <div className="text-white text-right whitespace-nowrap tabular-nums leading-tight">
            {pFrom || p ? (
              <div className="flex items-baseline gap-2 justify-end">
                {hasOld && (
                  <span className="line-through text-white/50 text-[13px] md:text-[14px]">
                    {formatRub(oldP)}
                  </span>
                )}
                <span className="text-xl md:text-2xl font-semibold">
                  <span className="nobr">
                    {pFrom ? `от ${formatRub(pFrom)}` : `от ${formatRub(p)}`}
                  </span>
                </span>
              </div>
            ) : (
              <div className="text-lg md:text-xl font-semibold">по запросу</div>
            )}
          </div>

          <div className="mt-2 grid grid-cols-2 gap-2">
            <a
              href="#calc"
              onClick={(e) => {
                e.preventDefault();
                // Ждем загрузки квиза (максимум 2 секунды)
                const tryOpenQuiz = (attempts = 0) => {
                  if (window.openQuiz) {
                    // Определяем тип продукта по заголовку
                    let productType = 'dom';
                    if(item.title.toLowerCase().includes('бытовка') || item.title.toLowerCase().includes('быт')) {
                      productType = 'byt';
                    } else if(item.title.toLowerCase().includes('хозблок') || item.title.toLowerCase().includes('хоз')) {
                      productType = 'hoz';
                    }
                    window.openQuiz({ 
                      type: productType, 
                      id: item.id, 
                      title: item.title 
                    });
                  } else if (attempts < 20) {
                    setTimeout(() => tryOpenQuiz(attempts + 1), 100);
                  } else {
                    // Fallback на калькулятор
                    handleCalcFromCard(e);
                  }
                };
                tryOpenQuiz();
              }}
              className="inline-flex items-center justify-center rounded-xl bg-amber-400 h-11 px-5 text-neutral-900 text-sm font-semibold shadow-[0_6px_18px_rgba(251,191,36,.35)] hover:bg-amber-300 whitespace-nowrap"
            >
              Рассчитать
            </a>
            <a
              href="#"
              onClick={(e) => {
                e.preventDefault();
                window.openWhatsAppTracked(
                  buildWA(`Хочу расчёт: ${item.title} (id ${item.id})`)
                );
              }}
              rel="noopener"
              className="inline-flex items-center justify-center rounded-xl bg-emerald-500 h-11 px-5 text-white text-sm font-semibold hover:bg-emerald-400 whitespace-nowrap"
            >
              WhatsApp
            </a>
          </div>
        </div>
      </div>
    </div>
  );
};

const Catalog = () => {
  const data = React.useMemo(readCatalog, []);
  const categories = data.categories || [];
  const defaultCat = categories.find((c) => c.default) || categories[0] || null;

  const [activeKey, setActiveKey] = React.useState(
    defaultCat ? defaultCat.key : null
  );
  const [query, setQuery] = React.useState('');
  const [sort, setSort] = React.useState('popular');
  const [sizeFilter, setSizeFilter] = React.useState('');

  // Обработка якорных ссылок
  React.useEffect(() => {
    const handleAnchorChange = (event) => {
      const anchor = event.detail.anchor;
      const category = categories.find(c => c.anchor === anchor);
      if (category) {
        setActiveKey(category.key);
        setSizeFilter('');
        // Прокручиваем к якорю
        setTimeout(() => {
          const element = document.getElementById(anchor);
          if (element) {
            element.scrollIntoView({ behavior: 'smooth', block: 'start' });
          }
        }, 100);
      }
    };

    // Слушаем события изменения якорей
    window.addEventListener('anchorChange', handleAnchorChange);
    return () => window.removeEventListener('anchorChange', handleAnchorChange);
  }, [categories]);

  const SIZE_CHIPS = React.useMemo(
    () => ({
      houses: ['6×8', '6×6', '7×6', '6×4', '9×6', '8×9'],
      cabins: ['6×3', '6×2', '7×2', '4×3', '3×2', '4×2'],
      sheds: ['6×3', '6×2', '4×3', '3×2', '2×2'],
    }),
    []
  );

  const normalizeItem = (item) => {
    const swapPairs = (s) =>
      String(s).replace(/(\d+)\s*[×x]\s*(\d+)/g, (_, a, b) => {
        const A = parseInt(a, 10),
          B = parseInt(b, 10);
        return A >= B ? `${A}×${B}` : `${B}×${A}`;
      });
    const fixed = { ...item };
    if (fixed.title) fixed.title = swapPairs(fixed.title);
    if (fixed.lead) fixed.lead = swapPairs(fixed.lead);
    fixed.tags = (fixed.tags || []).map((t) => swapPairs(String(t)));
    return fixed;
  };

  const allItems = React.useMemo(
    () =>
      categories.flatMap((c) =>
        (c.items || []).map((i) => normalizeItem({ ...i, _cat: c.key }))
      ),
    [categories]
  );

  const rankByPopularity = (item) => {
    const tags = (item.tags || []).map((t) => (t || '').toLowerCase());
    if (tags.includes('top') || tags.includes('hit') || tags.includes('хит'))
      return 0;
    if (
      tags.includes('sale10') ||
      tags.includes('-10%') ||
      tags.includes('скидка10')
    )
      return 1;
    return 2;
  };

  const shown = React.useMemo(() => {
    let items = allItems;
    if (activeKey) items = items.filter((i) => i._cat === activeKey);

    if (sizeFilter) {
      const raw = sizeFilter.replace(/×/g, 'x').toLowerCase().trim();
      const m = raw.match(/(\d+)\s*x\s*(\d+)/);
      if (m) {
        const a = parseInt(m[1], 10),
          b = parseInt(m[2], 10);
        const v1 = `${Math.max(a, b)}x${Math.min(a, b)}`;
        const v2 = `${Math.min(a, b)}x${Math.max(a, b)}`;
        items = items.filter((i) => {
          const title = String(i.title || '')
            .replace(/×/g, 'x')
            .toLowerCase();
          const tags = (i.tags || []).map((t) =>
            String(t).replace(/×/g, 'x').toLowerCase()
          );
          const hay = [title, ...tags];
          return hay.some((txt) => txt.includes(v1) || txt.includes(v2));
        });
      } else {
        const s = raw;
        items = items.filter((i) => {
          const title = String(i.title || '')
            .replace(/×/g, 'x')
            .toLowerCase();
          const tags = (i.tags || []).map((t) =>
            String(t).replace(/×/g, 'x').toLowerCase()
          );
          return title.includes(s) || tags.some((t) => t.includes(s));
        });
      }
    }

    if (query.trim()) {
      const q = query.trim().toLowerCase();
      items = items.filter(
        (i) =>
          (i.title || '').toLowerCase().includes(q) ||
          (i.lead || '').toLowerCase().includes(q) ||
          (i.tags || []).some((t) => String(t).toLowerCase().includes(q))
      );
    }

    if (sort === 'popular') {
      items = items.slice().sort((a, b) => {
        const r = rankByPopularity(a) - rankByPopularity(b);
        if (r !== 0) return r;
        const pa = a.price_from_value ?? a.price_value ?? a.price ?? 0;
        const pb = b.price_from_value ?? b.price_value ?? b.price ?? 0;
        return pb - pa;
      });
    }

    if (sort === 'price_asc')
      items = items
        .slice()
        .sort(
          (a, b) =>
            (a.price_from_value || a.price_value || 0) -
            (b.price_from_value || b.price_value || 0)
        );
    if (sort === 'price_desc')
      items = items
        .slice()
        .sort(
          (a, b) =>
            (b.price_from_value || b.price_value || 0) -
            (a.price_from_value || a.price_value || 0)
        );

    return items;
  }, [allItems, activeKey, query, sort, sizeFilter]);

  return (
    <section
      id="catalog"
      className="bg-neutral-950 pt-10 md:pt-12 pb-24 md:pb-24 border-t border-white/10"
    >
      <div className="mx-auto max-w-7xl px-4">
        <SectionTitle
          eyebrow="Каталог"
          title="Готовые модели и размеры • Москва и область +250 км"
        />
        <div className="mt-8 md:mt-10 flex flex-col gap-3">
          <div className="flex flex-nowrap gap-2 overflow-x-auto -mx-4 px-4 snap-x">
            {categories.map((c) => (
              <button
                key={c.key}
                onClick={() => {
                  setActiveKey(c.key);
                  setSizeFilter('');
                }}
                className={
                  'shrink-0 snap-start px-3 py-2 rounded-xl border ' +
                  (activeKey === c.key
                    ? 'bg-white text-neutral-900 border-white'
                    : 'border-white/20 text-white/80 hover:bg-white/10')
                }
              >
                {c.title}
              </button>
            ))}
            <button
              onClick={() => {
                setActiveKey(null);
                setSizeFilter('');
              }}
              className={
                'shrink-0 snap-start px-3 py-2 rounded-xl border ' +
                (activeKey === null
                  ? 'bg-white text-neutral-900 border-white'
                  : 'border-white/20 text-white/80 hover:bg-white/10')
              }
            >
              Все
            </button>
          </div>

          {activeKey && SIZE_CHIPS[activeKey]?.length > 0 && (
            <div className="flex flex-wrap gap-2 -mx-4 px-4 mt-1">
              {SIZE_CHIPS[activeKey].map((s) => {
                const normalizeSize = (str) =>
                  String(str).replace(/(\d+)\s*[×x]\s*(\d+)/gi, (_, a, b) => {
                    const A = parseInt(a, 10),
                      B = parseInt(b, 10);
                    return A >= B ? `${A}×${B}` : `${B}×${A}`;
                  });
                const active =
                  normalizeSize(sizeFilter || '') === normalizeSize(s);
                return (
                  <button
                    key={s}
                    onClick={() =>
                      setSizeFilter((prev) =>
                        normalizeSize(prev || '') === normalizeSize(s)
                          ? ''
                          : normalizeSize(s)
                      )
                    }
                    className={
                      'px-3 py-1.5 rounded-xl text-sm border ' +
                      (active
                        ? 'bg-emerald-400 text-neutral-900 border-emerald-400'
                        : 'border-white/20 text-white/80 hover:bg-white/10')
                    }
                  >
                    {s}
                  </button>
                );
              })}
              {sizeFilter && (
                <button
                  onClick={() => setSizeFilter('')}
                  className="px-3 py-1.5 rounded-xl text-sm border border-white/20 text-white/80 hover:bg-white/10"
                >
                  Сбросить размер
                </button>
              )}
            </div>
          )}

          <div className="mt-2 flex flex-col sm:flex-row sm:items-center gap-2">
            <div className="flex w-full sm:w-auto gap-2 sm:ml-auto">
              <input
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                placeholder="Поиск: 6×8, веранда…"
                className="w-full sm:w-[320px] md:w-[380px] rounded-xl border border-white/10 bg-neutral-900/60 px-3 py-2 text-white outline-none focus:ring-2 focus:ring-emerald-400"
              />
              <select
                value={sort}
                onChange={(e) => setSort(e.target.value)}
                className="w-full sm:w-auto rounded-xl border border-white/10 bg-neutral-900/60 px-3 py-2 text-white outline-none focus:ring-2 focus:ring-emerald-400"
              >
                <option value="popular">Сначала популярные</option>
                <option value="price_asc">Сначала дешевле</option>
                <option value="price_desc">Сначала дороже</option>
              </select>
            </div>
          </div>
        </div>

        <div className="mt-8 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5 product-grid">
          {shown.map((p, index) => {
            // Добавляем якорь для первого товара в каждой категории
            const category = categories.find(c => c.key === p._cat);
            const isFirstInCategory = index === 0 || shown[index - 1]._cat !== p._cat;
            
            return (
              <div key={p.id}>
                {isFirstInCategory && category?.anchor && (
                  <div id={category.anchor} className="scroll-mt-20"></div>
                )}
                <ProductCard item={p} />
              </div>
            );
          })}
        </div>
      </div>
    </section>
  );
};

// ===================== КОМПОНЕНТ ОТЗЫВОВ =====================
const Stars = ({ n = 5 }) => (
  <div className="flex">
    {Array.from({ length: 5 }).map((_, i) => (
      <svg
        key={i}
        viewBox="0 0 24 24"
        className={'h-4 w-4 ' + (i < n ? ' fill-amber-400' : 'fill-white/20')}
      >
        <path d="M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" />
      </svg>
    ))}
  </div>
);

const Avatar = ({ name }) => (
  <div className="h-10 w-10 rounded-full bg-gradient-to-br from-emerald-400 to-cyan-400 grid place-items-center text-neutral-900 font-semibold">
    {name?.[0] || '•'}
  </div>
);

const REVIEWS = [
  {
    id: 'rv1',
    name: 'Марина Р.',
    city: 'Дмитров',
    model: 'Дом 6×4 + веранда',
    text: `Долго искала подрядчиков, многие привозят готовые строения и разгружают до борта машины… а нам нужна была сборка на участке. Плюс почва у нас глинистая с подземными водами — надо было ставить на винтовые сваи. В этой компании все наши пожелания учли. Приехала бригада из пяти человек, все рукастые! Свое дело знают. Со сваями было нелегко, еле пробурили, но всё поставили на совесть. Дальше мы уже сами будем делать электрику в нашем домике! В общем всё оперативно! Всегда были на связи (с моей тревожностью это важный пункт 😄). Успехов компании! Человечное отношение! Спасибо вам!`,
    rating: 5,
    date: 'июнь 2025',
  },
  {
    id: 'rv2',
    name: 'Роман М.',
    city: 'Подольск',
    model: 'Хозблок 6×2',
    text: `Хозблок отличный, материалы действительно хорошие, вагонка без дырок от сучков. Ребята приехали на газели, не побоялись грязной дороги, застряли, потеряли время, вытащили трактором, но всё равно успели собрать за день, при этом как только пришла дождевая…`,
    rating: 5,
    date: 'август 2025',
  },
  {
    id: 'rv3',
    name: 'Игорь П.',
    city: 'Пушкино',
    model: 'Дом 6×6',
    text: `Приехали утром — к вечеру стоял дом. Не могли найти дорогу и опоздали на 2 часа, но предупредили. Электрику не сделали. В целом доволен.`,
    rating: 4,
    date: 'июль 2025',
  },
  {
    id: 'rv4',
    name: 'Сергей К.',
    city: 'Наро-Фоминск',
    model: 'Бытовка 6×3',
    text: `Отличные ребята — быстро и слаженно сработали.`,
    rating: 5,
    date: 'май 2025',
  },
  {
    id: 'rv5',
    name: 'Дмитрий Л.',
    city: 'Снегири',
    model: 'Дом 6×8 с террасой',
    text: `На сваях поставили ровно. Террасу сделали шире, чем планировали — спасибо за совет монтажникам. Начался дождь — постройку накрыли плёнками, перенесли на следующий день, поэтому вышло 1.5 дня. Нас устроило.`,
    rating: 4,
    date: 'июль 2025',
  },
  {
    id: 'rv6',
    name: 'Ольга Н.',
    city: 'Вербилки',
    model: 'Дом 6×6 + веранда 6×1',
    text: `Сроки держат. Дети сразу оккупировали веранду. Менеджер был на связи, отвечал быстро. Оплата по факту — это плюс.`,
    rating: 5,
    date: 'июнь 2025',
  },
  {
    id: 'rv7',
    name: 'Роман Е.',
    city: 'Боголюбово',
    model: 'Бытовка 6×3, двускат',
    text: `Под мастерскую самое то. Свет подключал сам позже — ребята сразу предупреждали, что они коробку ставят без проводки. Хотелось бы чуть большей внимательности к деталям.`,
    rating: 4,
    date: 'май 2025',
  },
  {
    id: 'rv8',
    name: 'Виктория М.',
    city: 'Редкино',
    model: 'Дом 6×6 + веранда 2×3',
    text: `Планировка удобная, окна ПВХ качественные. Ребята вежливые, без предоплаты взяли — такое сейчас редко. Рекомендую.`,
    rating: 5,
    date: 'август 2025',
  },
  {
    id: 'rv9',
    name: 'Алексей Г.',
    city: 'Поляны',
    model: 'Хозкомплекс 6×3, 3-в-1',
    text: `Сделали душ, туалет и кладовку раздельно, по месту подогнали. На крыше профлист — не гремит. Лил дождь, из-за этого растянулось на 2 дня, но предупредили заранее.`,
    rating: 4,
    date: 'июль 2025',
  },
  {
    id: 'rv10',
    name: 'Елена Т.',
    city: 'Мытищи',
    model: 'Дом 9×6',
    text: `Большая веранда смотрится огонь. Менеджер всегда на связи, подсказывал по отделке. По деньгам в принципе как договаривались.`,
    rating: 5,
    date: 'июнь 2025',
  },
];

const Reviews = () => {
  const [i, setI] = React.useState(0);
  const timerRef = React.useRef(null);
  const start = () => {
    timerRef.current = setInterval(
      () => setI((v) => (v + 1) % REVIEWS.length),
      10000
    );
  };
  const stop = () => {
    if (timerRef.current) clearInterval(timerRef.current);
  };
  React.useEffect(() => {
    start();
    return stop;
  }, []);
  const prev = () => setI((v) => (v - 1 + REVIEWS.length) % REVIEWS.length);
  const next = () => setI((v) => (v + 1) % REVIEWS.length);
  const r = REVIEWS[i];
  return (
    <section
      id="reviews"
      className="bg-neutral-950 py-14 md:py-20 border-t border-white/10"
    >
      <div className="mx-auto max-w-7xl px-4">
        <SectionTitle eyebrow="Отзывы клиентов" title="Что говорят люди" />
        <div
          className="relative mx-auto mt-8 max-w-4xl"
          onMouseEnter={stop}
          onMouseLeave={start}
          aria-live="polite"
        >
          <article className="rounded-2xl border border-white/10 bg-white/5 p-5 md:p-6 shadow">
            <div className="flex items-start gap-3">
              <Avatar name={r.name} />
              <div className="flex-1 text-left">
                <div className="flex items-center justify-between">
                  <div className="text-white font-medium">
                    {r.name} · <span className="text-white/70">{r.city}</span>
                  </div>
                  <Stars n={r.rating} />
                </div>
                <div className="text-white/60 text-sm">
                  {r.model} · {r.date}
                </div>
                <p className="mt-3 text-white/80 text-base leading-relaxed whitespace-pre-wrap break-words">
                  {r.text}
                </p>
              </div>
            </div>
          </article>
          <div className="mt-4 flex items-center justify-between">
            <div className="flex gap-2">
              <button
                onClick={prev}
                className="rounded-xl border border-white/20 px-3 py-2 text-white/80 hover:bg-white/10"
              >
                ←
              </button>
              <button
                onClick={next}
                className="rounded-xl border border-white/20 px-3 py-2 text-white/80 hover:bg-white/10"
              >
                →
              </button>
            </div>
            <div className="flex gap-1">
              {REVIEWS.map((_, idx) => (
                <button
                  key={idx}
                  onClick={() => setI(idx)}
                  aria-label={`Показать отзыв ${idx + 1}`}
                  className={
                    'h-2.5 w-2.5 rounded-full ' +
                    (idx === i ? 'bg-white' : 'bg-white/30 hover:bg-white/60')
                  }
                />
              ))}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
};

const MobileCTA = () => {
  const [visible, setVisible] = React.useState(false);
  React.useEffect(() => {
    const onScroll = () => setVisible(window.scrollY > 200);
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  if (!visible) return null;
  return (
    <div className="fixed bottom-0 inset-x-0 z-50 md:hidden bg-neutral-900/95 backdrop-blur border-t border-white/10 p-2 mobile-cta">
      <div className="max-w-7xl mx-auto flex gap-2">
        <a
          href={MAIN_PHONE_LINK}
          className="inline-flex items-center justify-center rounded-xl bg-amber-400 px-5 py-3 text-neutral-900 font-semibold hover:bg-amber-300 shadow-[0_6px_18px_rgba(251,191,36,.35)]"
        >
          Связаться с нами
        </a>
        <a
          href="#"
          onClick={(e) => {
            e.preventDefault();
            if (window.openQuiz) {
              window.openQuiz();
            } else {
              window.openWhatsAppTracked(
                buildWA('Здравствуйте! Хочу расчёт по домику.')
              );
            }
          }}
          className={`${BTN_WA} flex-1 px-4 py-3`}
        >
          Рассчитать стоимость
        </a>
      </div>
    </div>
  );
};

const CASES = [
  {
    id: 'case-6x8-troitsk',
    title: 'Дом 6×8 — Троицк',
    model: '6x8',
    image: './images/real1.jpeg',
    facts: ['Сборка 1 день', 'Фундамент: блоки', 'Без предоплаты'],
  },
  {
    id: 'case-6x4-veranda-aprelevka',
    title: 'Дом 6×4 + веранда — Апрелевка',
    model: '6x4',
    image: './images/real2.jpeg',
    facts: ['Веранда 6×1', 'Цветной профлист', 'Окна ПВХ'],
  },
  {
    id: 'case-2x7-nf',
    title: 'Бытовка 2×7 — Наро-Фоминск',
    model: '2x7',
    image: './images/real3.jpeg',
    facts: ['План 14 м²', 'Металлическая дверь', 'Сборка 1 день'],
  },
  {
    id: 'case-8x6-istra',
    title: 'Дом 8×6 — Истра',
    model: '8x6',
    image: './images/real4.jpeg',
    facts: ['Крыльцо', 'Окна ПВХ', 'Крыша металлочерепица'],
  },
  {
    id: 'case-6x8-snegiri',
    title: 'Дом 6×8 вкл. веранду 3×2 — Снегири',
    model: '6x8',
    image: './images/real5.jpeg',
    facts: ['Свайный фундамент', 'Веранда ~6 м²', 'Опорные стойки по фасаду'],
  },
  {
    id: 'case-6x6-verbilki',
    title: 'Дом 6×6 + веранда 6×1 — Вербилки',
    model: '6x6',
    image: './images/real6.jpeg',
    facts: ['Веранда вдоль фасада', 'Металлочерепица', 'Без предоплаты'],
  },
  {
    id: 'case-6x3-bogolyubovo',
    title: 'Бытовка 6×3 двускатная крыша — Боголюбово',
    model: '6x3',
    image: './images/real7.jpeg',
    facts: ['~18 м²', 'Кровля профлист', 'Окна ПВХ 2 камеры'],
  },
  {
    id: 'case-6x6-redkino',
    title: 'Дом 6×6 + веранда 2×3 — Редкино',
    model: '6x6',
    image: './images/real8.jpeg',
    facts: ['~36 м² + веранда ~6 м²', 'Двускатная крыша', 'Свайный фундамент'],
  },
  {
    id: 'case-6x3-polyany',
    title: 'Хозкомплекс 6×3 — 3-в-1 (душ/туалет/кладовая) — Поляны',
    model: '6x3',
    image: './images/real9.jpeg',
    facts: [
      'Двускатная крыша, профлист',
      'Отдельные помещения',
      'Сборка 1 день',
    ],
  },
];

const Cases = () => {
  const list = CASES;
  const openLead = (c) => {
    window.dispatchEvent(
      new CustomEvent('lead:open', {
        detail: { title: c.title, model: c.model, id: c.id },
      })
    );
  };
  return (
    <section
      id="cases"
      className="bg-neutral-950 py-14 md:py-20 border-t border-white/10"
    >
      <div className="mx-auto max-w-7xl px-4">
        <div className="mx-auto max-w-4xl text-center">
          <div className="mb-3 text-sm font-medium tracking-widest text-white/70 uppercase">
            Реальные объекты
          </div>
          <h2 className="text-3xl md:text-4xl font-semibold text-white leading-tight">
            Недавние работы
          </h2>
        </div>
        <div className="mt-8 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5">
          {list.map((c) => (
            <figure
              key={c.id}
              className="group rounded-2xl border border-white/10 bg-white/5 overflow-hidden hover:border-white/20 hover:shadow-[0_8px_40px_rgba(0,0,0,.35)] transition flex flex-col h-full"
            >
              <div className="relative w-full aspect-[16/10] bg-neutral-900">
                <Img
                  src={c.image}
                  alt={c.title}
                  className="absolute inset-0 w-full h-full object-cover object-center"
                />
              </div>
              <figcaption className="p-3 text-white/80 flex flex-col flex-1">
                <div
                  className="text-base md:text-[17px] font-semibold text-white leading-snug whitespace-normal break-words"
                  style={{ hyphens: 'auto' }}
                  title={c.title}
                >
                  {c.title}
                </div>
                {Array.isArray(c.facts) && c.facts.length > 0 && (
                  <ul className="mt-3 text-[12px] md:text-sm text-white/70 leading-relaxed list-disc list-inside space-y-1 marker:text-white/40">
                    {c.facts.map((f, idx) => (
                      <li
                        key={c.id + '-fact-' + idx}
                        className="whitespace-normal"
                      >
                        {f}
                      </li>
                    ))}
                  </ul>
                )}
                <div className="mt-auto pt-3 grid grid-cols-2 gap-2 items-end">
                  <button
                    onClick={() => openLead(c)}
                    className="inline-flex h-10 items-center justify-center rounded-xl bg-amber-400 px-4 text-neutral-900 text-sm font-semibold hover:bg-amber-300 shadow-[0_6px_18px_rgba(251,191,36,.25)] whitespace-nowrap"
                  >
                    Хочу такой
                  </button>
                  <button
                    onClick={(e) => {
                      e.preventDefault();
                      // Ждем загрузки квиза (максимум 2 секунды)
                      const tryOpenQuiz = (attempts = 0) => {
                        if (window.openQuiz) {
                          // Определяем тип продукта по заголовку
                          let productType = 'dom';
                          if(c.title.toLowerCase().includes('бытовка') || c.title.toLowerCase().includes('быт')) {
                            productType = 'byt';
                          } else if(c.title.toLowerCase().includes('хозблок') || c.title.toLowerCase().includes('хоз')) {
                            productType = 'hoz';
                          }
                          window.openQuiz({ 
                            type: productType, 
                            id: c.id, 
                            title: c.title 
                          });
                        } else if (attempts < 20) {
                          setTimeout(() => tryOpenQuiz(attempts + 1), 100);
                        } else {
                          // Fallback на WhatsApp
                          window.openWhatsAppTracked(
                            buildWA(`Здравствуйте! Хочу такой объект: ${c.title}.`)
                          );
                        }
                      };
                      tryOpenQuiz();
                    }}
                    className="inline-flex h-10 items-center justify-center rounded-xl bg-emerald-500 px-4 text-white text-sm font-semibold hover:bg-emerald-400 whitespace-nowrap"
                  >
                    Рассчитать
                  </button>
                </div>
              </figcaption>
            </figure>
          ))}
        </div>
      </div>
    </section>
  );
};

const About = () => (
  <section
    id="about"
    className="bg-neutral-950 pt-10 md:pt-14 pb-14 md:pb-20 border-t border-white/10"
  >
    <div className="mx-auto max-w-7xl px-4">
      <SectionTitle
        eyebrow="О нас"
        title="Строим из дерева с 1999 года"
        subtitle="Оплата после монтажа, гарантия 2 года. Работаем по Москве и области +250 км."
      />
      <div className="mt-8 grid grid-cols-2 md:grid-cols-4 gap-3 md:gap-4 lg:gap-5 items-stretch">
        {[
          { h: '20 000+ объектов', s: 'Покажем адреса и фото' },
          { h: '0 ₽ предоплата', s: 'Оплата после монтажа' },
          { h: 'Сборка за 1 день', s: 'Типовой объект' },
          { h: '20+ бригад', s: 'Собственные бригады' },
          { h: 'Гарантия 2 года', s: 'Поддержка 7 дней в неделю' },
          { h: 'Открытая смета', s: 'Фиксируем до монтажа' },
          { h: 'Фото/видео отчёты', s: 'Каждый этап' },
          { h: 'С 1999 года', s: 'Собственное производство' },
        ].map((item, i) => (
          <div
            key={i}
            className="rounded-2xl ring-1 ring-white/10 bg-white/5 p-4 md:p-5 h-full min-h-[110px] md:min-h-[120px] flex flex-col items-center justify-center text-center gap-1.5 shadow-[inset_0_1px_0_rgba(255,255,255,.05),0_10px_24px_rgba(0,0,0,.25)] hover:bg-white/10 transition"
          >
            <div className="text-white font-semibold">{item.h}</div>
            <div className="text-white/70 text-sm">{item.s}</div>
          </div>
        ))}
      </div>
    </div>
  </section>
);

const FAQ = () => (
  <section
    id="faq"
    className="bg-neutral-950 py-14 md:py-20 border-t border-white/10"
  >
    <div className="mx-auto max-w-7xl px-4">
      <SectionTitle
        eyebrow="FAQ"
        title="Частые вопросы о домиках, бытовках и хозблоках"
      />
      <div className="mt-6 space-y-3">
        {[
          [
            'Нужна ли предоплата?',
            'Нет. Работаем без предоплаты. Оплата по факту сборки. Сначала вы видите готовый объект, затем оплачиваете.',
          ],
          [
            'Сколько длится сборка и что нужно от меня?',
            'Типовой объект — 1 день. Крупные домики — до 2–3 дней. Нужен подъезд, ровная площадка, желательно электричество.',
          ],
          [
            'Какой фундамент выбрать?',
            'В 80% случаев достаточно блоков 20×20×40 — быстро и недорого. На слабых грунтах/уклоне — винтовые сваи. Мы подскажем по фото участка.',
          ],
          [
            'Как считаете доставку?',
            'Доставка индивидуально рассчитывается и зависит от типа и размеров строений - 250 км от МКАД, расстояние дальше обсуждается индивидуально.',
          ],
          [
            'Можно зимнюю сборку?',
            'Да. Утепление 150–200 мм, сухая доска, узлы с плёнками. Зимний монтаж — штатно.',
          ],
          [
            'Какие материалы и утепление?',
            'Каркас — сосна 1 сорт, стойка 45×95/145, шаг 600. Утепление 100–200 мм. Отделка: внутри OSB-3/вагонка, снаружи имитация бруса/OSB-3. Кровля — профлист, ондулин или металлочерепица.',
          ],
          [
            'Можно поменять планировку?',
            'Да. Перегородки, тамбур, окна/двери, веранда — настраиваем под вашу задачу.',
          ],
          [
            'Какие гарантии и документы?',
            'Гарантия 2 года. В смете фиксируем комплектацию и сроки.',
          ],
          ['Как происходит оплата?', 'Наличными, без предоплаты.'],
          [
            'Нужны ли разрешения?',
            'На бытовки/хозблоки обычно не требуется. Домики до ~50–70 м² часто ставят как временные — подскажем порядок при необходимости.',
          ],
        ].map(([q, a], i) => (
          <details
            key={i}
            className="rounded-2xl border border-white/10 bg-white/5 p-4"
          >
            <summary className="cursor-pointer font-medium text-white">
              {q}
            </summary>
            <div className="mt-2 text-white/70 text-sm leading-relaxed">
              {a}
            </div>
          </details>
        ))}
      </div>
    </div>
  </section>
);

const Steps = () => (
  <section
    id="steps"
    className="bg-neutral-950 py-14 md:py-20 border-t border-white/10"
  >
    <div className="mx-auto max-w-7xl px-4">
      <SectionTitle
        eyebrow="Как работаем"
        title="От звонка до ключей — 6 шагов"
      />
      <div className="mt-8 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-6 gap-4">
        {[
          { t: 'Заявка', d: 'Звонок или WhatsApp — 5 минут.' },
          { t: 'Подбор', d: 'Модель/план под задачи.' },
          { t: 'Смета', d: 'Фиксируем смету.' },
          { t: 'Доставка', d: 'Привозим в выбранный день.' },
          { t: 'Сборка', d: '1 день на площадке.' },
          { t: 'Сдача', d: 'Оплата по факту. Гарантия 2 года.' },
        ].map((s, i) => (
          <div
            key={i}
            className="rounded-2xl border border-white/10 bg-white/5 p-4 text-center sm:text-left"
          >
            <div className="text-emerald-300 text-2xl font-bold">{i + 1}</div>
            <div className="mt-1 font-semibold">{s.t}</div>
            <div className="text-white/70 text-sm">{s.d}</div>
          </div>
        ))}
      </div>
    </div>
  </section>
);

/* ===================== КАЛЬКУЛЯТОР (цены скрываем) ===================== */
const Calculator = () => {
  const [type, setType] = React.useState('houses');
  const [width, setWidth] = React.useState(6);
  const [length, setLength] = React.useState(6);
  const [insul, setInsul] = React.useState('150');
  const [facade, setFacade] = React.useState('imit');
  const [roof, setRoof] = React.useState('proflist');
  const [terrace, setTerrace] = React.useState('none');
  const [address, setAddress] = React.useState('');
  const [purpose, setPurpose] = React.useState('');
  const [purposeOther, setPurposeOther] = React.useState('');
  const [foundation, setFoundation] = React.useState('blocks');
  const [assembly, setAssembly] = React.useState('standard');

  const SIZE = {
    houses: { widths: [6, 7, 8, 9, 10], lengths: [4, 5, 6, 7, 8, 9, 10] },
    cabins: { widths: [2, 2.5, 3, 4], lengths: [2, 2.5, 3, 4, 5, 6, 7, 8] },
    sheds: { widths: [2, 3, 4], lengths: [2, 3, 4, 5, 6] },
  };

  const [client, setClient] = React.useState({ name: '', phone: '', city: '' });
  const [status, setStatus] = React.useState(null);
  const [summary, setSummary] = React.useState('');
  const [isModalOpen, setIsModalOpen] = React.useState(false);
  React.useEffect(() => {
    document.body.classList.toggle('modal-open', isModalOpen);
    return () => document.body.classList.remove('modal-open');
  }, [isModalOpen]);

  React.useEffect(() => {
    const onPrefill = (e) => {
      const { type: t, model: m } = e.detail || {};
      if (t) setType(t);
      setTimeout(() => {
        const mm = (m || '').replace('×', 'x');
        const [w, l] = mm.split('x').map(Number);
        if (Number.isFinite(w)) setWidth(w);
        if (Number.isFinite(l)) setLength(l);
      }, 0);
      document
        .querySelector('#calc')
        ?.scrollIntoView({ behavior: 'smooth', block: 'start' });
    };
    window.addEventListener('calc:prefill', onPrefill);
    return () => window.removeEventListener('calc:prefill', onPrefill);
  }, []);

  const normalizePhone = (v) => {
    let digits = String(v || '').replace(/\D/g, '');
    if (digits.startsWith('8')) digits = '7' + digits.slice(1);
    if (!digits.startsWith('7')) digits = '7' + digits;
    return '+' + digits.slice(0, 11);
  };

  function calcTotal() {
    const modelKey = `${width}x${length}`;
    let total = 0;
    if (type === 'houses') {
      total += PRICE.houses.base[modelKey] || 0;
      total += PRICE.houses.insulation[insul] || 0;
      total += PRICE.houses.facade[facade] || 0;
      total += PRICE.houses.roof[roof] || 0;
      total += PRICE.houses.terrace[terrace] || 0;
      total += PRICE.houses.foundation[foundation] || 0;
      total += PRICE.houses.assembly[assembly] || 0;
    } else if (type === 'cabins') {
      total += PRICE.cabins.base[modelKey] || 0;
      if (insul === '100') total += PRICE.cabins.insulation['100'];
      total += PRICE.cabins.foundation[foundation] || 0;
    } else if (type === 'sheds') {
      total += PRICE.sheds.base[modelKey] || 0;
      total += PRICE.sheds.foundation[foundation] || 0;
    }
    return total;
  }

  const labelByBudget = (t) =>
    t < 400000
      ? 'Мини'
      : t < 900000
        ? 'Стандарт'
        : t < 1500000
          ? 'Расширенный'
          : 'Премиум';

  function buildSummary() {
    const total = calcTotal();
    const area = width * length;
    const cat =
      type === 'houses'
        ? 'Каркасный дом'
        : type === 'cabins'
          ? 'Бытовка'
          : 'Хозблок';
    const title = `${cat} ${width}×${length} — ~${area} м²`;
    const L = [];
    L.push(`🏠 ${title}`);
    if (address) L.push(`📍 Адрес/локация: ${address}`);
    if (purpose) {
      const label =
        purpose === 'other'
          ? purposeOther || 'Другое'
          : PURPOSE_LABELS[purpose] || purpose;
      L.push(`🎯 Назначение: ${label}`);
    }
    L.push('');
    L.push('🏗️ Комплектация:');
    if (type === 'houses') {
      L.push(`– Утепление: ${insul} мм`);
      L.push(`– Фасад: ${LABELS.facade[facade] || facade}`);
      L.push(`– Кровля: ${LABELS.roof[roof] || roof}`);
      if (terrace !== 'none')
        L.push(`– Терраса: ${LABELS.terrace[terrace] || terrace}`);
      L.push(`– Фундамент: ${LABELS.foundation[foundation] || foundation}`);
      L.push(`– Сборка: ${LABELS.assembly[assembly] || assembly}`);
    } else if (type === 'cabins') {
      L.push(`– Утепление: ${insul} мм`);
      L.push(`– Фундамент: ${LABELS.foundation[foundation] || foundation}`);
    } else if (type === 'sheds') {
      L.push(`– Фундамент: ${LABELS.foundation[foundation] || foundation}`);
    }
    L.push('');
    L.push(
      '🚚 Доставка: индивидуально рассчитывается и зависит от типа и размеров строений - 250 км от МКАД, расстояние дальше обсуждается индивидуально.'
    );
    L.push('');
    L.push(`📦 Комплект: ${labelByBudget(total)}`);
    L.push('Оставьте контакты — пришлём смету и сроки.');
    return L.join('\n');
  }

  function onCalculate(e) {
    e.preventDefault();
    setSummary(buildSummary()); // ← используем новый генератор текста
    setStatus(null);
    setIsModalOpen(true);
  }

  async function onSubmitLead(e) {
    e.preventDefault();

    const typeLabel =
      type === 'houses'
        ? 'Каркасный дом'
        : type === 'cabins'
          ? 'Бытовка'
          : 'Хозблок';
    const phoneDigits = (client.phone || '').replace(/\D+/g, '');
    if (phoneDigits.length < 10) {
      // Показываем ошибку валидации
      const errorMsg = document.createElement('div');
      errorMsg.textContent = 'Введите, пожалуйста, телефон полностью.';
      errorMsg.style.cssText = 'color: #e74c3c; margin-top: 10px; font-size: 14px;';
      
      const container = e.target.closest('.calc-form') || e.target.closest('.lead-modal');
      const existingError = container.querySelector('.calc-error');
      if (existingError) existingError.remove();
      errorMsg.className = 'calc-error';
      container.appendChild(errorMsg);
      
      setTimeout(() => {
        if (errorMsg.parentNode) errorMsg.remove();
      }, 3000);
      setStatus('err');
      return;
    }

    const message = [
      `Интерес: ${typeLabel}`,
      `Размер: ${width}×${length}`,
      type === 'houses' || type === 'cabins' ? `Утепление: ${insul} мм` : null,
      facade ? `Фасад: ${LABELS.facade?.[facade] || facade}` : null,
      roof ? `Крыша: ${LABELS.roof?.[roof] || roof}` : null,
      terrace && terrace !== 'none'
        ? `Терраса: ${LABELS.terrace?.[terrace] || terrace}`
        : null,
      foundation
        ? `Фундамент: ${LABELS.foundation?.[foundation] || foundation}`
        : null,
      assembly ? `Сборка: ${LABELS.assembly?.[assembly] || assembly}` : null,
      address ? `Адрес/локация: ${address}` : null,
      purpose
        ? `Цель: ${purpose === 'other' ? purposeOther || 'Другое' : PURPOSE_LABELS[purpose] || purpose}`
        : null,
      '',
      `Клиент: ${client.name || ''} +${phoneDigits} ${client.city || ''}`,
      '',
      `UTM: ${JSON.stringify(UTM)}`,
    ]
      .filter(Boolean)
      .join('\n');

    // Заголовок для имени контакта в amo: "Иван Каркасный дом 6x6"
    const titleForName = `${typeLabel} ${String(width)}x${String(length)}`;

    const req = {
      name: [client.name || '', titleForName].filter(Boolean).join(' ').trim(),
      phone: '+' + phoneDigits,
      email: '',
      message,
      form_name: 'calculator',
      user_fields: {
        // Основные поля для АМО
        ClientName: String(client.name || ''),
        Address: String(address || ''),
        City: String(client.city || ''),
        
        // Поля калькулятора
        Type: type,
        TypeLabel: typeLabel,
        Width: String(width),
        Length: String(length),
        Insulation: String(insul || ''),
        Facade: String(facade || ''),
        Roof: String(roof || ''),
        Terrace: String(terrace || ''),
        Foundation: String(foundation || ''),
        Assembly: String(assembly || ''),
        Purpose: String(purpose || ''),
        PurposeText: String(
          purpose === 'other'
            ? purposeOther || 'Другое'
            : PURPOSE_LABELS[purpose] || purpose || ''
        ),
        
        // UTM параметры
        from_site: 'site',
        utm_source: UTM.utm_source || '',
        utm_medium: UTM.utm_medium || '',
        utm_campaign: UTM.utm_campaign || '',
        utm_term: UTM.utm_term || '',
        utm_content: UTM.utm_content || '',
        referrer: UTM.referrer || document.referrer || '',
        landing: UTM.landing || location.href,
        
        // Дополнительные поля для АМО
        source: 'Калькулятор',
        lead_source: 'Калькулятор',
        form_type: 'calc_smeta',
        
        // Тег для всех заявок с сайта
        tags: 'каркас',
      },
    };

    setStatus(null);
    const cb = function (resp) {
      // UIS может возвращать разные форматы ответов
      const ok = resp && (
        resp.result === 'success' || 
        resp.success === true || 
        resp.status === 'success' ||
        (resp.response && resp.response.success) ||
        // Если нет явной ошибки, считаем успешным
        (!resp.error && !resp.message)
      );
      
      if (ok) {
        try {
          ym(104121210, 'reachGoal', 'lead_submit_calc');
        } catch (e) {}
        setStatus('ok');
      } else {
        setStatus('err');
      }
    };
    window.sendLeadToUIS(req, cb);
  }

  const inputClass =
    'w-full rounded-xl border border-white/10 bg-neutral-900/60 px-3 py-2 text-white outline-none focus:ring-2 focus:ring-emerald-400';
  const fieldClass = 'rounded-2xl border border-white/10 bg-white/5 p-4';

  return (
    <>
      <section
        id="calc"
        className="bg-neutral-950 py-14 md:py-20 border-t border-white/10"
      >
        <div className="mx-auto max-w-7xl px-4">
          <div className="mx-auto max-w-4xl text-center">
            <div className="mb-3 text-sm font-medium tracking-widest text-white/70 uppercase">
              Калькулятор стоимости
            </div>
            <h2 className="text-3xl md:text-4xl font-semibold text-white leading-tight">
              Рассчитаем стоимость по вашей конфигурации
            </h2>
            <p className="mt-3 text-white/70 text-base md:text-lg">
              Выберите параметры — мы отправим смету и сроки строительства.
            </p>
          </div>

          <div className="mt-8 rounded-2xl border border-white/10 bg-white/5 p-5">
            <form onSubmit={onCalculate}>
              <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                <div className={fieldClass}>
                  <div className="text-white/80 font-medium mb-2">
                    Категория
                  </div>
                  <select
                    className={inputClass}
                    value={type}
                    onChange={(e) => setType(e.target.value)}
                  >
                    <option value="houses">Каркасный дом</option>
                    <option value="cabins">Бытовка</option>
                    <option value="sheds">Хозблок</option>
                  </select>
                  <div className="grid grid-cols-2 gap-3 mt-4">
                    <div>
                      <label className="block text-sm text-white/70 mb-1">
                        Ширина (м)
                      </label>
                      <select
                        className={inputClass}
                        value={width}
                        onChange={(e) => setWidth(+e.target.value)}
                      >
                        {SIZE[type].widths.map((w) => (
                          <option key={'w' + w} value={w}>
                            {w}
                          </option>
                        ))}
                      </select>
                    </div>
                    <div>
                      <label className="block text-sm text-white/70 mb-1">
                        Длина (м)
                      </label>
                      <select
                        className={inputClass}
                        value={length}
                        onChange={(e) => setLength(+e.target.value)}
                      >
                        {SIZE[type].lengths.map((l) => (
                          <option key={'l' + l} value={l}>
                            {l}
                          </option>
                        ))}
                      </select>
                    </div>
                  </div>
                  <div className="mt-4">
                    <label className="block text-sm text-white/70 mb-1">
                      Адрес / населённый пункт
                    </label>
                    <input
                      className={inputClass}
                      placeholder="Например: МО, Чехов, д. Ларионово"
                      value={address}
                      onChange={(e) => setAddress(e.target.value)}
                    />
                    <p className="mt-1 text-xs text-white/50">
                      Достаточно города и района — менеджер посчитает доставку.
                    </p>
                  </div>
                  <div className="mt-4">
                    <label className="block text-sm text-white/70 mb-1">
                      Цель использования
                    </label>
                    <select
                      className={inputClass}
                      value={purpose}
                      onChange={(e) => setPurpose(e.target.value)}
                    >
                      <option value="">Выберите</option>
                      <option value="summer">Летний дачный домик</option>
                      <option value="pmzh">ПМЖ / зимнее проживание</option>
                      <option value="guest">Гостевой дом</option>
                      <option value="rent">Аренда / кемпинг</option>
                      <option value="worksite">Бытовка для рабочих</option>
                      <option value="storage">Хозблок / склад</option>
                      <option value="other">Другое…</option>
                    </select>
                    {purpose === 'other' && (
                      <input
                        className={`${inputClass} mt-2`}
                        placeholder="Опишите своей фразой"
                        value={purposeOther}
                        onChange={(e) => setPurposeOther(e.target.value)}
                      />
                    )}
                  </div>
                </div>

                <div className={fieldClass}>
                  <div className="text-white/80 font-medium mb-2">
                    Конфигурация
                  </div>
                  {type === 'houses' && (
                    <div className="space-y-3">
                      <div>
                        <label className="block text-sm text-white/70 mb-1">
                          Утепление
                        </label>
                        <select
                          className={inputClass}
                          value={insul}
                          onChange={(e) => setInsul(e.target.value)}
                        >
                          <option value="100">100 мм</option>
                          <option value="150">150 мм</option>
                          <option value="200">200 мм</option>
                        </select>
                      </div>
                      <div>
                        <label className="block text-sm text-white/70 mb-1">
                          Отделка фасада
                        </label>
                        <select
                          className={inputClass}
                          value={facade}
                          onChange={(e) => setFacade(e.target.value)}
                        >
                          <option value="imit">Имитация бруса</option>
                          <option value="blockhaus">Блок-хаус</option>
                        </select>
                      </div>
                      <div>
                        <label className="block text-sm text-white/70 mb-1">
                          Кровля
                        </label>
                        <select
                          className={inputClass}
                          value={roof}
                          onChange={(e) => setRoof(e.target.value)}
                        >
                          <option value="proflist">Профлист</option>
                          <option value="metal">Металлочерепица</option>
                        </select>
                      </div>
                      <div>
                        <label className="block text-sm text-white/70 mb-1">
                          Терраса
                        </label>
                        <select
                          className={inputClass}
                          value={terrace}
                          onChange={(e) => setTerrace(e.target.value)}
                        >
                          <option value="none">Без террасы</option>
                          <option value="small">Терраса (малая)</option>
                          <option value="big">Терраса (большая)</option>
                        </select>
                      </div>
                      <div>
                        <label className="block text-sm text-white/70 mb-1">
                          Фундамент
                        </label>
                        <select
                          className={inputClass}
                          value={foundation}
                          onChange={(e) => setFoundation(e.target.value)}
                        >
                          <option value="blocks">Блоки 40×20×20</option>
                          <option value="screws_light">Сваи (стандарт)</option>
                          <option value="screws_heavy">Сваи (усиленные)</option>
                        </select>
                      </div>
                      <div>
                        <label className="block text-sm text-white/70 mb-1">
                          Сборка
                        </label>
                        <select
                          className={inputClass}
                          value={assembly}
                          onChange={(e) => setAssembly(e.target.value)}
                        >
                          <option value="standard">Обычная</option>
                          <option value="winter">Зимняя</option>
                        </select>
                      </div>
                    </div>
                  )}
                  {type === 'cabins' && (
                    <div className="space-y-3">
                      <div>
                        <label className="block text-sm text-white/70 mb-1">
                          Утепление
                        </label>
                        <select
                          className={inputClass}
                          value={insul}
                          onChange={(e) => setInsul(e.target.value)}
                        >
                          <option value="50">50 мм</option>
                          <option value="100">100 мм</option>
                        </select>
                      </div>
                      <div>
                        <label className="block text-sm text-white/70 mb-1">
                          Фундамент
                        </label>
                        <select
                          className={inputClass}
                          value={foundation}
                          onChange={(e) => setFoundation(e.target.value)}
                        >
                          <option value="blocks">Блоки</option>
                          <option value="screws_light">Сваи</option>
                        </select>
                      </div>
                    </div>
                  )}
                  {type === 'sheds' && (
                    <div className="text-sm text-white/60">
                      Комплектация фиксированная, можно добавить окна и
                      рассчитать доставку.
                    </div>
                  )}
                </div>

                <div className={fieldClass}>
                  <div className="text-white/80 font-medium mb-2">
                    Рассчитать стоимость
                  </div>
                  <button
                    type="submit"
                    className="w-full inline-flex items-center justify-center rounded-xl bg-white px-4 py-2 text-neutral-900 font-medium hover:opacity-90"
                  >
                    Рассчитать стоимость
                  </button>
                  <p className="mt-3 text-sm text-white/60">
                    Сформируем смету и свяжемся для уточнения деталей.
                  </p>
                  <pre className="mt-3 h-40 overflow-auto rounded-xl border border-white/10 bg-neutral-900/80 p-3 text-white/80 text-sm">
                    {summary || 'Результаты расчета.'}
                  </pre>
                </div>
              </div>
            </form>
          </div>
        </div>

        {isModalOpen && (
          <div className="fixed inset-0 z-[60] flex items-center justify-center">
            <div
              className="absolute inset-0 bg-black/60"
              onClick={() => setIsModalOpen(false)}
            />
            <div className="relative z-[61] w-[92vw] max-w-xl rounded-2xl border border-white/10 bg-neutral-950 p-5 shadow-2xl">
              <div className="flex items-start justify-between gap-4">
                <div className="text-white font-semibold text-xl">
                  Заявка на смету
                </div>
                <button
                  onClick={() => setIsModalOpen(false)}
                  className="rounded-lg px-2 py-1 text-white/70 hover:bg-white/10"
                >
                  ✕
                </button>
              </div>
              <pre className="mt-3 max-h-40 overflow-auto rounded-xl border border-white/10 bg-neutral-900/80 p-3 text-white/80 text-sm">
                {summary}
              </pre>
              <form
                onSubmit={onSubmitLead}
                className="mt-4 grid grid-cols-1 gap-3"
              >
                <input
                  className={inputClass}
                  required
                  placeholder="Ваше имя"
                  value={client.name}
                  onChange={(e) =>
                    setClient({ ...client, name: e.target.value })
                  }
                />
                <input
                  className={inputClass}
                  required
                  inputMode="tel"
                  pattern=".*"
                  placeholder="+7 999 123-45-67"
                  value={client.phone}
                  onChange={(e) =>
                    setClient({
                      ...client,
                      phone: normalizePhone(e.target.value),
                    })
                  }
                />
                <input
                  className={inputClass}
                  placeholder="Город/адрес"
                  value={client.city}
                  onChange={(e) =>
                    setClient({ ...client, city: e.target.value })
                  }
                />
                <input
                  type="text"
                  name="company"
                  className="hidden"
                  tabIndex="-1"
                  autoComplete="off"
                  onChange={() => {}}
                />
                <div className="flex flex-col sm:flex-row gap-2">
                  <button
                    type="submit"
                    className="flex-1 inline-flex items-center justify-center rounded-xl bg-white px-5 py-3 text-neutral-900 font-medium hover:opacity-90"
                    data-ev="lead_submit"
                    data-label="calc_modal"
                  >
                    Получить точную смету
                  </button>
                  <a
                    href="#"
                    onClick={(e) => {
                      e.preventDefault();
                      window.openWhatsAppTracked(
                        buildWA(
                          (summary &&
                            `Здравствуйте! Отправляю конфигурацию:\n\n${summary}\n\nПерезвоните, пожалуйста.`) ||
                            'Здравствуйте! Нужна смета.'
                        )
                      );
                    }}
                    className={`${BTN_WA} flex-1 px-5 py-3`}
                    data-ev="cta_wa"
                    data-label="calc_modal"
                  >
                    WhatsApp
                  </a>
                </div>
                {status === 'ok' && (
                  <div className="text-emerald-300 text-sm">
                    Спасибо! Запрос принят — свяжемся в ближайшее время.
                  </div>
                )}
                {status === 'err' && (
                  <div className="text-rose-300 text-sm">
                    Не удалось отправить. Попробуйте ещё раз или напишите в
                    WhatsApp.
                  </div>
                )}
              </form>
            </div>
          </div>
        )}
      </section>
    </>
  );
};

// ===== Глобальная форма лида: открывается по событию 'lead:open'
const LeadModal = () => {
  const [open, setOpen] = React.useState(false);
  React.useEffect(() => {
    document.body.classList.toggle('modal-open', open);
    return () => document.body.classList.remove('modal-open');
  }, [open]);

  const [ctx, setCtx] = React.useState(null);
  const [client, setClient] = React.useState({ name: '', phone: '', city: '' });
  const [status, setStatus] = React.useState(null);

  const inputClass =
    'w-full rounded-xl border border-white/10 bg-neutral-900/60 px-3 py-2 text-white outline-none focus:ring-2 focus:ring-emerald-400';

  const normalizePhone = (v) => {
    let digits = String(v || '').replace(/\D/g, '');
    if (digits.startsWith('8')) digits = '7' + digits.slice(1);
    if (!digits.startsWith('7')) digits = '7' + digits;
    return '+' + digits.slice(0, 11);
  };

  React.useEffect(() => {
    const onOpen = (e) => {
      setCtx(e.detail || {});
      setOpen(true);
      setStatus(null);
    };
    window.addEventListener('lead:open', onOpen);
    return () => window.removeEventListener('lead:open', onOpen);
  }, []);

  async function onSubmitLead(e) {
    e.preventDefault();

    const phoneDigits = String(client.phone || '').replace(/\D/g, '');
    if (phoneDigits.length < 10) {
      // Показываем ошибку валидации
      const errorMsg = document.createElement('div');
      errorMsg.textContent = 'Введите, пожалуйста, телефон полностью.';
      errorMsg.style.cssText = 'color: #e74c3c; margin-top: 10px; font-size: 14px;';
      
      const container = e.target.closest('.calc-form') || e.target.closest('.lead-modal');
      const existingError = container.querySelector('.calc-error');
      if (existingError) existingError.remove();
      errorMsg.className = 'calc-error';
      container.appendChild(errorMsg);
      
      setTimeout(() => {
        if (errorMsg.parentNode) errorMsg.remove();
      }, 3000);
      setStatus('err');
      return;
    }

    const message = [
      ctx?.title ? `Интерес: ${ctx.title}` : 'Интерес: Объект с сайта',
      ctx?.model ? `Модель: ${ctx.model}` : null,
      '',
      `Клиент: ${client.name || ''} +${phoneDigits} ${client.city || ''}`,
      '',
      `UTM: ${JSON.stringify(UTM)}`,
    ]
      .filter(Boolean)
      .join('\n');

    // Плоский заголовок без смайликов для имени контакта
    const guessCat = /бытовк/i.test(ctx?.title || '')
      ? 'Бытовка'
      : /хозблок/i.test(ctx?.title || '')
        ? 'Хозблок'
        : 'Каркасный дом';

    const modelPlain = String(ctx?.model || '').replace(/×/g, 'x');
    const titleForName = modelPlain
      ? `${guessCat} ${modelPlain}`
      : String(shortTitle(ctx?.title || ''))
          .split('—')[0]
          .replace(/×/g, 'x');

    const req = {
      name: [client.name || '', titleForName].filter(Boolean).join(' ').trim(),
      phone: '+' + phoneDigits,
      email: '',
      message,
      form_name: 'calculator',
      user_fields: {
        case_id: ctx?.id || '',
        model: modelPlain || '',
        title: String(ctx?.title || ''),
        from_site: 'site',

        ClientName: String(client.name || ''),
        City: String(client.city || ''),
        Address: String(client.city || ''), // здесь поле одно «Город/адрес», кладём и в Address

        ...UTM,
      },
    };

    setStatus(null);
    window.sendLeadToUIS(req, (resp) => {
      // UIS может возвращать разные форматы ответов
      const ok = resp && (
        resp.result === 'success' || 
        resp.success === true || 
        resp.status === 'success' ||
        (resp.response && resp.response.success) ||
        // Если нет явной ошибки, считаем успешным
        (!resp.error && !resp.message)
      );
      
      setStatus(ok ? 'ok' : 'err');
      if (ok) {
        try {
          if (typeof Comagic?.trackEvent === 'function')
            Comagic.trackEvent('Lead', 'GlobalModal', 'submit', '1');
        } catch (e) {}
      } else {
      }
    });
  }

  if (!open) return null;
  return (
    <div className="fixed inset-0 z-[70] flex items-center justify-center">
      <div
        className="absolute inset-0 bg-black/60"
        onClick={() => setOpen(false)}
      />
      <div className="relative z-[71] w-[92vw] max-w-xl rounded-2xl border border-white/10 bg-neutral-950 p-5 shadow-2xl">
        <div className="flex items-start justify-between gap-4">
          <div className="text-white font-semibold text-xl">Заявка</div>
          <button
            onClick={() => setOpen(false)}
            className="rounded-lg px-2 py-1 text-white/70 hover:bg-white/10"
          >
            ✕
          </button>
        </div>
        {ctx?.title && (
          <div className="mt-2 text-white/80 text-sm">
            {shortTitle(ctx.title)}
          </div>
        )}
        <form onSubmit={onSubmitLead} className="mt-4 grid grid-cols-1 gap-3">
          <input
            className={inputClass}
            required
            placeholder="Ваше имя"
            value={client.name}
            onChange={(e) => setClient({ ...client, name: e.target.value })}
          />
          <input
            className={inputClass}
            required
            inputMode="tel"
            pattern=".*"
            placeholder="+7 999 123-45-67"
            value={client.phone}
            onChange={(e) =>
              setClient({ ...client, phone: normalizePhone(e.target.value) })
            }
          />
          <input
            className={inputClass}
            placeholder="Город/адрес"
            value={client.city}
            onChange={(e) => setClient({ ...client, city: e.target.value })}
          />
          <div className="flex flex-col sm:flex-row gap-2">
            <button
              type="submit"
              className="flex-1 inline-flex items-center justify-center rounded-xl bg-white px-5 py-3 text-neutral-900 font-medium hover:opacity-90"
            >
              Отправить
            </button>
            <a
              href="#"
              onClick={(e) => {
                e.preventDefault();
                window.openWhatsAppTracked(
                  buildWA(
                    `Здравствуйте! Хочу такой объект: ${shortTitle(ctx?.title || '')}.`
                  )
                );
              }}
              className={`${BTN_WA} flex-1 px-5 py-3`}
            >
              WhatsApp
            </a>
          </div>
          {status === 'ok' && (
            <div className="text-emerald-300 text-sm">
              Спасибо! Запрос принят — свяжемся в ближайшее время.
            </div>
          )}
          {status === 'err' && (
            <div className="text-rose-300 text-sm">
              Не удалось отправить. Попробуйте ещё раз или напишите в WhatsApp.
            </div>
          )}
        </form>
      </div>
    </div>
  );
};

// ---------- НИЖЕ ДОЛЖЕН БЫТЬ ТОЛЬКО ОДИН ТАКОЙ БЛОК ----------
const Footer = () => (
  <footer className="bg-neutral-950 border-t border-white/10">
    <div className="mx-auto max-w-7xl px-4 py-8 grid gap-4 md:grid-cols-3 text-white/70 text-sm">
      <div>
        <div>г. Москва, м. Румянцево, ул. Адмирала Корнилова, 63Б/2</div>
        <div className="mt-1">
          Москва и{'\u00A0'}область{'\u00A0'}+ 250{'\u00A0'}км от{'\u00A0'}МКАД
        </div>
        <div className="mt-1">Ежедневно 08:00–20:00</div>
        <div className="mt-1">
          География: Тверь, Калуга, Тула, Рязань, Владимир; восток Смоленской;
          юго-запад Ярославской
        </div>
      </div>
      <div className="text-left md:text-right md:col-start-3 md:justify-self-end">
        <a href={MAIN_PHONE_LINK} className="text-white hover:underline">
          {MAIN_PHONE}
        </a>
        <br />
        <a
          href="#"
          onClick={(e) => {
            e.preventDefault();
            window.openWhatsAppTracked(
              buildWA('Здравствуйте! Нужна консультация.')
            );
          }}
          className="hover:underline"
        >
          WhatsApp
        </a>
      </div>
    </div>
    <div className="border-t border-white/10">
      <div className="mx-auto max-w-7xl px-4 py-4 text-white/50 text-xs flex flex-col md:flex-row md:items-center gap-1 md:gap-0 md:justify-between">
        <span>
          © 1999–{new Date().getFullYear()} {COMPANY_NAME}
        </span>
        <span className="md:text-right">
          Каркасные домики с утеплением, дачные летние домики, деревянные
          бытовки, хозблоки
        </span>
      </div>
    </div>
  </footer>
);

/* ==== LOGO (SVG) ==== */
const Logo = ({ lockup = 'full', className = '' }) => (
  <div className={`inline-flex items-center gap-2 ${className}`}>
    <svg
      viewBox="0 0 64 64"
      preserveAspectRatio="xMidYMid meet"
      aria-hidden={lockup !== 'full'}
      className="h-8 w-auto shrink-0 text-white"
    >
      <g
        stroke="currentColor"
        strokeWidth="3.5"
        strokeLinecap="round"
        strokeLinejoin="round"
        fill="none"
      >
        <path d="M8 28 L32 12 L56 28" />
        <path d="M14 28 V52 H50 V28" />
        <rect x="28" y="38" width="8" height="8" rx="1.5" />
      </g>
      <circle
        cx="52"
        cy="16"
        r="5"
        className="text-amber-400"
        fill="currentColor"
      />
      <path
        d="M14 52 L50 52"
        className="text-emerald-400"
        stroke="currentColor"
        strokeWidth="3.5"
        strokeLinecap="round"
      />
    </svg>
    {lockup === 'full' && (
      <div className="leading-tight select-none">
        <div className="font-semibold text-white">Конструктивные решения</div>
        <div className="text-[11px] md:text-xs text-white/60">
          Домики · бытовки · хозблоки
        </div>
      </div>
    )}
  </div>
);

/* ===================== APP ===================== */
const App = () => {
  useTypograf('.typo');
  React.useEffect(() => {
    const script = document.createElement('script');
    script.type = 'application/ld+json';
    script.text = JSON.stringify({
      '@context': 'https://schema.org',
      '@type': 'LocalBusiness',
      name: 'Конструктивные решения',
      telephone: '+7-495-132-38-30',
      areaServed: 'Москва и Московская область',
      address: {
        '@type': 'PostalAddress',
        addressLocality: 'Москва',
        streetAddress: 'ул. Адмирала Корнилова, 63Б/2',
      },
      url: window.location.origin,
      sameAs: [WHATSAPP_LINK],
    });
    document.head.appendChild(script);
    return () => {
      document.head.removeChild(script);
    };
  }, []);

  return (
    <main className="typo min-h-screen bg-neutral-950 text-white pb-28 md:pb-24">
      <Hero />
      <About />
      <Catalog />
      <section className="bg-neutral-950">
        <div className="relative mx-auto max-w-7xl px-4 py-10 rounded-2xl overflow-hidden ring-1 ring-amber-200/25 bg-[radial-gradient(140%_90%_at_0%_0%,rgba(251,191,36,0.12),transparent),radial-gradient(140%_90%_at_100%_0%,rgba(16,185,129,0.10),transparent),linear-gradient(0deg,rgba(255,255,255,0.03),rgba(255,255,255,0.03))]">
          <div
            className="pointer-events-none absolute inset-0 opacity-35 mix-blend-soft-light"
            style={{
              backgroundImage:
                'radial-gradient(rgba(255,255,255,.05) 1px, transparent 1px)',
              backgroundSize: '6px 6px',
            }}
          />
          <div className="flex flex-col items-center text-center gap-3">
            <div className="text-white">
              <div className="text-xl md:text-2xl font-semibold">
                Не нашли нужный размер?
              </div>
              <div className="text-white/85 text-sm md:text-base">
                Пришлите размеры или эскиз — подберём проект и назовём цену за 5
                минут.
              </div>
            </div>
            <div className="flex gap-2 justify-center flex-nowrap">
              <a
                href="#calc"
                className="inline-flex h-11 items-center justify-center rounded-xl bg-amber-400 px-4 text-neutral-900 text-sm font-semibold shadow-[0_6px_18px_rgba(251,191,36,.35)] hover:bg-amber-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-amber-300 transition whitespace-nowrap"
              >
                Рассчитать со специалистом
              </a>
              <a
                href="#"
                onClick={(e) => {
                  e.preventDefault();
                  window.openWhatsAppTracked(
                    buildWA('Здравствуйте! Хочу подбор каркасного строения.')
                  );
                }}
                className="inline-flex h-11 items-center justify-center rounded-xl bg-emerald-500 px-4 text-white text-sm font-semibold hover:bg-emerald-400 whitespace-nowrap"
              >
                WhatsApp
              </a>
            </div>
          </div>
        </div>
      </section>
      <Reviews />
      <Cases />
      <Steps />
      <FAQ />
      <Calculator />
      <Footer />
      <MobileCTA />
      <LeadModal />
    </main>
  );
};

/**
 * Img — подстраховка для путей/расширений.
 * Пробует исходный src, затем варианты: ./, /, /site/ и расширения: webp, jpg, jpeg, png.
 */
const Img = ({ src, alt = '', className = '', ...rest }) => {
  const candidates = React.useMemo(() => {
    if (!src) return [];
    const clean = src.replace(/^\.?\//, '');
    const parts = clean.split('/');
    const file = parts.pop();
    const dir = parts.join('/');
    const m = file.match(/^(.+?)(\.[a-z0-9]+)?$/i);
    const base = m ? m[1] : file;
    const ext = m && m[2] ? m[2].toLowerCase() : '';
    const extOrder = ['.webp', '.jpg', '.jpeg', '.png'];
    const tryExts = ext
      ? [ext, ...extOrder.filter((e) => e !== ext)]
      : extOrder;
    const baseDirs = [dir ? `${dir}/${base}` : base, `images/${base}`];
    const list = [];
    baseDirs.forEach((b) => {
      tryExts.forEach((e) => {
        list.push(`./${b}${e}`);
        list.push(`${b}${e}`);
        list.push(`/site/${b}${e}`);
        list.push(`/${b}${e}`);
      });
    });
    list.push(src);
    return Array.from(new Set(list));
  }, [src]);

  const [i, setI] = React.useState(0);
  const onError = () =>
    setI((prev) => (prev + 1 < candidates.length ? prev + 1 : prev));
  const current = candidates[i] || src;
  return (
    <img
      src={current}
      alt={alt}
      className={className}
      loading="lazy"
      onError={onError}
      {...rest}
    />
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
