// Connect — contact form. Socials live on /links.
// Submits to Cloudflare Pages Function /contact, which verifies the
// Turnstile token and forwards via Web3Forms.

const ConnectPage = () => {
  const T = window.TOKENS;
  const [form, setForm] = React.useState({ email: '', subject: '', message: '' });
  const [status, setStatus] = React.useState('idle'); // idle | submitting | success | error
  const [errorMsg, setErrorMsg] = React.useState('');
  const [touched, setTouched] = React.useState(false);
  const [token, setToken] = React.useState('');

  const widgetHostRef = React.useRef(null);
  const widgetIdRef = React.useRef(null);

  const fieldsValid =
    /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email) &&
    form.subject.trim().length >= 2 &&
    form.message.trim().length >= 10;
  const canSubmit = fieldsValid && token && status !== 'submitting';

  const siteKey = (window.SITE_CONFIG && window.SITE_CONFIG.turnstileSiteKey) || '';

  // Render Turnstile widget once the API script has loaded. Polls briefly
  // because the script is async and may not be ready at first paint.
  React.useEffect(() => {
    let cancelled = false;
    let pollId = null;

    const tryRender = () => {
      if (cancelled) return;
      if (!window.turnstile || !widgetHostRef.current) {
        pollId = setTimeout(tryRender, 200);
        return;
      }
      widgetIdRef.current = window.turnstile.render(widgetHostRef.current, {
        sitekey: siteKey,
        theme: 'dark',
        callback: (t) => setToken(t),
        'expired-callback': () => setToken(''),
        'error-callback': () => setToken(''),
        'timeout-callback': () => setToken(''),
      });
    };
    tryRender();

    return () => {
      cancelled = true;
      if (pollId) clearTimeout(pollId);
      if (widgetIdRef.current && window.turnstile) {
        try { window.turnstile.remove(widgetIdRef.current); } catch (_) {}
      }
    };
  }, [siteKey]);

  const resetWidget = () => {
    if (widgetIdRef.current && window.turnstile) {
      try { window.turnstile.reset(widgetIdRef.current); } catch (_) {}
    }
    setToken('');
  };

  const submit = async (e) => {
    e.preventDefault();
    setTouched(true);
    if (!canSubmit) return;

    setStatus('submitting');
    setErrorMsg('');
    try {
      const res = await fetch('/contact', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        body: JSON.stringify({
          email: form.email.trim(),
          subject: form.subject.trim(),
          message: form.message.trim(),
          token,
        }),
      });
      const raw = await res.text();
      let data = {};
      try { data = JSON.parse(raw); } catch (_) { /* non-JSON response */ }
      console.log('[contact] HTTP', res.status, 'body:', raw.slice(0, 400));

      if (res.ok && data.ok) {
        setStatus('success');
        setForm({ email: '', subject: '', message: '' });
        setTouched(false);
        resetWidget();
        setTimeout(() => setStatus('idle'), 6000);
      } else {
        setStatus('error');
        const base = data.error
          ? errorLabel(data.error)
          : `unexpected response (HTTP ${res.status}). check devtools console.`;
        const detail = data.upstream_message
          ? ` upstream: ${data.upstream_message}`
          : '';
        setErrorMsg(base + detail);
        resetWidget();
        setTimeout(() => setStatus('idle'), 8000);
      }
    } catch (err) {
      console.log('[contact] fetch threw:', err);
      setStatus('error');
      setErrorMsg('network error. try again.');
      resetWidget();
      setTimeout(() => setStatus('idle'), 6000);
    }
  };

  const inputStyle = {
    width: '100%', boxSizing: 'border-box',
    padding: '12px 14px', background: T.bgSunken,
    border: `1px solid ${T.fgFaint}`, color: T.fg,
    fontFamily: T.mono, fontSize: 13, outline: 'none',
  };
  const labelStyle = {
    fontSize: 10, letterSpacing: '0.3em', color: T.fgGhost,
    textTransform: 'uppercase', marginBottom: 8, display: 'block',
  };

  return (
    <div style={{
      minHeight: '100vh', position: 'relative', zIndex: 1,
      padding: '140px 40px 160px', maxWidth: 1200, margin: '0 auto',
      fontFamily: T.mono, color: T.fg,
    }}>
      <div style={{ fontSize: 11, letterSpacing: '0.4em', color: T.accent, marginBottom: 24 }}>
        ━━ INDEX / CONNECT
      </div>

      <window.GlitchTitle lines={[{ text: 'GET IN' }, { text: 'TOUCH.', accent: true }]} />

      <div style={{ marginTop: 24, fontSize: 15, color: T.fgMid, maxWidth: 600, lineHeight: 1.6, fontFamily: T.sans }}>
        For project work, consulting, or workshops please drop a note below.
        Looking for socials?{' '}
        <span
          onClick={() => window.navigate('/links')}
          style={{ color: T.fg, cursor: 'pointer', textDecoration: 'underline', textUnderlineOffset: 3 }}
        >
          /links
        </span>
        {' '}has all of them.
      </div>

      <form
        onSubmit={submit}
        style={{
          marginTop: 56, padding: '32px 40px',
          border: `1px solid ${T.fgFaint}`, background: `${T.bgRaised}80`,
          display: 'flex', flexDirection: 'column', gap: 20,
        }}
      >
        <div style={{ fontSize: 11, letterSpacing: '0.4em', color: T.fgGhost }}>
          ━━ MESSAGE
        </div>

        <div>
          <label style={labelStyle}>your email</label>
          <input
            type="email" placeholder="you@domain.com"
            value={form.email}
            onChange={(e) => setForm(f => ({ ...f, email: e.target.value }))}
            style={inputStyle}
            disabled={status === 'submitting'}
          />
        </div>

        <div>
          <label style={labelStyle}>subject</label>
          <input
            type="text" placeholder="what's this about?"
            value={form.subject}
            onChange={(e) => setForm(f => ({ ...f, subject: e.target.value }))}
            style={inputStyle}
            disabled={status === 'submitting'}
          />
        </div>

        <div>
          <label style={labelStyle}>message</label>
          <textarea
            placeholder="say what's on your mind..."
            rows={6}
            value={form.message}
            onChange={(e) => setForm(f => ({ ...f, message: e.target.value }))}
            style={{ ...inputStyle, resize: 'vertical', minHeight: 140 }}
            disabled={status === 'submitting'}
          />
        </div>

        <div>
          <label style={labelStyle}>verify human</label>
          <div ref={widgetHostRef} />
        </div>

        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12 }}>
          <div style={{ fontSize: 11, color: T.fgDim, letterSpacing: '0.05em' }}>
            {touched && !fieldsValid && status === 'idle' && (
              <span style={{ color: T.danger }}>// fill all 3 fields, valid email</span>
            )}
            {touched && fieldsValid && !token && status === 'idle' && (
              <span style={{ color: T.danger }}>// complete the captcha</span>
            )}
            {status === 'submitting' && <span style={{ color: T.fgMid }}>// sending...</span>}
            {status === 'success' && (
              <span style={{ color: T.ok }}>✓ message sent. i'll reply from CET hours.</span>
            )}
            {status === 'error' && (
              <span style={{ color: T.danger }}>✗ {errorMsg || 'something went wrong. try again.'}</span>
            )}
          </div>
          <button
            type="submit"
            disabled={!canSubmit}
            style={{
              padding: '12px 28px', background: canSubmit ? T.accent : T.fgFaint,
              color: canSubmit ? T.bg : T.fgDim, border: 'none',
              fontFamily: T.mono, fontSize: 11, letterSpacing: '0.3em',
              textTransform: 'uppercase', fontWeight: 700,
              cursor: canSubmit ? 'pointer' : 'not-allowed',
              transition: 'background .15s',
            }}
          >
            {status === 'submitting' ? '// sending...' : status === 'success' ? '✓ sent' : '[↵] send →'}
          </button>
        </div>
      </form>

      <div style={{
        marginTop: 80, padding: 24, border: `1px dashed ${T.fgFaint}`,
        fontSize: 13, color: T.fgDim, fontFamily: T.sans, lineHeight: 1.7,
      }}>
        <span style={{ color: T.fg, fontFamily: T.mono, fontSize: 11, letterSpacing: '0.2em' }}>// LOCATION</span> Poland (CET, UTC+1).
        Working hours roughly 08:00-20:00 CET, but I read async outside that window too.
      </div>
    </div>
  );
};

const errorLabel = (code) => {
  switch (code) {
    case 'invalid_email': return 'invalid email.';
    case 'invalid_subject': return 'subject too short.';
    case 'invalid_message': return 'message too short.';
    case 'missing_captcha': return 'captcha missing.';
    case 'captcha_failed': return 'captcha failed. try again.';
    case 'server_misconfigured': return 'server not configured yet.';
    case 'send_failed': return 'send failed upstream. try again.';
    case 'invalid_body': return 'malformed request.';
    default: return 'something went wrong. try again.';
  }
};

window.ConnectPage = ConnectPage;
