/* Shared components, hooks, constants for Аудитор Рынка */

const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ---------- Reveal on intersection ----------
function useReveal(rootRef) {
  useEffect(() => {
    const root = rootRef?.current || document;
    const els = root.querySelectorAll('.reveal');
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) e.target.classList.add('in');
        else e.target.classList.remove('in');
      });
    }, { threshold: 0.18 });
    els.forEach(el => io.observe(el));
    return () => io.disconnect();
  }, [rootRef]);
}

// ---------- Snap-scroll observer (which screen is visible) ----------
function useActiveScreen(rootRef) {
  const [active, setActive] = useState(0);
  useEffect(() => {
    const root = rootRef.current;
    if (!root) return;
    const screens = root.querySelectorAll('.screen');
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting && e.intersectionRatio > 0.55) {
          const idx = [...screens].indexOf(e.target);
          if (idx >= 0) setActive(idx);
        }
      });
    }, { threshold: [0.55, 0.75] , root });
    screens.forEach(s => io.observe(s));
    return () => io.disconnect();
  }, [rootRef]);
  return active;
}

// ---------- Haptic helper ----------
// Pattern [4,12,4] = short double-tick — felt on Android. iOS Safari
// silently ignores Web Vibration API; visual press-feedback in CSS covers it.
function useHaptic() {
  return useCallback((pattern) => {
    try { navigator.vibrate?.(pattern || [4, 12, 4]); } catch {}
  }, []);
}

// ---------- Smooth scroll (custom rAF-based, ~25% faster than browser default) ----------
function smoothScrollTo(container, top, duration = 480) {
  if (!container) return;
  const start = container.scrollTop;
  const delta = top - start;
  if (Math.abs(delta) < 1) return;
  const t0 = performance.now();
  const ease = (t) => 1 - Math.pow(1 - t, 3); // cubic ease-out
  const step = (now) => {
    const t = Math.min(1, (now - t0) / duration);
    container.scrollTop = start + delta * ease(t);
    if (t < 1) requestAnimationFrame(step);
  };
  requestAnimationFrame(step);
}

// ---------- Page transition (curtain) ----------
function navigateWithCurtain(href) {
  const c = document.createElement('div');
  c.className = 'curtain in';
  document.body.appendChild(c);
  // Curtain animation is .65s; navigate just before it completes so the next
  // page's boot-curtain (in HTML) takes over at translateY(0) seamlessly.
  setTimeout(() => { window.location.href = href; }, 620);
}

// ---------- Top nav ----------
const PAGES = [
  { key: 'hub',         label: 'Подход',     href: 'index.html' },
  { key: 'kapital',     label: 'Инвестору',  href: 'kapital.html' },
  { key: 'baza',        label: 'Семье',      href: 'baza.html' },
  { key: 'rezidentsiya',label: 'Трофейное',  href: 'rezidentsiya.html' },
];

function TopNav({ currentPage }) {
  const [open, setOpen] = useState(false);
  const haptic = useHaptic();

  useEffect(() => {
    if (open) {
      const prev = document.body.style.overflow;
      document.body.style.overflow = 'hidden';
      return () => { document.body.style.overflow = prev; };
    }
  }, [open]);

  const go = (href, key) => {
    if (currentPage === key) { setOpen(false); return; }
    navigateWithCurtain(href);
  };

  return (
    <>
      <div className="nav">
        <a className="nav-brand" href="index.html" onClick={(e) => { e.preventDefault(); navigateWithCurtain('index.html'); }}>
          <span className="dot"></span>
          <span>АУДИТОР РЫНКА · ПХУКЕТ ’26</span>
        </a>
        <div className="nav-links">
          {PAGES.map(p => (
            <a key={p.key}
               href={p.href}
               className={currentPage === p.key ? 'active' : ''}
               onClick={(e) => {
                 if (currentPage === p.key) { e.preventDefault(); return; }
                 e.preventDefault(); navigateWithCurtain(p.href);
               }}>
              {p.label}
            </a>
          ))}
        </div>
        <button
          className={'nav-burger ' + (open ? 'open' : '')}
          aria-label={open ? 'Закрыть меню' : 'Открыть меню'}
          aria-expanded={open}
          onClick={() => { haptic(6); setOpen(o => !o); }}>
          <span className="bar-line b1"></span>
          <span className="bar-line b2"></span>
          <span className="bar-line b3"></span>
        </button>
      </div>

      <div className={'nav-overlay ' + (open ? 'open' : '')} aria-hidden={!open}>
        <div className="nav-overlay-head">
          <span>НАВИГАЦИЯ · 2026</span>
          <button className="close" aria-label="Закрыть" onClick={() => { haptic(6); setOpen(false); }}>
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
              <path d="M6 6l12 12M18 6L6 18" strokeLinecap="round"/>
            </svg>
          </button>
        </div>
        <nav className="nav-overlay-links">
          {PAGES.map((p, i) => (
            <a key={p.key}
               href={p.href}
               className={currentPage === p.key ? 'active' : ''}
               onClick={(e) => { e.preventDefault(); haptic(6); go(p.href, p.key); }}>
              <span>{p.label}</span>
              <span className="num">{String(i + 1).padStart(2, '0')}</span>
            </a>
          ))}
        </nav>
        <div className="nav-overlay-foot">
          <span>ПХУКЕТ · ТАИЛАНД</span>
          <a href="https://t.me/khabibullin_azamat" target="_blank" rel="noreferrer">
            <Icon.Telegram /> Telegram
          </a>
        </div>
      </div>
    </>
  );
}

// ---------- Progress rail ----------
function ProgressRail({ screens, activeIdx, onJump }) {
  return (
    <div className="rail">
      {screens.map((s, i) => (
        <div key={i}
             className={'tick ' + (i === activeIdx ? 'active' : '')}
             onClick={() => onJump(i)}>
          <span className="label">{s}</span>
          <span className="bar"></span>
          <span>{String(i+1).padStart(2,'0')}</span>
        </div>
      ))}
    </div>
  );
}

// ---------- Placeholder imagery ----------
function Placeholder({ label, style, className }) {
  return (
    <div className={'placeholder ' + (className || '')} style={style}>
      <div className="ph-label">{label}</div>
    </div>
  );
}

// ---------- Icons (simple inline SVG — we don't have lucide-react available) ----------
const Icon = {
  ArrowRight: (p) => (
    <svg width={p.size||16} height={p.size||16} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <path d="M5 12h14M13 5l7 7-7 7" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  ArrowDown: (p) => (
    <svg width={p.size||16} height={p.size||16} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <path d="M12 5v14M5 13l7 7 7-7" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  ArrowUpRight: (p) => (
    <svg width={p.size||16} height={p.size||16} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <path d="M7 17L17 7M8 7h9v9" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  Check: (p) => (
    <svg width={p.size||16} height={p.size||16} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <path d="M4 12l5 5L20 6" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  Shield: (p) => (
    <svg width={p.size||18} height={p.size||18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <path d="M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6l8-3z" strokeLinejoin="round"/>
    </svg>
  ),
  Chart: (p) => (
    <svg width={p.size||18} height={p.size||18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <path d="M3 20h18M6 16V9M11 16V5M16 16v-6M21 16v-3" strokeLinecap="round"/>
    </svg>
  ),
  Map: (p) => (
    <svg width={p.size||18} height={p.size||18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <path d="M9 4l-6 3v13l6-3 6 3 6-3V4l-6 3-6-3zM9 4v13M15 7v13" strokeLinejoin="round"/>
    </svg>
  ),
  Key: (p) => (
    <svg width={p.size||18} height={p.size||18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <circle cx="8" cy="15" r="4"/>
      <path d="M11 12l9-9M16 6l3 3" strokeLinecap="round"/>
    </svg>
  ),
  Diamond: (p) => (
    <svg width={p.size||18} height={p.size||18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <path d="M3 9l4-5h10l4 5-9 11L3 9zM3 9h18M9 4l3 5 3-5" strokeLinejoin="round"/>
    </svg>
  ),
  Building: (p) => (
    <svg width={p.size||18} height={p.size||18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <path d="M4 21V5l8-2 8 2v16M4 21h16M8 9h2M8 13h2M8 17h2M14 9h2M14 13h2M14 17h2" strokeLinecap="round"/>
    </svg>
  ),
  Telegram: (p) => (
    <svg width={p.size||14} height={p.size||14} viewBox="0 0 24 24" fill="currentColor">
      <path d="M21 3L2 11l5 2 2 6 3-4 5 4 4-16z"/>
    </svg>
  ),
  Document: (p) => (
    <svg width={p.size||18} height={p.size||18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <path d="M14 3H6a2 2 0 00-2 2v14a2 2 0 002 2h12a2 2 0 002-2V9l-6-6z" strokeLinejoin="round"/>
      <path d="M14 3v6h6M8 13h8M8 17h6" strokeLinecap="round"/>
    </svg>
  ),
  Handshake: (p) => (
    <svg width={p.size||18} height={p.size||18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <circle cx="9" cy="12" r="4"/>
      <circle cx="15" cy="12" r="4"/>
    </svg>
  ),
};

// ---------- Corner marks wrapper ----------
function Corners({ children, style, className }) {
  return (
    <div className={className} style={{ position: 'relative', ...style }}>
      <span className="corner tl"></span>
      <span className="corner tr"></span>
      <span className="corner bl"></span>
      <span className="corner br"></span>
      {children}
    </div>
  );
}

// ---------- Screen index/tag labels ----------
function ScreenMeta({ index, total, tag }) {
  return (
    <>
      <div className="screen-index">
        {String(index).padStart(2,'0')} / {String(total).padStart(2,'0')}
      </div>
      <div className="screen-tag">{tag}</div>
    </>
  );
}

// ---------- Tweaks panel ----------
const TWEAK_KEY = 'audit_tweaks_v1';
function useTweaks(defaults) {
  const [tweaks, setTweaks] = useState(() => {
    try {
      const saved = JSON.parse(localStorage.getItem(TWEAK_KEY) || '{}');
      return { ...defaults, ...saved };
    } catch { return defaults; }
  });
  const set = useCallback((key, value) => {
    setTweaks(prev => {
      const next = { ...prev, [key]: value };
      try { localStorage.setItem(TWEAK_KEY, JSON.stringify(next)); } catch {}
      try {
        window.parent.postMessage({ type: '__edit_mode_set_keys', edits: { [key]: value } }, '*');
      } catch {}
      return next;
    });
  }, []);
  return [tweaks, set];
}

function TweaksPanel({ open, tweaks, onSet, schema }) {
  if (!open) return null;
  return (
    <div className="tweaks">
      <h4>Tweaks · настройка</h4>
      {schema.map(s => (
        <label key={s.key}>
          <span>{s.label}</span>
          <span className="opts">
            {s.options.map(o => (
              <button
                key={o.value}
                className={tweaks[s.key] === o.value ? 'active' : ''}
                onClick={() => onSet(s.key, o.value)}>
                {o.label}
              </button>
            ))}
          </span>
        </label>
      ))}
    </div>
  );
}

function useEditModeBridge() {
  const [open, setOpen] = useState(false);
  useEffect(() => {
    function onMsg(e) {
      const d = e.data;
      if (!d || typeof d !== 'object') return;
      if (d.type === '__activate_edit_mode') setOpen(true);
      if (d.type === '__deactivate_edit_mode') setOpen(false);
    }
    window.addEventListener('message', onMsg);
    try { window.parent.postMessage({ type: '__edit_mode_available' }, '*'); } catch {}
    return () => window.removeEventListener('message', onMsg);
  }, []);
  return open;
}

// ---------- Apply tweaks as CSS vars on the root ----------
function applyTweakStyles(tweaks) {
  const root = document.documentElement;
  const accentMap = {
    blue: 'oklch(0.38 0.12 250)',
    gold: 'oklch(0.52 0.10 75)',
    ink:  '#1d1d1f',
  };
  root.style.setProperty('--accent', accentMap[tweaks.accent] || accentMap.blue);
  const surfaceMap = {
    white: '#ffffff',
    bone:  '#f7f5f1',
    pearl: '#eff0ec',
  };
  root.style.setProperty('--bg', surfaceMap[tweaks.surface] || '#ffffff');
  document.body.style.background = surfaceMap[tweaks.surface] || '#ffffff';
}

// ---------- Chart frame: dismiss "swipe" hint on first touch ----------
function useChartFrameHints(rootRef) {
  useEffect(() => {
    const root = rootRef?.current || document;
    const frames = root.querySelectorAll('.chart-frame');
    const handlers = [];
    frames.forEach(f => {
      const handler = () => f.classList.add('touched');
      f.addEventListener('touchstart', handler, { passive: true });
      f.addEventListener('scroll', handler, { passive: true });
      handlers.push([f, handler]);
    });
    return () => handlers.forEach(([f, h]) => {
      f.removeEventListener('touchstart', h);
      f.removeEventListener('scroll', h);
    });
  }, [rootRef]);
}

// ---------- Share via window ----------
Object.assign(window, {
  useReveal, useActiveScreen, useTweaks, useEditModeBridge,
  useHaptic, useChartFrameHints, smoothScrollTo,
  TopNav, ProgressRail, Placeholder, Icon,
  Corners, ScreenMeta, navigateWithCurtain, TweaksPanel, applyTweakStyles,
});
