// Main app — interactive layer over the static HTML
// Handles: prayer modal, request form, commitment counter, tweaks panel, scroll reveals
const { useState, useEffect, useRef } = React;

function t(key) { return (window.I18N && window.I18N.t(key)) || key; }
function useLang() {
  const [lang, setLangState] = useState(() => (window.I18N ? window.I18N.getLang() : 'pt'));
  useEffect(() => {
    const h = (e) => setLangState(e.detail.lang);
    window.addEventListener('langchange', h);
    return () => window.removeEventListener('langchange', h);
  }, []);
  return lang;
}

const MYSTERY_IDS = ['joyful', 'sorrowful', 'glorious', 'luminous'];

// ─── Tweaks defaults ─────────────────────────────────────────────
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": ["#3A6CA2","#FFFFFF","#2F6099","#E6C57C"],
  "fontSize": 19,
  "showCandles": true,
  "particleIntensity": "soft"
}/*EDITMODE-END*/;

// ─── Prayer modal ────────────────────────────────────────────────
function PrayerModal({ open, onClose }) {
  const lang = useLang();
  const [currentPrayer, setCurrentPrayer] = useState('hail-mary');
  const [currentMystery, setCurrentMystery] = useState(0);

  if (!open) return null;

  const prayerTitle = t('prayer.' + currentPrayer + '.title');
  const prayerBody = t('prayer.' + currentPrayer + '.body');
  const mysteryId = MYSTERY_IDS[currentMystery];
  const mysteryName = t('mystery.' + mysteryId + '.name');
  const mysteryDay = t('mystery.' + mysteryId + '.day');
  const mysteryList = t('mystery.' + mysteryId + '.list');

  function handlePrayerClick(prayerKey, label) {
    setCurrentPrayer(prayerKey);
  }

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: '900px' }}>
        <button className="modal-close" onClick={onClose}>{t('modal.close')}</button>
        <div className="eyebrow" style={{ display: 'block', textAlign: 'center', marginBottom: 12 }}>{t('modal.eyebrow')}</div>
        <h3 style={{ marginBottom: 8 }}>{t('modal.title')}</h3>
        <p style={{ textAlign: 'center', color: 'var(--ink-dark-soft)', fontStyle: 'italic', marginBottom: 32 }}>
          {t('modal.subtitle')}
        </p>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 40, alignItems: 'start' }}>
          <div>
            <window.InteractiveRosary onPrayerClick={handlePrayerClick} />
          </div>
          <div style={{ paddingTop: 20 }}>
            <div className="eyebrow left-only" style={{ marginBottom: 10 }}>{t('modal.prayer.label')}</div>
            <h4 style={{ fontFamily: 'var(--serif-display)', fontStyle: 'italic', fontSize: '1.6rem', marginBottom: 14, color: 'var(--marian)' }}>
              {prayerTitle}
            </h4>
            <p className="modal-prayer" style={{ textAlign: 'left', margin: 0 }}>{prayerBody}</p>

            <div className="ornament"><span className="line"></span><span className="diamond"></span><span className="line"></span></div>

            <div className="eyebrow left-only" style={{ marginBottom: 14 }}>{t('modal.mysteries.label')}</div>
            <div className="modal-mysteries">
              {MYSTERY_IDS.map((id, i) => (
                <button key={id}
                  className={'modal-mystery' + (currentMystery === i ? ' active' : '')}
                  onClick={() => setCurrentMystery(i)}>
                  {t('mystery.' + id + '.name')}
                </button>
              ))}
            </div>
            <p style={{ color: 'var(--ink-dark-soft)', marginTop: 12, fontFamily: 'var(--cap)', letterSpacing: '0.2em', textTransform: 'uppercase', fontSize: '10px' }}>
              {mysteryDay}
            </p>
            <ol style={{ paddingLeft: 20, margin: '14px 0 0', color: 'var(--ink-dark-soft)' }}>
              {mysteryList.map((item, i) => (
                <li key={i} style={{ marginBottom: 6, fontStyle: 'italic' }}>{item}</li>
              ))}
            </ol>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── Commitment counter ─────────────────────────────────────────
function CommitmentCounter() {
  useLang();
  // Real-feel counter: starts at a number, increments on commit
  const STORAGE_KEY = 'apostolado_commit_v1';
  const COUNT_KEY = 'apostolado_count_v1';
  const initialCount = 12473;

  const [count, setCount] = useState(() => {
    const stored = parseInt(localStorage.getItem(COUNT_KEY) || '');
    return isNaN(stored) ? initialCount : stored;
  });
  const [committed, setCommitted] = useState(() => localStorage.getItem(STORAGE_KEY) === '1');
  const [bump, setBump] = useState(false);
  const counterRef = useRef(null);

  // Animate count from initialCount to count on mount
  useEffect(() => {
    const el = counterRef.current;
    if (!el) return;
    const target = count;
    const duration = 1800;
    const start = performance.now();
    let frame;
    function tick(t) {
      const p = Math.min(1, (t - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      const val = Math.round(target * eased);
      el.textContent = val.toLocaleString('pt-BR');
      if (p < 1) frame = requestAnimationFrame(tick);
    }
    // Only animate on first mount
    const seen = sessionStorage.getItem('counter_seen');
    if (!seen) {
      frame = requestAnimationFrame(tick);
      sessionStorage.setItem('counter_seen', '1');
    } else {
      el.textContent = target.toLocaleString('pt-BR');
    }
    return () => frame && cancelAnimationFrame(frame);
  }, []);

  useEffect(() => {
    if (counterRef.current && sessionStorage.getItem('counter_seen')) {
      counterRef.current.textContent = count.toLocaleString('pt-BR');
    }
  }, [count]);

  function handleCommit() {
    if (committed) return;
    setCommitted(true);
    localStorage.setItem(STORAGE_KEY, '1');
    const next = count + 1;
    setCount(next);
    localStorage.setItem(COUNT_KEY, String(next));
    setBump(true);
    setTimeout(() => setBump(false), 600);
  }

  return (
    <>
      <div ref={counterRef} className={'counter' + (bump ? ' bump' : '')}>
        {initialCount.toLocaleString('pt-BR')}
      </div>
      <div className="counter-label">{t('crusade.counter.label')}</div>
      <button onClick={handleCommit} className={'btn commit-btn' + (committed ? ' committed' : '')}>
        {committed ? t('crusade.btn.done') : t('crusade.btn')}
      </button>
      {committed && (
        <p style={{ marginTop: 24, fontStyle: 'italic', color: 'var(--ink-soft)', maxWidth: 480, marginLeft: 'auto', marginRight: 'auto' }}>
          {t('crusade.thanks')} <br />
          <span style={{ fontFamily: 'var(--cap)', fontSize: 10, letterSpacing: '0.25em' }}>{t('crusade.thanks2')}</span>
        </p>
      )}
    </>
  );
}

// ─── Prayer request form ────────────────────────────────────────
function PrayerRequestForm() {
  useLang();
  const [submitted, setSubmitted] = useState(false);
  const [data, setData] = useState({ name: '', city: '', intention: '' });

  function submit(e) {
    e.preventDefault();
    if (!data.name || !data.intention) return;
    // Persist locally
    const all = JSON.parse(localStorage.getItem('prayer_requests') || '[]');
    all.push({ ...data, at: Date.now() });
    localStorage.setItem('prayer_requests', JSON.stringify(all));
    setSubmitted(true);
  }

  if (submitted) {
    return (
      <div className="request-success" dangerouslySetInnerHTML={{ __html: t('request.success') }} />
    );
  }

  return (
    <form className="request-form" onSubmit={submit}>
      <div className="field">
        <label>{t('request.name')}</label>
        <input type="text" value={data.name} onChange={(e) => setData({...data, name: e.target.value})} required />
      </div>
      <div className="field">
        <label>{t('request.city')}</label>
        <input type="text" value={data.city} onChange={(e) => setData({...data, city: e.target.value})} />
      </div>
      <div className="field">
        <label>{t('request.intention')}</label>
        <textarea value={data.intention} onChange={(e) => setData({...data, intention: e.target.value})} required rows="4" />
      </div>
      <button type="submit" className="btn request-submit">{t('request.submit')}</button>
    </form>
  );
}

// ─── Candle component ───────────────────────────────────────────
function VirtualCandle() {
  useLang();
  const [lit, setLit] = useState(() => localStorage.getItem('candle_lit') === '1');
  const [intention, setIntention] = useState(() => localStorage.getItem('candle_intention') || '');
  const [showInput, setShowInput] = useState(!lit);
  const [draft, setDraft] = useState('');

  function light() {
    if (!draft.trim()) return;
    setLit(true);
    setIntention(draft);
    setShowInput(false);
    localStorage.setItem('candle_lit', '1');
    localStorage.setItem('candle_intention', draft);
  }

  function relight() {
    setLit(false);
    setIntention('');
    setDraft('');
    setShowInput(true);
    localStorage.removeItem('candle_lit');
    localStorage.removeItem('candle_intention');
  }

  return (
    <div style={{ textAlign: 'center' }}>
      <svg viewBox="0 0 120 200" width="140" height="220" style={{ margin: '0 auto', display: 'block' }}>
        <defs>
          <radialGradient id="flame-grad" cx="50%" cy="60%">
            <stop offset="0%" stopColor="#fff5d6" />
            <stop offset="35%" stopColor="#FFC857" />
            <stop offset="70%" stopColor="#D9B870" stopOpacity="0.8" />
            <stop offset="100%" stopColor="#B8893E" stopOpacity="0" />
          </radialGradient>
          <radialGradient id="candle-glow">
            <stop offset="0%" stopColor="rgba(255, 200, 87, 0.6)" />
            <stop offset="100%" stopColor="rgba(255, 200, 87, 0)" />
          </radialGradient>
        </defs>
        {/* glow when lit */}
        {lit && <circle cx="60" cy="60" r="55" fill="url(#candle-glow)">
          <animate attributeName="r" values="50;65;50" dur="3s" repeatCount="indefinite" />
        </circle>}
        {/* candle body */}
        <rect x="48" y="90" width="24" height="95" fill="#F4ECDC" stroke="#8C6628" strokeWidth="0.5" />
        <rect x="48" y="90" width="24" height="6" fill="#D9B870" opacity="0.4" />
        {/* wick */}
        <line x1="60" y1="90" x2="60" y2="80" stroke="#1F1A12" strokeWidth="1.5" />
        {/* flame */}
        {lit && (
          <g>
            <ellipse cx="60" cy="65" rx="10" ry="18" fill="url(#flame-grad)">
              <animate attributeName="ry" values="18;20;17;19;18" dur="1.6s" repeatCount="indefinite" />
              <animate attributeName="cy" values="65;63;66;64;65" dur="1.6s" repeatCount="indefinite" />
            </ellipse>
            <ellipse cx="60" cy="68" rx="4" ry="9" fill="#FFC857">
              <animate attributeName="ry" values="9;11;8;10;9" dur="1.4s" repeatCount="indefinite" />
            </ellipse>
          </g>
        )}
        {/* base */}
        <ellipse cx="60" cy="185" rx="14" ry="3" fill="#8C6628" opacity="0.3" />
      </svg>

      {showInput && (
        <div style={{ marginTop: 16 }}>
          <input
            type="text"
            value={draft}
            placeholder={t('candle.placeholder')}
            onChange={(e) => setDraft(e.target.value)}
            style={{
              width: 280, maxWidth: '90%', padding: '12px 16px',
              background: 'transparent', border: 0,
              borderBottom: '1px solid var(--gold)',
              color: 'var(--ink)', fontFamily: 'var(--serif-body)',
              fontSize: '1rem', fontStyle: 'italic', textAlign: 'center',
              outline: 'none'
            }}
          />
          <br />
          <button onClick={light} className="btn btn-gold" style={{ marginTop: 18 }}>
            {t('candle.light')}
          </button>
        </div>
      )}

      {!showInput && lit && (
        <div style={{ marginTop: 20, fontStyle: 'italic', color: 'var(--ink-soft)', maxWidth: 360, margin: '20px auto 0' }}>
          <p style={{ marginBottom: 8 }}>“{intention}”</p>
          <p style={{ fontFamily: 'var(--cap)', fontSize: 9, letterSpacing: '0.26em', color: 'var(--gold-light)', textTransform: 'uppercase' }}>
            {t('candle.burning')}
          </p>
          <button onClick={relight} className="btn btn-outline" style={{ marginTop: 22, fontSize: 10, padding: '12px 24px' }}>
            {t('candle.relight')}
          </button>
        </div>
      )}
    </div>
  );
}

// ─── Cruzada Mundial: formulário + mapa ─────────────────────────
const CRUSADE_GOAL = 1000000;
const CRUSADE_PINS_KEY = 'apostolado_crusade_pins_v1';

function loadPins() {
  try {
    const stored = JSON.parse(localStorage.getItem(CRUSADE_PINS_KEY) || 'null');
    if (Array.isArray(stored)) return stored;
  } catch (e) {}
  return [];
}

function CrusadeFormModal({ open, onClose, onSubmitted }) {
  useLang();
  const [name, setName] = useState('');
  const [city, setCity] = useState('');
  const [country, setCountry] = useState('');
  const [countryAuto, setCountryAuto] = useState(true);
  const [coords, setCoords] = useState(null);

  useEffect(() => {
    if (!city.trim()) { setCountry(''); setCoords(null); return; }
    const hit = window.guessCityCountry && window.guessCityCountry(city);
    if (hit) {
      const lang = window.I18N ? window.I18N.getLang() : 'pt';
      setCountry(hit.country[lang] || hit.country.pt);
      setCoords({ lat: hit.lat, lng: hit.lng });
      setCountryAuto(true);
    } else {
      setCoords(null);
      if (countryAuto) setCountry('');
    }
  }, [city]);

  if (!open) return null;

  function submit(e) {
    e.preventDefault();
    if (!name.trim() || !city.trim()) return;

    // Só adicionamos um pino ao mapa quando temos coordenadas reais da cidade —
    // nunca um ponto fictício/aleatório.
    if (coords) {
      const pins = loadPins();
      const next = [...pins, { city: city.trim(), lat: coords.lat, lng: coords.lng, isNew: true }];
      localStorage.setItem(CRUSADE_PINS_KEY, JSON.stringify(next));
      var updatedPins = next;
    } else {
      var updatedPins = loadPins();
    }

    const COUNT_KEY = 'apostolado_count_v1';
    const cur = parseInt(localStorage.getItem(COUNT_KEY) || '12473', 10);
    localStorage.setItem(COUNT_KEY, String(cur + 1));
    localStorage.setItem('apostolado_commit_v1', '1');

    onSubmitted(updatedPins, cur + 1);
  }

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: '520px' }}>
        <button className="modal-close" onClick={onClose}>{t('modal.close')}</button>
        <div className="eyebrow" style={{ display: 'block', textAlign: 'center', marginBottom: 12 }}>{t('crusade.eyebrow')}</div>
        <h3 style={{ marginBottom: 24 }}>{t('crusade.form.title')}</h3>

        <form className="crusade-form" onSubmit={submit}>
          <div className="field">
            <label>{t('crusade.form.name')}</label>
            <input type="text" value={name} onChange={(e) => setName(e.target.value)} required />
          </div>
          <div className="field">
            <label>{t('crusade.form.city')}</label>
            <input type="text" value={city} onChange={(e) => setCity(e.target.value)} required />
          </div>
          {country && (
            <p className="crusade-country-hint" dangerouslySetInnerHTML={{
              __html: t('crusade.form.country_detected').replace('{country}', '<strong>' + country + '</strong>')
            }} />
          )}
          {!country && city.trim() && (
            <div className="field">
              <label>{t('crusade.form.country')}</label>
              <input type="text" value={country} onChange={(e) => { setCountry(e.target.value); setCountryAuto(false); }} />
            </div>
          )}
          <button type="submit" className="btn btn-gold" style={{ marginTop: 8 }}>{t('crusade.form.submit')}</button>
        </form>
      </div>
    </div>
  );
}

function CrusadeSection() {
  useLang();
  const STORAGE_KEY = 'apostolado_commit_v1';
  const COUNT_KEY = 'apostolado_count_v1';
  const initialCount = 12473;

  const [count, setCount] = useState(() => {
    const stored = parseInt(localStorage.getItem(COUNT_KEY) || '', 10);
    return isNaN(stored) ? initialCount : stored;
  });
  const [committed, setCommitted] = useState(() => localStorage.getItem(STORAGE_KEY) === '1');
  const [pins, setPins] = useState(() => loadPins());
  const [modalOpen, setModalOpen] = useState(false);
  const counterRef = useRef(null);

  useEffect(() => {
    const el = counterRef.current;
    if (!el) return;
    const target = count;
    const duration = 1800;
    const start = performance.now();
    let frame;
    function tick(tt) {
      const p = Math.min(1, (tt - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      const val = Math.round(target * eased);
      el.textContent = val.toLocaleString();
      if (p < 1) frame = requestAnimationFrame(tick);
    }
    const seen = sessionStorage.getItem('crusade_counter_seen');
    if (!seen) {
      frame = requestAnimationFrame(tick);
      sessionStorage.setItem('crusade_counter_seen', '1');
    } else {
      el.textContent = target.toLocaleString();
    }
    return () => frame && cancelAnimationFrame(frame);
  }, []);

  useEffect(() => {
    if (counterRef.current && sessionStorage.getItem('crusade_counter_seen')) {
      counterRef.current.textContent = count.toLocaleString();
    }
  }, [count]);

  function handleSubmitted(newPins, newCount) {
    setPins(newPins);
    setCount(newCount);
    setCommitted(true);
    setModalOpen(false);
  }

  const pct = Math.min(100, (count / CRUSADE_GOAL) * 100);

  return (
    <>
      <div ref={counterRef} className="counter">{initialCount.toLocaleString()}</div>
      <div className="counter-label">{t('crusade.counter.label')}</div>
      <div className="crusade-progress-track">
        <div className="crusade-progress-fill" style={{ width: pct + '%' }}></div>
      </div>
      <div className="crusade-progress-label">
        {count.toLocaleString()} / {CRUSADE_GOAL.toLocaleString()} — {t('crusade.goal.label')}
      </div>

      <div className="crusade-cta-row">
        <button
          onClick={() => committed ? null : setModalOpen(true)}
          className={'btn commit-btn' + (committed ? ' committed' : '')}
        >
          {committed ? t('crusade.btn.done') : t('crusade.btn2')}
        </button>
      </div>

      {committed && (
        <p style={{ marginTop: 24, fontStyle: 'italic', color: 'var(--ink-soft)', maxWidth: 480, marginLeft: 'auto', marginRight: 'auto' }}>
          {t('crusade.thanks')} <br />
          <span style={{ fontFamily: 'var(--cap)', fontSize: 10, letterSpacing: '0.25em' }}>{t('crusade.thanks2')}</span>
        </p>
      )}
      {committed && (
        <button
          onClick={() => { localStorage.removeItem(STORAGE_KEY); setCommitted(false); }}
          className="crusade-reset-link"
        >
          {t('crusade.reset')}
        </button>
      )}

      <window.WorldMap pins={pins} />
      <p className="worldmap-note">{t('crusade.map.note')}</p>

      <CrusadeFormModal open={modalOpen} onClose={() => setModalOpen(false)} onSubmitted={handleSubmitted} />
    </>
  );
}

// ─── Tweaks (palette + density) ────────────────────────────────
function Tweaks() {
  const [t, setTweak] = window.useTweaks(TWEAK_DEFAULTS);

  // Apply palette
  useEffect(() => {
    const [bg, ink, marian, gold] = t.palette;
    document.documentElement.style.setProperty('--bg', bg);
    document.documentElement.style.setProperty('--ink', ink);
    document.documentElement.style.setProperty('--marian', marian);
    document.documentElement.style.setProperty('--gold', gold);
    document.documentElement.style.setProperty('font-size', t.fontSize + 'px');
  }, [t.palette, t.fontSize]);

  // Particle visibility
  useEffect(() => {
    const c = document.getElementById('particle-canvas');
    if (!c) return;
    if (t.particleIntensity === 'off') c.style.display = 'none';
    else {
      c.style.display = 'block';
      c.style.opacity = t.particleIntensity === 'rich' ? '0.8' : (t.particleIntensity === 'soft' ? '0.5' : '0.3');
    }
  }, [t.particleIntensity]);

  return (
    <window.TweaksPanel title="Tweaks">
      <window.TweakSection label="Paleta" />
      <window.TweakColor
        label="Tom do céu"
        value={t.palette}
        options={[
          ['#3A6CA2', '#FFFFFF', '#2F6099', '#E6C57C'],  // Azul-céu (oficial)
          ['#4A7CB2', '#FFFFFF', '#2F6099', '#F2DEA0'],  // Céu mais claro
          ['#2C5687', '#FFFFFF', '#2F6099', '#E6C57C'],  // Azul mais profundo
          ['#3E6E86', '#FFFFFF', '#2F6099', '#E6C57C'],  // Azul esverdeado sereno
        ]}
        onChange={(v) => setTweak('palette', v)}
      />
      <window.TweakSection label="Tipografia" />
      <window.TweakSlider label="Tamanho do texto" value={t.fontSize} min={16} max={22} step={1} unit="px"
        onChange={(v) => setTweak('fontSize', v)} />
      <window.TweakSection label="Atmosfera" />
      <window.TweakRadio
        label="Partículas"
        value={t.particleIntensity}
        options={['off', 'soft', 'rich']}
        onChange={(v) => setTweak('particleIntensity', v)}
      />
    </window.TweaksPanel>
  );
}

// ─── Main App ──────────────────────────────────────────────────
function App() {
  const [prayerModalOpen, setPrayerModalOpen] = useState(false);

  // Expose modal open for static HTML buttons
  useEffect(() => {
    window.__openPrayerModal = () => setPrayerModalOpen(true);
  }, []);

  // Scroll reveal
  useEffect(() => {
    const els = document.querySelectorAll('.reveal');
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          e.target.classList.add('in');
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, []);

  // Toggle dos nichos (mobile / toque)
  useEffect(() => {
    const niches = document.querySelectorAll('.dim-niche');
    const handlers = [];
    niches.forEach((n) => {
      const h = () => {
        const wasActive = n.classList.contains('active');
        niches.forEach((m) => m.classList.remove('active'));
        if (!wasActive) n.classList.add('active');
      };
      n.addEventListener('click', h);
      handlers.push([n, h]);
    });
    return () => handlers.forEach(([n, h]) => n.removeEventListener('click', h));
  }, []);

  // Nav scroll state
  useEffect(() => {
    const nav = document.querySelector('.nav');
    if (!nav) return;
    const handler = () => {
      if (window.scrollY > 40) nav.classList.add('scrolled');
      else nav.classList.remove('scrolled');
    };
    handler();
    window.addEventListener('scroll', handler, { passive: true });
    return () => window.removeEventListener('scroll', handler);
  }, []);

  return (
    <>
      <PrayerModal open={prayerModalOpen} onClose={() => setPrayerModalOpen(false)} />
      <Tweaks />
    </>
  );
}

// ─── Render mountpoints ────────────────────────────────────────
function mount(id, comp) {
  const el = document.getElementById(id);
  if (el) ReactDOM.createRoot(el).render(comp);
}

document.addEventListener('DOMContentLoaded', () => {
  mount('app-root', <App />);
  mount('hero-rosary-mount', <window.HeroRosary />);
  mount('counter-mount', <CrusadeSection />);
  mount('request-form-mount', <PrayerRequestForm />);
  mount('candle-mount', <VirtualCandle />);
});

// Babel scripts run AFTER DOMContentLoaded — if it already fired, mount now.
if (document.readyState !== 'loading') {
  mount('app-root', <App />);
  mount('hero-rosary-mount', <window.HeroRosary />);
  mount('counter-mount', <CrusadeSection />);
  mount('request-form-mount', <PrayerRequestForm />);
  mount('candle-mount', <VirtualCandle />);
}
