// Shared utilities + hooks for Alin Global variants
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ===== Routing =====================================================

// Hash-based router with a lightweight param capture: #/article/:slug
function useHashRoute(defaultRoute = 'home') {
  const parse = () => {
    const h = window.location.hash.replace(/^#\/?/, '');
    if (!h) return { route: defaultRoute, param: null };
    const parts = h.split('/');
    return { route: parts[0] || defaultRoute, param: parts[1] || null };
  };
  const [state, setState] = useState(parse);
  useEffect(() => {
    const onHash = () => {
      setState(parse());
      window.scrollTo({ top: 0, behavior: 'instant' });
    };
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);
  const go = (r) => { window.location.hash = '/' + r; };
  return [state.route, go, state.param];
}

// ===== Language ====================================================

const ALIN_LANGS = ['he', 'en', 'ru'];

function useLanguage(initial = 'he') {
  const [lang, setLang] = useState(() => {
    const stored = localStorage.getItem('alin-lang');
    return ALIN_LANGS.includes(stored) ? stored : initial;
  });
  useEffect(() => {
    localStorage.setItem('alin-lang', lang);
    document.documentElement.lang = lang;
    document.documentElement.dir = lang === 'he' ? 'rtl' : 'ltr';
  }, [lang]);
  const t = window.ALIN_CONTENT[lang];
  return { lang, setLang, t };
}

// Three-way language toggle (HE / EN / RU)
function LangToggle({ lang, setLang, variant = 'default' }) {
  const entries = [
    { k: 'he', label: 'עב' },
    { k: 'en', label: 'EN' },
    { k: 'ru', label: 'RU' },
  ];
  return (
    <div className={`lang-toggle lang-toggle--${variant}`} role="group" aria-label="Language">
      {entries.map((e, i) => (
        <React.Fragment key={e.k}>
          <button
            type="button"
            onClick={() => setLang(e.k)}
            className={lang === e.k ? 'is-active' : ''}
            aria-pressed={lang === e.k}
          >
            {e.label}
          </button>
          {i < entries.length - 1 && <span className="lang-sep">/</span>}
        </React.Fragment>
      ))}
    </div>
  );
}

// ===== FAQ =========================================================

function FAQItem({ q, a, isOpen, onToggle, idx, lang }) {
  return (
    <div className={`faq-item ${isOpen ? 'is-open' : ''}`}>
      <button className="faq-q" onClick={onToggle}>
        <span className="faq-q-num">{String(idx + 1).padStart(2, '0')}</span>
        <span className="faq-q-text">{q}</span>
        <span className="faq-q-icon" aria-hidden>
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
            <path d={isOpen ? "M6 12h12" : "M12 6v12M6 12h12"} strokeLinecap="round"/>
          </svg>
        </span>
      </button>
      <div className="faq-a-wrap" style={{ maxHeight: isOpen ? '400px' : '0' }}>
        <div className="faq-a">{a}</div>
      </div>
    </div>
  );
}

function FAQ({ t, lang }) {
  const [open, setOpen] = useState(0);
  return (
    <div className="faq-list">
      {t.faq.items.map((item, i) => (
        <FAQItem
          key={i}
          idx={i}
          q={item.q}
          a={item.a}
          isOpen={open === i}
          onToggle={() => setOpen(open === i ? -1 : i)}
          lang={lang}
        />
      ))}
    </div>
  );
}

// ===== Payload CMS API =============================================

const CMS_API = window.ALIN_CMS_API || 'https://alin-cms-payload.natali-526.workers.dev';

// Translate app locale to Payload locale — CMS authored in en, translated to he/ru
function cmsLocale(lang) {
  return lang === 'he' ? 'he' : lang === 'ru' ? 'ru' : 'en';
}

function mediaUrl(doc) {
  if (!doc || typeof doc !== 'object') return null;
  const u = doc.url;
  if (!u) return null;
  if (u.startsWith('http://') || u.startsWith('https://')) return u;
  return CMS_API + u;
}

async function fetchCms(path, params = {}) {
  const qs = new URLSearchParams();
  for (const [k, v] of Object.entries(params)) {
    if (v !== undefined && v !== null && v !== '') qs.set(k, String(v));
  }
  const url = `${CMS_API}/api/${path}${qs.toString() ? '?' + qs.toString() : ''}`;
  const res = await fetch(url, { headers: { 'accept': 'application/json' } });
  if (!res.ok) throw new Error(`CMS ${res.status}: ${res.statusText}`);
  return res.json();
}

function useArticles({ lang, featured = false, categorySlug, tagSlug, search, limit = 50 }) {
  const [state, setState] = useState({ loading: true, articles: [], error: null });
  useEffect(() => {
    let alive = true;
    setState({ loading: true, articles: [], error: null });
    const params = {
      locale: cmsLocale(lang),
      depth: 2,
      limit,
      sort: '-publishedAt',
    };
    const whereParts = [];
    if (featured) whereParts.push(['where[isFeatured][equals]', 'true']);
    if (categorySlug) whereParts.push(['where[category.slug][equals]', categorySlug]);
    if (tagSlug) whereParts.push(['where[tags.slug][contains]', tagSlug]);
    if (search) {
      whereParts.push(['where[or][0][title][like]', search]);
      whereParts.push(['where[or][1][excerpt][like]', search]);
    }
    const qs = new URLSearchParams();
    Object.entries(params).forEach(([k, v]) => qs.set(k, String(v)));
    whereParts.forEach(([k, v]) => qs.set(k, v));
    fetch(`${CMS_API}/api/articles?${qs.toString()}`, { headers: { accept: 'application/json' } })
      .then(r => { if (!r.ok) throw new Error('CMS ' + r.status); return r.json(); })
      .then(data => { if (alive) setState({ loading: false, articles: data.docs || [], error: null }); })
      .catch(err => { if (alive) setState({ loading: false, articles: [], error: String(err) }); });
    return () => { alive = false; };
  }, [lang, featured, categorySlug, tagSlug, search, limit]);
  return state;
}

function useArticle({ lang, slug }) {
  const [state, setState] = useState({ loading: true, article: null, error: null });
  useEffect(() => {
    if (!slug) { setState({ loading: false, article: null, error: 'no-slug' }); return; }
    let alive = true;
    setState({ loading: true, article: null, error: null });
    fetchCms('articles', { locale: cmsLocale(lang), depth: 2, limit: 1, 'where[slug][equals]': slug })
      .then(data => { if (alive) setState({ loading: false, article: data.docs?.[0] || null, error: null }); })
      .catch(err => { if (alive) setState({ loading: false, article: null, error: String(err) }); });
    return () => { alive = false; };
  }, [lang, slug]);
  return state;
}

function useCategories(lang) {
  const [data, setData] = useState([]);
  useEffect(() => {
    let alive = true;
    fetchCms('categories', { locale: cmsLocale(lang), limit: 50 })
      .then(d => { if (alive) setData(d.docs || []); })
      .catch(() => { if (alive) setData([]); });
    return () => { alive = false; };
  }, [lang]);
  return data;
}

function useTags(lang) {
  const [data, setData] = useState([]);
  useEffect(() => {
    let alive = true;
    fetchCms('tags', { locale: cmsLocale(lang), limit: 100 })
      .then(d => { if (alive) setData(d.docs || []); })
      .catch(() => { if (alive) setData([]); });
    return () => { alive = false; };
  }, [lang]);
  return data;
}

function formatArticleDate(iso, lang) {
  if (!iso) return '';
  const d = new Date(iso);
  const locale = lang === 'he' ? 'he-IL' : lang === 'ru' ? 'ru-RU' : 'en-US';
  return d.toLocaleDateString(locale, { year: 'numeric', month: 'long', day: 'numeric' });
}

function isAutoTranslated(article, lang) {
  if (!article || !article.isAutoTranslated) return false;
  if (lang === 'he') return !!article.isAutoTranslated.he;
  if (lang === 'ru') return !!article.isAutoTranslated.ru;
  return false;
}

// ===== Lexical rich text renderer ==================================

function LexicalTextNode({ node, index }) {
  const f = node.format || 0;
  let el = node.text;
  if (f & 1) el = <strong>{el}</strong>;
  if (f & 2) el = <em>{el}</em>;
  if (f & 4) el = <s>{el}</s>;
  if (f & 8) el = <u>{el}</u>;
  if (f & 16) el = <code>{el}</code>;
  return <React.Fragment key={index}>{el}</React.Fragment>;
}

function LexicalNode({ node, index }) {
  if (!node) return null;
  const children = (node.children || []).map((c, i) => <LexicalNode key={i} node={c} index={i} />);
  switch (node.type) {
    case 'root': return <>{children}</>;
    case 'heading': {
      const Tag = node.tag || 'h2';
      return React.createElement(Tag, null, children);
    }
    case 'paragraph': return <p>{children}</p>;
    case 'text': return <LexicalTextNode node={node} index={index} />;
    case 'linebreak': return <br />;
    case 'link': return <a href={node.fields?.url || '#'} target="_blank" rel="noopener noreferrer">{children}</a>;
    case 'list': return node.listType === 'number' ? <ol>{children}</ol> : <ul>{children}</ul>;
    case 'listitem': return <li>{children}</li>;
    case 'quote': return <blockquote>{children}</blockquote>;
    case 'block': {
      const blockType = node.fields?.blockType;
      if (blockType === 'youtube') {
        const id = node.fields?.url || '';
        const caption = node.fields?.caption;
        return (
          <figure className="article-inline-video">
            <YouTubeEmbed id={id} />
            {caption && <figcaption>{caption}</figcaption>}
          </figure>
        );
      }
      return null;
    }
    case 'relationship':
    case 'upload': return null;
    default: return <>{children}</>;
  }
}

function LexicalRender({ content }) {
  if (!content?.root) return null;
  return <div className="article-body-prose"><LexicalNode node={content.root} index={0} /></div>;
}

// ===== Article card (unified styling) ==============================

function ArticleCard({ article, lang, t }) {
  const imgUrl = mediaUrl(article.featuredImage);
  const cat = article.category?.name;
  const date = formatArticleDate(article.publishedAt, lang);
  return (
    <a className="v1-post" href={`#/article/${article.slug}`}>
      <div className="v1-post-img">
        {imgUrl ? <img src={imgUrl} alt={article.title} className="site-img" />
                : <div className="ph-img"><span>Image</span></div>}
      </div>
      <div className="v1-post-meta">
        {cat && <span>{cat}</span>}
        <span>{date}</span>
      </div>
      <h3 className="v1-post-title">{article.title}</h3>
      <p className="v1-post-excerpt">{article.excerpt}</p>
      <span className="btn-link">{t.blog.read}</span>
    </a>
  );
}

// ===== Pages =======================================================

function BlogPage({ t, lang }) {
  const [categorySlug, setCategorySlug] = useState('');
  const [tagSlug, setTagSlug] = useState('');
  const [searchInput, setSearchInput] = useState('');
  const [search, setSearch] = useState('');
  const categories = useCategories(lang);
  const tags = useTags(lang);
  const { loading, articles } = useArticles({ lang, categorySlug, tagSlug, search });

  const onSearchSubmit = (e) => { e.preventDefault(); setSearch(searchInput.trim()); };

  return (
    <div className="blog-page">
      <div className="blog-page-header">
        <span className="eyebrow">{t.blog.eyebrow}</span>
        <h1 className="page-title">{t.blog.page_title}</h1>
        <p className="page-lead">{t.blog.page_lead}</p>
      </div>

      <form className="blog-filters" onSubmit={onSearchSubmit}>
        <label className="blog-filter">
          <span>{t.blog.filter_label_category}</span>
          <select value={categorySlug} onChange={e => setCategorySlug(e.target.value)}>
            <option value="">{t.blog.all_categories}</option>
            {categories.map(c => <option key={c.id} value={c.slug}>{c.name}</option>)}
          </select>
        </label>
        <label className="blog-filter">
          <span>{t.blog.filter_label_tag}</span>
          <select value={tagSlug} onChange={e => setTagSlug(e.target.value)}>
            <option value="">{t.blog.all_tags}</option>
            {tags.map(tg => <option key={tg.id} value={tg.slug}>{tg.name}</option>)}
          </select>
        </label>
        <label className="blog-filter blog-filter--search">
          <span>&nbsp;</span>
          <input
            type="search"
            placeholder={t.blog.search_placeholder}
            value={searchInput}
            onChange={e => setSearchInput(e.target.value)}
          />
        </label>
      </form>

      {loading ? (
        <div className="blog-status">{t.blog.loading}</div>
      ) : articles.length === 0 ? (
        <div className="blog-status">{t.blog.empty}</div>
      ) : (
        <div className="blog-grid">
          {articles.map(a => <ArticleCard key={a.id} article={a} lang={lang} t={t} />)}
        </div>
      )}
    </div>
  );
}

function ArticlePage({ t, lang, slug }) {
  const { loading, article } = useArticle({ lang, slug });
  if (loading) return <div className="article-page"><div className="blog-status">{t.blog.loading}</div></div>;
  if (!article) return (
    <div className="article-page">
      <div className="blog-status">{t.blog.empty}</div>
      <a href="#/blog" className="btn-link">{t.blog.back_to_list}</a>
    </div>
  );
  const imgUrl = mediaUrl(article.featuredImage);
  const auto = isAutoTranslated(article, lang);
  const cat = article.category?.name;
  const catSlug = article.category?.slug;
  const date = formatArticleDate(article.publishedAt, lang);
  return (
    <div className="article-page">
      <div className="article-page-inner">
        <a href="#/blog" className="article-back">{t.blog.back_to_list}</a>

        {auto && (
          <div className="translated-banner" role="note">
            <strong>{t.blog.translated_banner_title}</strong>
            <span>{t.blog.translated_banner_body}</span>
          </div>
        )}

        {imgUrl && (
          <div className="article-hero">
            <img src={imgUrl} alt={article.title} className="site-img" />
          </div>
        )}

        <div className="article-meta-row">
          {cat && <span className="article-cat">{cat}</span>}
          <span className="article-date">{t.blog.published_on}: {date}</span>
        </div>

        <h1 className="article-title">{article.title}</h1>
        {article.excerpt && <p className="article-lede">{article.excerpt}</p>}

        {article.videoEmbed?.youtubeId && article.videoEmbed.position !== 'bottom' && (
          <YouTubeEmbed id={article.videoEmbed.youtubeId} title={article.title} />
        )}

        {article.videoEmbed?.position !== 'only' && <LexicalRender content={article.content} />}

        {article.videoEmbed?.youtubeId && article.videoEmbed.position === 'bottom' && (
          <YouTubeEmbed id={article.videoEmbed.youtubeId} title={article.title} />
        )}

        {(article.tags || []).length > 0 && (
          <div className="article-tags">
            {article.tags.filter(Boolean).map(tg => (
              <span key={tg.id} className="article-tag">{tg.name}</span>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function YouTubeEmbed({ id, title }) {
  const vid = (id || '').match(/(?:youtube\.com\/(?:watch\?v=|embed\/)|youtu\.be\/)([A-Za-z0-9_-]{11})/);
  const yt = vid ? vid[1] : id;
  return (
    <div className="article-video">
      <iframe
        src={`https://www.youtube.com/embed/${yt}`}
        title={title || 'Video'}
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        allowFullScreen
        frameBorder="0"
      />
    </div>
  );
}

// ===== Static pages (unchanged from original, trilingual-safe) ====

function AboutPage({ t, lang }) {
  return (
    <div className="about-page">
      <div className="about-page-grid">
        <div className="about-page-img"><img src="images/practice.png" alt="" className="site-img" /></div>
        <div className="about-page-text">
          <span className="eyebrow">{t.about.eyebrow}</span>
          <h1 className="page-title">{t.about.title}</h1>
          {t.about.body.split('\n\n').map((p, i) => <p key={i}>{p}</p>)}
          <div className="about-creds">
            {t.about.credentials.map((c, i) => <span key={i} className="cred-tag">{c}</span>)}
          </div>
        </div>
      </div>
    </div>
  );
}

function ServicesPage({ t, lang }) {
  return (
    <div className="services-page">
      <div className="services-page-header">
        <span className="eyebrow">{t.services.eyebrow}</span>
        <h1 className="page-title">{t.services.title}</h1>
      </div>
      <div className="services-full-list">
        {t.services.items.map((s, i) => (
          <div key={i} className="service-full">
            <div className="service-full-num">{s.k}</div>
            <div className="service-full-body">
              <h3>{s.title}</h3>
              <p>{s.body}</p>
              <a className="service-full-cta" href="#/contact">{s.cta} →</a>
            </div>
            <div className="service-full-img"><img src={`images/${s.k === '01' ? 'practice' : s.k === '02' ? 'workshop' : 'hero'}.png`} alt="" className="site-img" /></div>
          </div>
        ))}
      </div>
    </div>
  );
}

function ContactPage({ t, lang }) {
  const [sent, setSent] = useState(false);
  const labelName = lang === 'he' ? 'שם' : lang === 'ru' ? 'Имя' : 'Name';
  const labelPhone = lang === 'he' ? 'טלפון' : lang === 'ru' ? 'Телефон' : 'Phone';
  const labelMsg = lang === 'he' ? 'מה הכי מעסיק אותך?' : lang === 'ru' ? 'Что вас больше всего беспокоит?' : 'What is on your mind?';
  const labelSend = lang === 'he' ? 'שלחי' : lang === 'ru' ? 'Отправить' : 'Send';
  const labelSent = lang === 'he' ? 'נשלח ✓' : lang === 'ru' ? 'Отправлено ✓' : 'Sent ✓';
  const labelLeave = lang === 'he' ? 'או השאירי פרטים' : lang === 'ru' ? 'Или оставьте свои данные' : 'Or leave your details';
  return (
    <div className="contact-page">
      <div className="contact-page-grid">
        <div className="contact-page-intro">
          <span className="eyebrow">{t.contact.eyebrow}</span>
          <h1 className="page-title">{t.contact.title}</h1>
          <p className="page-lead">{t.contact.body}</p>
          <div className="contact-methods">
            <a className="contact-method contact-method--primary" href="#">
              <span className="cm-icon">
                <svg viewBox="0 0 24 24" fill="currentColor"><path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.263.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/></svg>
              </span>
              <span className="cm-label">WhatsApp</span>
              <span className="cm-value">{t.contact.phone_num}</span>
            </a>
            <a className="contact-method" href={`tel:${t.contact.phone_num}`}>
              <span className="cm-icon">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.67A2 2 0 014.11 2h3a2 2 0 012 1.72c.127.96.361 1.903.7 2.81a2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0122 16.92z"/></svg>
              </span>
              <span className="cm-label">{t.contact.phone}</span>
              <span className="cm-value">{t.contact.phone_num}</span>
            </a>
            <a className="contact-method" href={`mailto:${t.contact.email_addr}`}>
              <span className="cm-icon">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><path d="M22 6l-10 7L2 6"/></svg>
              </span>
              <span className="cm-label">{t.contact.email}</span>
              <span className="cm-value">{t.contact.email_addr}</span>
            </a>
          </div>
        </div>
        <form className="contact-form" onSubmit={(e) => { e.preventDefault(); setSent(true); }}>
          <h3>{labelLeave}</h3>
          <label><span>{labelName}</span><input type="text" required /></label>
          <label><span>{labelPhone}</span><input type="tel" required /></label>
          <label><span>{labelMsg}</span><textarea rows="4"></textarea></label>
          <button type="submit" className="form-submit">{sent ? labelSent : labelSend}</button>
        </form>
      </div>
    </div>
  );
}

Object.assign(window, {
  useHashRoute, useLanguage, LangToggle, FAQ, FAQItem,
  useArticles, useArticle, useCategories, useTags,
  formatArticleDate, isAutoTranslated, mediaUrl,
  LexicalRender, ArticleCard, ArticlePage,
  BlogPage, AboutPage, ServicesPage, ContactPage,
  YouTubeEmbed,
});
