// components-drawer.jsx — Checkout Drawer with 6 states (INITIAL/LOADING/WAITING/SUCCESS/EXPIRED/ERROR)
// Reads from window.checkoutStore (vanilla JS store) and dispatches actions.

const STORE = () => window.checkoutStore;

function useCheckoutStore() {
  const [state, setState] = React.useState(() => STORE().get());
  React.useEffect(() => {
    const unsub = STORE().subscribe(setState);
    return unsub;
  }, []);
  return state;
}

// ── Pix pending banner (top of LP) ──────────────────────
function PixPendingBanner({ onResume }) {
  const [tx, setTx] = React.useState(() => STORE().loadPersist());
  const [now, setNow] = React.useState(Date.now());

  React.useEffect(() => {
    const id = setInterval(() => {
      const persisted = STORE().loadPersist();
      if (!persisted) {
        setTx(null);
        return;
      }
      setTx(persisted);
      setNow(Date.now());
    }, 1000);
    return () => clearInterval(id);
  }, []);

  // also re-read when store changes (e.g. after submit / clearPersist)
  const storeState = useCheckoutStore();
  React.useEffect(() => {
    setTx(STORE().loadPersist());
  }, [storeState.phase, storeState.transactionId]);

  if (!tx) return null;
  const ms = Math.max(0, tx.expiresAt - now);
  if (ms <= 0) return null;
  const m = Math.floor(ms / 60000);
  const s = Math.floor((ms % 60000) / 1000);
  const pad = (n) => String(n).padStart(2, '0');

  return (
    <div className="pix-banner" role="status">
      <div className="pix-banner__txt">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
          <circle cx="12" cy="12" r="10"/>
          <path d="M12 6v6l4 2"/>
        </svg>
        <span>Você tem um PIX pendente — expira em {pad(m)}:{pad(s)}</span>
      </div>
      <button className="pix-banner__btn" onClick={onResume}>
        Continuar pagamento →
      </button>
    </div>
  );
}

// ── Drawer ──────────────────────────────────────────────
function Drawer() {
  const s = useCheckoutStore();
  const drawerRef = React.useRef(null);
  const closeBtnRef = React.useRef(null);
  const emailInputRef = React.useRef(null);
  const bodyRef = React.useRef(null);

  // Reset body scroll to top on open or phase change
  React.useEffect(() => {
    if (s.open && bodyRef.current) {
      bodyRef.current.scrollTop = 0;
    }
  }, [s.open, s.phase]);

  // When drawer opens, scroll the page so the drawer's top is visible in viewport
  React.useEffect(() => {
    if (!s.open) return;
    const id = requestAnimationFrame(() => {
      if (!drawerRef.current) return;
      const rect = drawerRef.current.getBoundingClientRect();
      const targetY = window.scrollY + rect.top - 16; // 16px breathing room
      window.scrollTo({ top: Math.max(0, targetY), behavior: 'smooth' });
    });
    return () => cancelAnimationFrame(id);
  }, [s.open]);

  // ESC to close
  React.useEffect(() => {
    if (!s.open) return;
    const onKey = (e) => {
      if (e.key === 'Escape') STORE().close();
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [s.open]);

  // Focus trap
  React.useEffect(() => {
    if (!s.open || !drawerRef.current) return;
    const t = setTimeout(() => {
      // Initial focus: email input if present, else close btn
      const target = emailInputRef.current || closeBtnRef.current;
      if (target && target.focus) target.focus();
    }, 100);
    const handler = (e) => {
      if (e.key !== 'Tab' || !drawerRef.current) return;
      const focusables = drawerRef.current.querySelectorAll(
        'a[href], button:not([disabled]), textarea, input:not([disabled]), select, [tabindex]:not([tabindex="-1"])'
      );
      if (!focusables.length) return;
      const first = focusables[0];
      const last = focusables[focusables.length - 1];
      if (e.shiftKey && document.activeElement === first) {
        e.preventDefault(); last.focus();
      } else if (!e.shiftKey && document.activeElement === last) {
        e.preventDefault(); first.focus();
      }
    };
    document.addEventListener('keydown', handler);
    return () => { clearTimeout(t); document.removeEventListener('keydown', handler); };
  }, [s.open, s.phase]);

  // Swipe down to close (mobile)
  React.useEffect(() => {
    if (!s.open || !drawerRef.current) return;
    const el = drawerRef.current;
    let startY = null;
    const onStart = (e) => {
      const handleEl = el.querySelector('.drawer__handle');
      if (!handleEl) { startY = null; return; }
      const r = handleEl.getBoundingClientRect();
      if (e.touches[0].clientY > r.bottom + 20) { startY = null; return; }
      startY = e.touches[0].clientY;
    };
    const onEnd = (e) => {
      if (startY === null) return;
      const dy = e.changedTouches[0].clientY - startY;
      if (dy > 80 && el.scrollTop <= 0) STORE().close();
      startY = null;
    };
    el.addEventListener('touchstart', onStart, { passive: true });
    el.addEventListener('touchend', onEnd, { passive: true });
    return () => {
      el.removeEventListener('touchstart', onStart);
      el.removeEventListener('touchend', onEnd);
    };
  }, [s.open]);

  return (
    <>
      <div
        className="drawer-backdrop"
        data-open={s.open ? '1' : '0'}
        onClick={() => {
          if (window.matchMedia('(min-width: 600px)').matches) STORE().close();
        }}
        aria-hidden={!s.open}
      />
      <div
        className="drawer"
        data-open={s.open ? '1' : '0'}
        role="dialog"
        aria-modal="true"
        aria-labelledby="drawer-title"
        aria-hidden={!s.open}
        ref={drawerRef}
      >
        <div className="drawer__top">
          <div className="drawer__handle" aria-hidden />
          <button
            className="drawer__close"
            ref={closeBtnRef}
            onClick={() => STORE().close()}
            aria-label="Fechar checkout"
          >
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
              <path d="M18 6L6 18M6 6l12 12"/>
            </svg>
          </button>
          <h2 id="drawer-title" style={{ position: 'absolute', left: -9999 }}>Checkout</h2>
        </div>
        <div className="drawer__body" ref={bodyRef}>
          {s.phase === 'INITIAL' || s.phase === 'LOADING' ? <InitialState s={s} emailInputRef={emailInputRef} /> : null}
          {s.phase === 'WAITING' ? <WaitingState s={s} /> : null}
          {s.phase === 'SUCCESS' ? <SuccessState s={s} /> : null}
          {s.phase === 'EXPIRED' ? <ExpiredState s={s} /> : null}
          {s.phase === 'ERROR' ? <ErrorState s={s} /> : null}
        </div>
      </div>
    </>
  );
}

// ── INITIAL ─────────────────────────────────────────────
function InitialState({ s, emailInputRef }) {
  const total = STORE().calcTotal(s.plano, s.pack, s.video);
  const planPrice = s.plano === 'trimestral' ? 33.90 : 17.90;
  const setField = STORE().setField;
  const loading = s.phase === 'LOADING';
  const emailOk = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s.email);
  const canSubmit = emailOk && !s.submitting;

  return (
    <>
      <div className="benefits">
        <div className="benefits__head">
          <div className="benefits__avatar" aria-hidden />
          <div className="benefits__id">
            <div className="benefits__name">Gabriela Rosa</div>
            <div className="benefits__handle">@gaby_rosa8</div>
          </div>
        </div>
        <div className="benefits__title">Benefícios exclusivos</div>
        <ul className="benefits__list">
          <li>
            <span className="benefits__check" aria-hidden>
              <svg width="10" height="10" viewBox="0 0 12 12" fill="none">
                <path d="M2 6.5l2.5 2.5 5.5-6" stroke="#fff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </span>
            Acesso aos vídeos amadores
          </li>
          <li>
            <span className="benefits__check" aria-hidden>
              <svg width="10" height="10" viewBox="0 0 12 12" fill="none">
                <path d="M2 6.5l2.5 2.5 5.5-6" stroke="#fff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </span>
            Chat exclusivo com a Gaby
          </li>
          <li>
            <span className="benefits__check" aria-hidden>
              <svg width="10" height="10" viewBox="0 0 12 12" fill="none">
                <path d="M2 6.5l2.5 2.5 5.5-6" stroke="#fff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </span>
            Cancele a qualquer hora
          </li>
        </ul>
      </div>

      <div className="switcher" role="tablist" aria-label="Plano" style={{ marginTop: 16 }}>
        <button
          role="tab"
          aria-selected={s.plano === 'mensal'}
          data-active={s.plano === 'mensal' ? '1' : '0'}
          onClick={() => setField({ plano: 'mensal' })}
          disabled={loading}
        >
          Mensal
        </button>
        <button
          role="tab"
          aria-selected={s.plano === 'trimestral'}
          data-active={s.plano === 'trimestral' ? '1' : '0'}
          onClick={() => setField({ plano: 'trimestral' })}
          disabled={loading}
        >
          Trimestral
        </button>
      </div>

      <div className="summary">
        <p className="summary__head">Resumo do pedido</p>
        <div className="summary__row">
          <span>{s.plano === 'trimestral' ? 'Assinatura Trimestral' : 'Assinatura Mensal'}</span>
          <span>{formatBRL(planPrice)}</span>
        </div>

        <div
          className="summary__bump summary__row"
          data-on={s.pack ? '1' : '0'}
          onClick={() => !loading && setField({ pack: !s.pack })}
          role="checkbox"
          aria-checked={s.pack}
          tabIndex={loading ? -1 : 0}
          onKeyDown={(e) => { if ((e.key === ' ' || e.key === 'Enter') && !loading) { e.preventDefault(); setField({ pack: !s.pack }); } }}
        >
          <span className="summary__bump" style={{ flex: 1, padding: 0 }}>
            <span className="summary__check">
              <svg width="11" height="11" viewBox="0 0 12 12" fill="none" aria-hidden>
                <path d="M2 6.5l2.5 2.5 5.5-6" stroke="#fff" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </span>
            <span className="summary__lbl">Pack de Fotos exclusivas</span>
          </span>
          <span style={{ fontSize: 13 }}>+{formatBRL(9.90)}</span>
        </div>

        <div
          className="summary__bump summary__row"
          data-on={s.video ? '1' : '0'}
          onClick={() => !loading && setField({ video: !s.video })}
          role="checkbox"
          aria-checked={s.video}
          tabIndex={loading ? -1 : 0}
          onKeyDown={(e) => { if ((e.key === ' ' || e.key === 'Enter') && !loading) { e.preventDefault(); setField({ video: !s.video }); } }}
        >
          <span className="summary__bump" style={{ flex: 1, padding: 0 }}>
            <span className="summary__check">
              <svg width="11" height="11" viewBox="0 0 12 12" fill="none" aria-hidden>
                <path d="M2 6.5l2.5 2.5 5.5-6" stroke="#fff" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </span>
            <span className="summary__lbl">Videochamada privada com a Gaby</span>
          </span>
          <span style={{ fontSize: 13 }}>+{formatBRL(50.00)}</span>
        </div>

        <div className="summary__sep" />
        <div className="summary__total">
          <span className="summary__total-lbl">Total</span>
          <span className="summary__total-val">{formatBRL(total)}</span>
        </div>
      </div>

      <div className="field">
        <label htmlFor="ck-email">Seu melhor email</label>
        <input
          id="ck-email"
          ref={emailInputRef}
          type="email"
          inputMode="email"
          autoComplete="email"
          placeholder="voce@email.com"
          aria-required="true"
          aria-invalid={!!s.emailErr}
          value={s.email}
          disabled={loading}
          onChange={(e) => setField({ email: e.target.value, emailErr: '' })}
          onBlur={() => {
            if (s.email && !emailOk) setField({ emailErr: 'Email inválido' });
          }}
        />
        {s.emailErr ? (
          <span className="field__err" role="alert">{s.emailErr}</span>
        ) : (
          <span className="field__hint">Usamos seu email apenas para enviar o acesso.</span>
        )}
      </div>

      <button
        className="btn btn--primary btn--full"
        style={{ marginTop: 16, opacity: canSubmit ? 1 : 0.5, pointerEvents: canSubmit ? 'auto' : 'none' }}
        onClick={() => STORE().submit()}
        disabled={!canSubmit}
        aria-disabled={!canSubmit}
      >
        {loading ? (
          <>
            <span className="spinner" /> Gerando PIX...
          </>
        ) : (
          <>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
              <rect x="4" y="11" width="16" height="10" rx="2"/>
              <path d="M8 11V7a4 4 0 018 0v4"/>
            </svg>
            Pagar com PIX · {formatBRL(total)}
          </>
        )}
      </button>

      <div className="trust">
        <div className="trust__item">
          <span className="trust__icon">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
              <rect x="4" y="11" width="16" height="10" rx="2"/>
              <path d="M8 11V7a4 4 0 018 0v4"/>
            </svg>
          </span>
          <span>Pagamento<br/>seguro</span>
        </div>
        <div className="trust__item">
          <span className="trust__icon">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
              <path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z"/>
              <circle cx="12" cy="12" r="3"/>
              <path d="M3 3l18 18"/>
            </svg>
          </span>
          <span>Cobrança<br/>discreta</span>
        </div>
        <div className="trust__item">
          <span className="trust__icon">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
              <path d="M13 2L3 14h7l-1 8 10-12h-7l1-8z"/>
            </svg>
          </span>
          <span>Acesso<br/>instantâneo</span>
        </div>
      </div>
    </>
  );
}

// ── WAITING ─────────────────────────────────────────────
function WaitingState({ s }) {
  const [now, setNow] = React.useState(Date.now());
  const [copied, setCopied] = React.useState(false);
  const [qrUrl, setQrUrl] = React.useState('');

  React.useEffect(() => {
    const id = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(id);
  }, []);

  // B2 + B8: Generate QR code as data URL via QRious library
  React.useEffect(() => {
    if (!s.paymentCode || !window.QRious) { setQrUrl(''); return; }
    try {
      const qr = new window.QRious({ value: s.paymentCode, size: 200, level: 'L' });
      setQrUrl(qr.toDataURL('image/png'));
    } catch (e) {
      console.error('QR gen failed:', e);
      setQrUrl('');
    }
  }, [s.paymentCode]);

  const ms = Math.max(0, (s.expiresAt || 0) - now);
  const m = Math.floor(ms / 60000);
  const sec = Math.floor((ms % 60000) / 1000);
  const pad = (n) => String(n).padStart(2, '0');

  const copy = async () => {
    try {
      await navigator.clipboard.writeText(s.paymentCode || '');
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch (e) {
      // fallback
      const ta = document.createElement('textarea');
      ta.value = s.paymentCode || '';
      document.body.appendChild(ta);
      ta.select();
      try { document.execCommand('copy'); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch (er) {}
      document.body.removeChild(ta);
    }
  };

  return (
    <div className="pix">
      <div className="pix__status">
        <span className="pix__dot" aria-hidden />
        Aguardando pagamento...
      </div>
      <div className="pix__qr">
        {qrUrl ? <img src={qrUrl} alt="QR Code para pagamento PIX" width="200" height="200" style={{ display: 'block' }} /> : null}
      </div>
      <p className="pix__hint">Escaneie com o app do seu banco</p>
      <div className="pix__or"><span>ou</span></div>
      <div className="pix__copy">
        <div className="pix__cc" title={s.paymentCode}>{s.paymentCode}</div>
        <button className="pix__copybtn pix__copybtn--cta" data-copied={copied ? '1' : '0'} onClick={copy}>
          {copied ? '✓ Chave copiada' : 'Copiar chave Pix'}
        </button>
      </div>
      <p className="pix__timer">Expira em <strong style={{ color: '#fff' }}>{pad(m)}:{pad(sec)}</strong></p>
      <p className="pix__micro">Esta tela atualizará sozinha após o pagamento.</p>
    </div>
  );
}

// ── SUCCESS ─────────────────────────────────────────────
function SuccessState({ s }) {
  const safeAccessUrl = (typeof s.accessUrl === 'string' && s.accessUrl.startsWith('https://t.me/'))
    ? s.accessUrl : '#';
  return (
    <div className="success">
      <div className="success__icon" aria-hidden>
        <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
          <path d="M5 12.5l5 5L20 6.5"/>
        </svg>
      </div>
      <h3 className="success__head">Pagamento confirmado!</h3>
      <p className="success__sub">Seu acesso foi liberado.</p>
      <a
        href={safeAccessUrl}
        className="btn btn--primary btn--full"
        target="_blank"
        rel="noopener noreferrer"
        style={{ textDecoration: 'none' }}
      >
        Acessar conteúdo agora →
      </a>
      <p className="success__micro">Também enviamos o link para seu email.</p>
    </div>
  );
}

// ── EXPIRED ─────────────────────────────────────────────
function ExpiredState({ s }) {
  return (
    <div className="expired">
      <div style={{
        width: 56, height: 56, borderRadius: '50%',
        background: 'rgba(255,64,64,0.1)',
        border: '1px solid rgba(255,64,64,0.3)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        marginBottom: 16,
      }}>
        <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#FF6060" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
          <circle cx="12" cy="12" r="10"/>
          <path d="M12 6v6l4 2"/>
        </svg>
      </div>
      <h3 className="expired__head">Código expirado</h3>
      <p className="expired__sub">O tempo limite para pagamento foi atingido.</p>
      <button className="btn btn--primary btn--full" onClick={() => STORE().regeneratePix()}>
        Gerar novo PIX
      </button>
    </div>
  );
}

// ── ERROR ───────────────────────────────────────────────
function ErrorState({ s }) {
  const is400 = Array.isArray(s.errorFields) && s.errorFields.length > 0;
  return (
    <div style={{ paddingTop: 8 }}>
      <div className="alert" role="alert">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
          <circle cx="12" cy="12" r="10"/>
          <path d="M12 8v4M12 16h.01"/>
        </svg>
        {s.error || 'Algo deu errado.'}
        {is400 && (
          <ul style={{margin:'8px 0 0', paddingLeft:18, fontSize:13}}>
            {s.errorFields.map((f) => <li key={f}>{f}</li>)}
          </ul>
        )}
      </div>
      <button
        className="btn btn--primary btn--full"
        onClick={() => {
          if (is400) STORE().setField({ phase: 'INITIAL', error: '', errorFields: null });
          else if (s.email) STORE().submit();
          else STORE().setField({ phase: 'INITIAL', error: '' });
        }}
      >
        {is400 ? 'Corrigir' : 'Tentar novamente'}
      </button>
    </div>
  );
}

Object.assign(window, { Drawer, PixPendingBanner });
