/* Scholarship application — on-site form that replaces the old Google Form.
   Exports window.Pages.scholarship.

   ── EDITING THE QUESTIONS ───────────────────────────────────────────────
   The whole application lives in buildSections() below. Each cycle you can add,
   remove, or reword questions there — nothing else needs to change. A field
   looks like:
     { name: 'gpa', label: 'Cumulative GPA', type: 'text', required: true,
       width: 'half', placeholder: 'e.g. 3.8', helper: 'On a 4.0 scale' }
   type:    'text' | 'email' | 'tel' | 'date' | 'textarea' | 'select' | 'radio'
   width:   'half' (pairs up on a row) | 'full' (default, spans the row)
   options: [...] for 'select' and 'radio'
   description: ['line', 'line'] extra prompt lines shown under the label
   showIf:  (form) => boolean — only render/validate the field when true

   The questions mirror the chapter's 2026–2027 Google Form. Year/deadline come
   from data.js → scholarship so they update in one place.

   ── WHERE ANSWERS GO ────────────────────────────────────────────────────
   On submit the form POSTs to /api/scholarship, handled by our own Cloudflare
   Worker (worker/index.js) — no third-party form service. The Worker stores
   each application in a Cloudflare D1 database you own (see README → Scholarship
   submissions). Until the D1 database is configured, the endpoint politely says
   submissions aren't switched on yet, so nothing breaks before setup.

   Optional native anti-spam: set data.scholarship.turnstileSiteKey to a
   Cloudflare Turnstile site key to show a Turnstile widget; the Worker verifies
   it when TURNSTILE_SECRET is set. Leave it blank to rely on the honeypot. */
const schDS = window.WKYHBHutchinsonBellDesignSystem_7985db || {};

// Application questions, grouped into sections. `year` (e.g. "2026–2027") is
// woven into the prompts that reference it. Edit freely each cycle.
function buildSections(year) {
  const yr = year || 'this';
  return [
    {
      title: 'Student information',
      fields: [
        { name: 'studentName', label: 'Student name', type: 'text', required: true, placeholder: 'First and last name' },
        { name: 'studentAddress', label: 'Student home address', type: 'text', required: true, placeholder: 'Street, city, state, ZIP' },
        { name: 'studentPhone', label: 'Student phone number', type: 'tel', width: 'half', placeholder: '(270) 555-0123' },
        { name: 'studentEmail', label: 'Student email', type: 'email', required: true, width: 'half', placeholder: 'you@email.com' },
      ],
    },
    {
      title: 'Parent / guardian information',
      fields: [
        { name: 'parentName', label: 'Parent(s) / guardian name', type: 'text', required: true, placeholder: 'Parent or guardian name(s)' },
        { name: 'parentAddress', label: 'Parent(s) / guardian home address', type: 'text', placeholder: 'Only if different from the student' },
        { name: 'parentPhone', label: 'Parent(s) / guardian cell phone', type: 'tel', width: 'half', placeholder: '(270) 555-0123' },
        { name: 'parentEmail', label: 'Parent(s) / guardian email', type: 'email', required: true, width: 'half', placeholder: 'parent@email.com' },
      ],
    },
    {
      title: 'Membership & eligibility',
      fields: [
        { name: 'membership', label: 'Are you or your parent(s)/guardian a member of the Western Kentucky Hutchinson Bell?', type: 'radio', required: true,
          options: ['Yes', 'No'], helper: 'Current chapter membership is required of applicants.' },
        { name: 'highSchool', label: 'Please list the high school you graduated from and the year you graduated.', type: 'text', required: true, placeholder: 'High school name and graduation year' },
      ],
    },
    {
      title: 'Florida College',
      fields: [
        { name: 'camps', label: 'Please list all of the FC Camps you have attended while in high school or college, and the ones you plan to attend this upcoming summer.', type: 'textarea', required: true,
          placeholder: 'List camps attended and planned.' },
        { name: 'accepted', label: `Have you been accepted to Florida College for the ${yr} academic year?`, type: 'radio', required: true,
          options: ['Yes', 'No', 'Other (explain)'] },
        { name: 'acceptedOther', label: 'If you chose "Other" above, please explain briefly.', type: 'text',
          showIf: (f) => f.accepted === 'Other (explain)', placeholder: 'Brief explanation' },
        { name: 'enrollLevel', label: 'For the upcoming fall academic year you will be enrolled as a:', type: 'radio', required: true,
          options: ['Freshman', 'Sophomore', 'Junior', 'Senior'] },
      ],
    },
    {
      title: 'Additional information',
      fields: [
        { name: 'siblings', label: 'If you have any other siblings attending college or trade school next year, please list them below along with where they are attending.', type: 'textarea',
          placeholder: 'Optional' },
        { name: 'otherAid', label: 'Are you receiving any other type of financial aid or scholarships from other entities? If yes, please list below.', type: 'textarea',
          placeholder: 'Optional' },
      ],
    },
    {
      title: 'Tell us about yourself',
      fields: [
        { name: 'essay', label: 'In a few paragraphs, please respond to the following:', type: 'textarea', required: true,
          description: [
            '1. Why do you want to go to Florida College?',
            '2. In what ways have you been involved with Florida College camps, Florida College, or the Hutchinson Bell organizations?',
            '3. Please explain how your experiences with Florida College camps, Florida College, or the Hutchinson Bell has impacted you and your desire to attend Florida College.',
            '4. Please describe how you hope to be involved this next year at FC (academically, socially, athletically, spiritually, etc.).',
          ],
          placeholder: 'Write a few paragraphs responding to the prompts above.' },
      ],
    },
  ];
}

const errStyle = { display: 'block', fontSize: 'var(--text-xs)', color: 'var(--bell-crimson)', marginTop: 6 };
function labelWithStar(f) { return f.required ? `${f.label} *` : f.label; }

function FieldDescription({ lines }) {
  if (!lines || !lines.length) return null;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6, margin: '2px 0 2px' }}>
      {lines.map((l, i) => (
        <span key={i} style={{ fontFamily: 'var(--font-body)', fontSize: 14, lineHeight: 1.5, color: 'var(--text-body)' }}>{l}</span>
      ))}
    </div>
  );
}

function RadioField({ field, value, error, onChange }) {
  return (
    <div style={{ gridColumn: '1 / -1', display: 'flex', flexDirection: 'column', gap: 8 }}>
      <span style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--text-sm)', color: 'var(--text-strong)' }}>{labelWithStar(field)}</span>
      {field.helper && <span style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-muted)', marginTop: -2 }}>{field.helper}</span>}
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, marginTop: 2 }}>
        {field.options.map((o) => {
          const active = value === o;
          return (
            <label key={o} style={{
              display: 'inline-flex', alignItems: 'center', gap: 9, cursor: 'pointer',
              fontFamily: 'var(--font-body)', fontSize: 14.5, color: 'var(--text-body)',
              background: 'var(--surface)', border: `1.5px solid ${active ? 'var(--bell-crimson)' : 'var(--border-strong)'}`,
              boxShadow: active ? '0 0 0 3px var(--focus-ring)' : 'none',
              borderRadius: 'var(--radius-md)', padding: '9px 14px', transition: 'border-color var(--dur-fast), box-shadow var(--dur-fast)',
            }}>
              <input type="radio" name={field.name} value={o} checked={active} onChange={() => onChange(field.name, o)}
                style={{ width: 16, height: 16, accentColor: 'var(--bell-crimson)', margin: 0 }} />
              {o}
            </label>
          );
        })}
      </div>
      {error && <span style={errStyle}>{error}</span>}
    </div>
  );
}

/* Cloudflare Turnstile widget (native anti-spam). Renders only when a site key
   is configured; calls onToken with the token (or '' when it expires/errors). */
function Turnstile({ siteKey, onToken }) {
  const ref = React.useRef(null);
  const rendered = React.useRef(false);
  React.useEffect(() => {
    let timer;
    const SRC = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
    if (!document.querySelector(`script[src="${SRC}"]`)) {
      const el = document.createElement('script');
      el.src = SRC; el.async = true; el.defer = true;
      document.head.appendChild(el);
    }
    const tryRender = () => {
      if (rendered.current || !ref.current) return;
      if (!window.turnstile) { timer = setTimeout(tryRender, 200); return; }
      rendered.current = true;
      window.turnstile.render(ref.current, {
        sitekey: siteKey,
        callback: (token) => onToken(token),
        'expired-callback': () => onToken(''),
        'error-callback': () => onToken(''),
      });
    };
    tryRender();
    return () => { if (timer) clearTimeout(timer); };
  }, [siteKey]);
  return <div ref={ref} />;
}

function ScholarshipField({ field, value, error, onChange }) {
  const { Input } = schDS; const U = window.U;
  const common = { value: value || '', onChange: (e) => onChange(field.name, e.target.value) };
  if (field.type === 'radio') return <RadioField field={field} value={value} error={error} onChange={onChange} />;
  if (field.type === 'textarea') {
    return (
      <div style={{ gridColumn: '1 / -1' }}>
        {field.description && (
          <div style={{ marginBottom: 8 }}>
            <span style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--text-sm)', color: 'var(--text-strong)' }}>{labelWithStar(field)}</span>
            <FieldDescription lines={field.description} />
          </div>
        )}
        <U.TextArea label={field.description ? undefined : labelWithStar(field)} rows={field.description ? 8 : 5}
          required={field.required} placeholder={field.placeholder} {...common} />
        {error && <span style={errStyle}>{error}</span>}
      </div>
    );
  }
  if (field.type === 'select') {
    return (
      <div style={{ gridColumn: '1 / -1' }}>
        <U.Select label={labelWithStar(field)} {...common}>
          <option value="" disabled>Select…</option>
          {field.options.map((o) => <option key={o} value={o}>{o}</option>)}
        </U.Select>
        {error && <span style={errStyle}>{error}</span>}
      </div>
    );
  }
  return (
    <div style={{ gridColumn: field.width === 'half' ? 'auto' : '1 / -1' }}>
      <Input label={labelWithStar(field)} type={field.type || 'text'} required={field.required}
        placeholder={field.placeholder} helper={error ? undefined : field.helper} error={error} {...common} />
    </div>
  );
}

function ScholarshipPage() {
  const { Button } = schDS; const U = window.U; const data = window.WKYHB;
  const s = data.scholarship || {};
  const sections = React.useMemo(() => buildSections(s.year), [s.year]);
  const allFields = React.useMemo(() => sections.flatMap((sec) => sec.fields), [sections]);

  const [form, setForm] = React.useState({});
  const [botField, setBotField] = React.useState(''); // honeypot — real people leave it blank
  const [tsToken, setTsToken] = React.useState('');   // Turnstile token (when enabled)
  const [err, setErr] = React.useState({});
  const [status, setStatus] = React.useState('idle'); // idle | sending | done | error
  const [topError, setTopError] = React.useState('');

  const turnstileOn = !!(s.turnstileSiteKey && !/your[-_ ]?turnstile/i.test(s.turnstileSiteKey));
  const set = (name, val) => setForm((f) => ({ ...f, [name]: val }));
  const visible = (f) => !f.showIf || f.showIf(form);

  const validate = () => {
    const next = {};
    allFields.forEach((f) => {
      if (!visible(f)) return;
      const v = (form[f.name] || '').trim();
      if (f.required && !v) next[f.name] = 'This field is required.';
      else if (f.type === 'email' && v && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(v)) next[f.name] = 'Enter a valid email address.';
    });
    setErr(next);
    return Object.keys(next).length === 0;
  };

  const submit = async (e) => {
    e.preventDefault();
    setTopError('');
    if (botField) return; // bot tripped the honeypot
    if (!validate()) { setTopError('Please fix the highlighted fields and try again.'); return; }
    if (turnstileOn && !tsToken) { setTopError('Please complete the anti-spam check below and try again.'); return; }

    // Readable payload: question label → answer, so stored applications read
    // like the form rather than field codes.
    const answers = {};
    allFields.forEach((f) => { if (visible(f)) answers[f.label] = (form[f.name] || '').trim() || '—'; });
    const payload = {
      year: s.year || '',
      studentName: (form.studentName || '').trim(),
      studentEmail: (form.studentEmail || '').trim(),
      answers,
      botcheck: botField,
      turnstileToken: tsToken,
    };

    setStatus('sending');
    try {
      const res = await fetch('/api/scholarship', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        body: JSON.stringify(payload),
      });
      const json = await res.json().catch(() => ({}));
      if (res.ok && json.success) { setStatus('done'); U.scrollTop(); }
      else { setStatus('error'); setTopError(json.message || ('Something went wrong sending your application. Please try again, or email ' + data.org.email + '.')); }
    } catch (ex) {
      setStatus('error');
      setTopError('We could not reach the server. Check your connection and try again, or email ' + data.org.email + '.');
    }
  };

  const reset = () => { setForm({}); setErr({}); setTopError(''); setTsToken(''); setStatus('idle'); };

  // Off-season: applications closed → show a graceful notice instead of the form.
  if (!s.open) {
    return (
      <React.Fragment>
        <U.PageHeader eyebrow="Scholarships" title="Florida College Scholarship"
          lead="Our chapter awards scholarships each year to students from Western Kentucky headed to Florida College." />
        <U.Section bg="surface">
          <U.Container narrow>
            <div style={cardStyle}>
              <U.SuccessPanel title="Applications are closed right now" resetLabel="">
                A new application opens every year. Subscribe to the chapter newsletter and we'll let you know the moment {s.year ? `the ${s.year} ` : 'the next '}application is available. Questions in the meantime? Email <a href={`mailto:${data.org.email}`} style={linkStyle}>{data.org.email}</a>.
              </U.SuccessPanel>
              <div style={{ display: 'flex', justifyContent: 'center', marginTop: 8 }}>
                <Button size="lg" onClick={() => window.open(data.links.newsletter, '_blank')} iconRight={<U.IconExternal />}>Get notified next year</Button>
              </div>
            </div>
          </U.Container>
        </U.Section>
      </React.Fragment>
    );
  }

  return (
    <React.Fragment>
      <U.PageHeader eyebrow="Scholarships" title={`Florida College Scholarship${s.year ? ` ${s.year}` : ''}`}
        lead="The Western Kentucky Chapter of the Hutchinson Bell is proud to support Kentucky students (within the counties served by the WKHB Chapter) attending Florida College." />
      <U.Section bg="surface">
        <U.Container narrow>
          {/* Intro / eligibility notes — mirrors the top of the application. */}
          <div style={{ ...cardStyle, marginBottom: 'var(--space-6)' }}>
            <p style={{ fontFamily: 'var(--font-serif)', fontSize: 'var(--text-md)', lineHeight: 1.65, color: 'var(--text-body)', margin: '0 0 14px' }}>
              We welcome all students planning to attend FC{s.year ? ` for the ${s.year} school year` : ''} to apply, and will award scholarships to as many students as possible. Scholarships are awarded annually only — applicants must re-apply each academic year a scholarship is sought.
            </p>
            <ul style={{ margin: 0, paddingLeft: 20, display: 'flex', flexDirection: 'column', gap: 8, fontFamily: 'var(--font-body)', fontSize: 14.5, lineHeight: 1.55, color: 'var(--text-body)' }}>
              {s.deadline && <li>Applications are due by <strong>{s.deadline}</strong>.</li>}
              <li>Applicants receiving scholarships will be notified by the email provided{s.notifyBy ? <> no later than <strong>{s.notifyBy}</strong></> : ''}.</li>
              <li>Current membership in the Western KY Chapter of the Hutchinson Bell is required of applicants. Need to join or renew? <a href={data.links.join} target="_blank" rel="noopener" style={linkStyle}>Click here</a>.</li>
            </ul>
          </div>

          <div style={cardStyle}>
            {status === 'done' ? (
              <U.SuccessPanel title="Application received — thank you!" onReset={reset} resetLabel="Submit another application">
                We've got your application and a confirmation has gone to the chapter. We'll be in touch at the email you provided{s.notifyBy ? ` no later than ${s.notifyBy}` : ''}. Questions? Email <a href={`mailto:${data.org.email}`} style={linkStyle}>{data.org.email}</a>.
              </U.SuccessPanel>
            ) : (
              <form onSubmit={submit} noValidate style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-6)' }}>
                <p style={{ fontFamily: 'var(--font-body)', fontSize: 14.5, color: 'var(--text-muted)', margin: 0, lineHeight: 1.6 }}>
                  Fields marked <span style={{ color: 'var(--bell-crimson)', fontWeight: 700 }}>*</span> are required. Your responses are sent securely to the chapter.
                </p>

                {sections.map((section) => (
                  <fieldset key={section.title} style={{ border: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 14 }}>
                    <legend style={{ padding: 0 }}><U.Eyebrow>{section.title}</U.Eyebrow></legend>
                    <div className="wk-2col" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
                      {section.fields.filter(visible).map((f) => (
                        <ScholarshipField key={f.name} field={f} value={form[f.name]} error={err[f.name]} onChange={set} />
                      ))}
                    </div>
                  </fieldset>
                ))}

                {/* Honeypot — hidden from people, catches bots */}
                <input type="text" tabIndex={-1} autoComplete="off" value={botField} onChange={(e) => setBotField(e.target.value)}
                  style={{ position: 'absolute', left: '-9999px', width: 1, height: 1, opacity: 0 }} aria-hidden="true" />

                {turnstileOn && <Turnstile siteKey={s.turnstileSiteKey} onToken={setTsToken} />}

                {topError && (
                  <div style={{ background: 'rgba(196,18,46,0.08)', border: '1px solid rgba(196,18,46,0.35)', borderRadius: 'var(--radius-md)', padding: '12px 14px', fontFamily: 'var(--font-body)', fontSize: 14, color: 'var(--bell-crimson)', lineHeight: 1.5 }}>
                    {topError}
                  </div>
                )}

                <Button type="submit" size="lg" fullWidth disabled={status === 'sending'}>
                  {status === 'sending' ? 'Submitting…' : 'Submit application'}
                </Button>
                <p style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--text-muted)', margin: 0, textAlign: 'center', lineHeight: 1.5 }}>
                  Questions or need to send anything else? Email <a href={`mailto:${data.org.email}`} style={linkStyle}>{data.org.email}</a>.
                </p>
              </form>
            )}
          </div>
        </U.Container>
      </U.Section>
    </React.Fragment>
  );
}

const cardStyle = { background: 'var(--surface-paper)', borderRadius: 'var(--radius-lg)', border: '1px solid var(--border)', boxShadow: 'var(--shadow-md)', borderTop: '4px solid var(--bell-crimson)', padding: 'var(--space-7)' };
const linkStyle = { color: 'var(--bell-crimson)', fontWeight: 600, textDecoration: 'none' };

window.Pages = window.Pages || {};
window.Pages.scholarship = ScholarshipPage;
