/* Officer-only receipt workspace. Donor information lives only in component
   memory until an officer explicitly issues a receipt to the private API. */
const receiptApiRoot = '/admin/receipts-api';
const receiptToday = () => new Intl.DateTimeFormat('en-CA', { timeZone: 'America/Chicago', year: 'numeric', month: '2-digit', day: '2-digit' }).format(new Date());
const receiptMoney = (value) => new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(Number(value || 0));
const receiptDate = (value) => value ? new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric', timeZone: 'UTC' }).format(new Date(`${value.slice(0, 10)}T12:00:00Z`)) : '—';
const emptyReceipt = () => ({ donorName: '', donorEmail: '', donorAddress: '', donationDate: receiptToday(), monetaryAmount: '', paymentMethod: 'cash', checkNumber: '', propertyDescription: '', purpose: '', benefits: '', benefitsDescription: '', benefitsValue: '', issuedBy: '' });

function DonationReceiptPreview({ receipt, draft = false }) {
  const organization = receipt.organization || { name: 'Western Kentucky Chapter of the Hutchinson Bell', ein: '81-5379542', status: '501(c)(3) public charity', relationship: 'The chapter operates under The Hutchinson Bell.', address: 'PO Box 50613\nBowling Green, KY 42102' };
  return <article className="dr-paper" aria-label={draft ? 'Receipt preview' : 'Saved receipt'}>
    <header className="dr-paper-header">
      <p className="dr-eyebrow">Western Kentucky Chapter</p>
      <h2>Donation acknowledgment</h2>
      <p className="dr-organization">{organization.name}</p>
      <p>EIN {organization.ein} · {organization.status}<br />{organization.relationship}<br /><span className="dr-preserve">{organization.address}</span></p>
      <div className="dr-paper-meta"><strong>{draft ? 'PREVIEW · NOT YET ISSUED' : receipt.receiptNumber}</strong><span>{draft ? 'Issue date assigned when saved' : `Issued ${receiptDate(receipt.issueDate || receipt.issuedAt)}`}</span></div>
    </header>
    {receipt.status === 'void' && <div className="dr-void-stamp">VOID — retained for chapter records</div>}
    <section className="dr-paper-section"><h3>Donor</h3><p className="dr-donor-name">{receipt.donorName}</p>
      {receipt.donorAddress && <p className="dr-preserve">{receipt.donorAddress}</p>}
      {receipt.donorEmail && <p>{receipt.donorEmail}</p>}
    </section>
    <section className="dr-paper-section"><h3>Contribution received</h3>
      <dl className="dr-facts"><div><dt>Date received</dt><dd>{receiptDate(receipt.donationDate)}</dd></div>
        {receipt.monetaryAmount && <div><dt>Monetary contribution</dt><dd><strong>{receiptMoney(receipt.monetaryAmount)}</strong> · {({ cash: 'Cash', check: 'Check', other: 'Other monetary gift' })[receipt.paymentMethod]}{receipt.checkNumber ? ` #${receipt.checkNumber}` : ''}</dd></div>}
      </dl>
      {receipt.propertyDescription && <div className="dr-property"><h4>Non-cash contribution</h4><p className="dr-preserve">{receipt.propertyDescription}</p><p className="dr-paper-note">No value has been assigned to the donated property by the chapter. Determining its value is the donor’s responsibility.</p></div>}
      {receipt.purpose && <div><h4>Designation / purpose</h4><p className="dr-preserve">{receipt.purpose}</p></div>}
    </section>
    <section className="dr-paper-section"><h3>Goods or services provided in return</h3>
      {receipt.benefits === 'none' ? <p>No goods or services were provided in exchange for this contribution.</p> : <React.Fragment>
        <p className="dr-preserve">{receipt.benefitsDescription}</p><p><strong>Good faith estimate of fair market value: {receiptMoney(receipt.benefitsValue)}</strong></p>
        <p className="dr-paper-note">For federal income tax purposes, the deductible portion of a contribution is limited to the amount by which the money contributed and the fair market value of property donated exceed the value of goods or services provided in return, subject to applicable law.</p>
      </React.Fragment>}
    </section>
    <footer className="dr-paper-footer"><p>Acknowledged by <strong>{receipt.issuedBy}</strong>, on behalf of the chapter.</p><p>Thank you for supporting our chapter.</p></footer>
  </article>;
}

function DonationReceipts() {
  const [session, setSession] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [authError, setAuthError] = React.useState('');
  const [unavailable, setUnavailable] = React.useState(false);
  const [error, setError] = React.useState('');
  const [invalidField, setInvalidField] = React.useState('');
  const [notice, setNotice] = React.useState('');
  const [fields, setFields] = React.useState(emptyReceipt);
  const [moneyGift, setMoneyGift] = React.useState(true);
  const [propertyGift, setPropertyGift] = React.useState(false);
  const [dirty, setDirty] = React.useState(false);
  const [stage, setStage] = React.useState('edit');
  const [review, setReview] = React.useState(null);
  const [confirmed, setConfirmed] = React.useState(false);
  const [receipt, setReceipt] = React.useState(null);
  const [records, setRecords] = React.useState([]);
  const [cursor, setCursor] = React.useState(null);
  const [historyLoading, setHistoryLoading] = React.useState(false);
  const [historyError, setHistoryError] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [saveUnknown, setSaveUnknown] = React.useState(false);
  const [voidOpen, setVoidOpen] = React.useState(false);
  const [voidReason, setVoidReason] = React.useState('');
  const pendingSave = React.useRef(null);
  const inFlight = React.useRef(false);
  const allowed = React.useRef(false);
  const errorRef = React.useRef(null);
  const viewRef = React.useRef(null);

  const clearPrivate = React.useCallback(() => {
    allowed.current = false; pendingSave.current = null;
    setSession(null); setFields(emptyReceipt()); setReview(null); setReceipt(null); setRecords([]);
    setDirty(false); setError(''); setInvalidField(''); setNotice(''); setVoidOpen(false); setVoidReason('');
  }, []);

  const request = React.useCallback(async (path, options = {}) => {
    const response = await fetch(`${receiptApiRoot}${path}`, { credentials: 'same-origin', cache: 'no-store', redirect: 'manual',
      ...options, headers: { Accept: 'application/json', ...(options.body ? { 'Content-Type': 'application/json' } : {}), ...options.headers } });
    if (response.type === 'opaqueredirect' || (response.status >= 300 && response.status < 400)) {
      clearPrivate(); setAuthError('Your leadership session ended. Sign in again to continue.');
      throw new Error('Sign-in required.');
    }
    const result = await response.json().catch(() => null);
    if ([401, 403].includes(response.status) || (response.ok && !result)) {
      clearPrivate(); setAuthError('Your leadership session ended or receipt access is unavailable. Sign in again to continue.');
      throw new Error('Sign-in required.');
    }
    if (!response.ok || !result?.success) {
      const failure = new Error(result?.message || result?.error || 'The request could not be completed. Please try again.');
      failure.status = response.status; throw failure;
    }
    return result;
  }, [clearPrivate]);

  const loadHistory = React.useCallback(async (before = null) => {
    setHistoryLoading(true); setHistoryError('');
    try {
      const result = await request(`/receipts${before ? `?before=${encodeURIComponent(before)}` : ''}`);
      if (allowed.current) { setRecords((old) => before ? [...old, ...result.receipts] : result.receipts); setCursor(result.nextCursor || null); }
    } catch (failure) { if (allowed.current) setHistoryError(failure.message); }
    finally { setHistoryLoading(false); }
  }, [request]);

  React.useEffect(() => {
    let cancelled = false;
    const load = async () => {
      try {
        const result = await request('/session');
        if (!cancelled) { allowed.current = true; setSession(result); await loadHistory(); }
      } catch (failure) { if (!cancelled) { setUnavailable(failure.status === 503); setAuthError(failure.status === 503 ? `${failure.message} Please contact the chapter website administrator.` : 'Your receipt access could not be verified. Sign in through Leadership login, or ask the chapter administrator for access.'); } }
      finally { if (!cancelled) setLoading(false); }
    };
    load();
    const restored = (event) => { if (event.persisted) { clearPrivate(); window.location.reload(); } };
    const hidden = (event) => { if (event.persisted) clearPrivate(); };
    window.addEventListener('pageshow', restored); window.addEventListener('pagehide', hidden);
    return () => { cancelled = true; allowed.current = false; window.removeEventListener('pageshow', restored); window.removeEventListener('pagehide', hidden); };
  }, [request, loadHistory, clearPrivate]);

  React.useEffect(() => {
    if (!dirty) return;
    const unload = (event) => { event.preventDefault(); event.returnValue = ''; };
    const navigate = (event) => { if (!window.confirm('Leave this receipt? Unsaved information will be lost.')) event.preventDefault(); };
    window.addEventListener('beforeunload', unload); window.addEventListener('wkbeforeNavigate', navigate);
    return () => { window.removeEventListener('beforeunload', unload); window.removeEventListener('wkbeforeNavigate', navigate); };
  }, [dirty]);
  React.useEffect(() => { if (error) { const field = invalidField && document.getElementById(`dr-${invalidField}`); (field || errorRef.current)?.focus(); } }, [error, invalidField]);
  React.useEffect(() => { if (stage !== 'edit') viewRef.current?.focus(); }, [stage]);

  const update = (name, value) => { setFields((old) => ({ ...old, [name]: value })); setDirty(true); setError(''); setInvalidField(''); };
  const normalized = () => ({ ...fields, donorName: fields.donorName.trim(), donorEmail: fields.donorEmail.trim(), donorAddress: fields.donorAddress.trim(),
    monetaryAmount: moneyGift ? fields.monetaryAmount.trim() : '', paymentMethod: moneyGift ? fields.paymentMethod : '',
    checkNumber: moneyGift && fields.paymentMethod === 'check' ? fields.checkNumber.trim() : '',
    propertyDescription: propertyGift ? fields.propertyDescription.trim() : '', purpose: fields.purpose.trim(),
    benefitsDescription: fields.benefits === 'provided' ? fields.benefitsDescription.trim() : '',
    benefitsValue: fields.benefits === 'provided' ? fields.benefitsValue.trim() : '', issuedBy: fields.issuedBy.trim() });

  const reviewReceipt = (event) => {
    event.preventDefault(); setError(''); setInvalidField('');
    const invalid = (message, name = '') => { setInvalidField(name); setError(message); };
    const value = normalized();
    const validAmount = (amount, allowZero = false) => /^(?:0|[1-9]\d{0,7})(\.\d{1,2})?$/.test(amount) && (allowZero ? Number(amount) >= 0 : Number(amount) > 0);
    if (!moneyGift && !propertyGift) return invalid('Choose a monetary contribution, a non-cash contribution, or both.');
    if (!value.donorName) return invalid('Enter the donor’s name.', 'donorName');
    if (!value.issuedBy) return invalid('Enter the officer’s full name.', 'issuedBy');
    if (moneyGift && !validAmount(value.monetaryAmount)) return invalid('Enter a monetary amount greater than zero, with no leading zeros and no more than two decimal places.', 'monetaryAmount');
    if (propertyGift && !value.propertyDescription) return invalid('Describe the donated property. Do not enter a value.', 'propertyDescription');
    if (!value.benefits) return invalid('Choose whether the donor received goods or services in return.');
    if (value.benefits === 'provided' && (!value.benefitsDescription || !validAmount(value.benefitsValue, true))) return invalid('Describe what the donor received and enter its good faith fair market value, including zero if appropriate.', !value.benefitsDescription ? 'benefitsDescription' : 'benefitsValue');
    setReview(value); setConfirmed(false); setStage('review'); setDirty(true);
  };

  const issueReceipt = async () => {
    if (!confirmed || inFlight.current) return;
    if (!pendingSave.current) pendingSave.current = { ...review, requestId: crypto.randomUUID(), confirmation: true };
    inFlight.current = true; setBusy(true); setError('');
    try {
      const result = await request('/receipts', { method: 'POST', body: JSON.stringify(pendingSave.current) });
      if (!allowed.current) return;
      pendingSave.current = null; setReceipt(result.receipt); setStage('saved'); setDirty(false); setSaveUnknown(false);
      setNotice('Receipt issued and saved in the chapter’s private records. Download the PDF to email the donor yourself.');
      await loadHistory();
    } catch (failure) {
      if (!allowed.current) return;
      const rejected = [400, 422].includes(failure.status);
      if (rejected) pendingSave.current = null;
      setSaveUnknown(!rejected);
      setError(rejected ? failure.message : 'We could not confirm whether this receipt was saved. Retry below using the same information; the receipt number will not be duplicated.');
    } finally { inFlight.current = false; setBusy(false); }
  };

  const reset = () => {
    if (dirty && !window.confirm('Discard the unsaved receipt and start over?')) return;
    setFields(emptyReceipt()); setMoneyGift(true); setPropertyGift(false); setReview(null); setReceipt(null); setStage('edit');
    setConfirmed(false); setDirty(false); setError(''); setNotice(''); setSaveUnknown(false); pendingSave.current = null;
    setVoidOpen(false); setVoidReason('');
  };
  const openReceipt = async (id) => {
    if (busy || (dirty && !window.confirm('Leave your unsaved receipt and open this saved receipt?'))) return;
    setBusy(true); setError(''); setNotice('');
    try {
      const result = await request(`/receipts/${encodeURIComponent(id)}`);
      if (!allowed.current) return;
      setReceipt(result.receipt); setStage('saved'); setDirty(false); setReview(null); setFields(emptyReceipt());
      pendingSave.current = null; setSaveUnknown(false); setVoidOpen(false); setVoidReason('');
    } catch (failure) { if (allowed.current) setError(failure.message); }
    finally { setBusy(false); }
  };
  const retryTreasurerCopy = async () => {
    if (inFlight.current) return;
    inFlight.current = true; setBusy(true); setError(''); setNotice('');
    try {
      const result = await request(`/receipts/${encodeURIComponent(receipt.id)}/treasurer-copy`, { method: 'POST', body: JSON.stringify({ confirmation: true }) });
      if (!allowed.current) return;
      setReceipt(result.receipt);
      setNotice('The email provider accepted the recordkeeping copy for treasurer@wkyhb.com. Inbox delivery is not confirmed.');
    } catch (failure) {
      if (!allowed.current) return;
      setError(`${failure.message} The receipt is still saved and its PDF is available. Delivery of the treasurer’s copy is not confirmed.`);
      try { const result = await request(`/receipts/${encodeURIComponent(receipt.id)}`); if (allowed.current) setReceipt(result.receipt); } catch { /* Keep the visible failure and never claim delivery. */ }
    } finally { inFlight.current = false; setBusy(false); }
  };
  const downloadPdf = async () => {
    if (inFlight.current) return;
    inFlight.current = true; setBusy(true); setError('');
    try {
      const response = await fetch(`${receiptApiRoot}/receipts/${encodeURIComponent(receipt.id)}/pdf`, { credentials: 'same-origin', cache: 'no-store', redirect: 'manual', headers: { Accept: 'application/pdf' } });
      if ([401, 403].includes(response.status) || response.type === 'opaqueredirect' || (response.status >= 300 && response.status < 400)) {
        clearPrivate(); setAuthError('Your leadership session ended. Sign in again to continue.'); return;
      }
      if (!response.ok || !response.headers.get('Content-Type')?.includes('application/pdf')) {
        const result = await response.json().catch(() => null);
        throw new Error(result?.message || 'The PDF could not be downloaded. Reopen the saved receipt and try again, or use Print receipt.');
      }
      const blob = await response.blob();
      if (!allowed.current) return;
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a'); link.href = url; link.download = `${receipt.receiptNumber}${receipt.status === 'void' ? '-VOID' : ''}.pdf`;
      document.body.appendChild(link); link.click(); link.remove();
      window.setTimeout(() => URL.revokeObjectURL(url), 30000);
    } catch (failure) { if (allowed.current) setError(failure.message); }
    finally { inFlight.current = false; setBusy(false); }
  };
  const voidReceipt = async (event) => {
    event.preventDefault(); if (inFlight.current || !voidReason.trim()) return;
    inFlight.current = true; setBusy(true); setError('');
    try {
      const result = await request(`/receipts/${encodeURIComponent(receipt.id)}/void`, { method: 'POST', body: JSON.stringify({ reason: voidReason.trim(), confirmation: true }) });
      if (!allowed.current) return;
      setReceipt(result.receipt); setVoidOpen(false); setNotice('Receipt marked void. The original record is retained. Notify the donor and treasurer if they already received a copy; the website does not send a void notice.'); await loadHistory();
    } catch (failure) { if (allowed.current) setError(failure.message); }
    finally { inFlight.current = false; setBusy(false); }
  };

  const field = (name, label, options = {}) => <label className={`dr-field ${options.wide ? 'dr-wide' : ''}`} htmlFor={`dr-${name}`}><span>{label}{options.required ? <span className="dr-required"> *</span> : <span className="dr-optional"> · optional</span>}</span>
    {options.multiline ? <textarea id={`dr-${name}`} name={name} value={fields[name]} onChange={(event) => update(name, event.target.value)} rows={options.rows || 3} maxLength={options.maxLength} required={options.required} aria-invalid={invalidField === name || undefined} aria-describedby={[options.help && `dr-${name}-help`, invalidField === name && 'dr-form-error'].filter(Boolean).join(' ') || undefined} />
      : <input id={`dr-${name}`} name={name} value={fields[name]} onChange={(event) => update(name, event.target.value)} type={options.type || 'text'} required={options.required} maxLength={options.maxLength} inputMode={options.inputMode} max={options.max} autoComplete="off" aria-invalid={invalidField === name || undefined} aria-describedby={[options.help && `dr-${name}-help`, invalidField === name && 'dr-form-error'].filter(Boolean).join(' ') || undefined} />}
    {options.help && <small id={`dr-${name}-help`}>{options.help}</small>}
  </label>;

  const copyStatus = receipt?.treasurerEmailStatus || 'pending';
  const canRetryTreasurerCopy = session?.emailAvailable && receipt?.status !== 'void' && (receipt?.treasurerCopyRetryAllowed ?? ['pending', 'failed', 'uncertain'].includes(copyStatus));

  return <section className="dr-workspace wk-container" aria-labelledby="dr-title">
    <header className="dr-header"><div><a className="dr-back" href="/admin/leadership">← Leadership hub</a><p className="dr-eyebrow">Chapter leadership</p><h1 id="dr-title">Donation receipts</h1><p>Create an acknowledgment, save it securely, and share it with your donor.</p></div>
      {session && <div className="dr-session"><span>{session.email}</span><a href="/cdn-cgi/access/logout" onClick={clearPrivate}>Sign out</a></div>}
    </header>
    {loading && <p role="status">Checking your receipt access…</p>}
    {authError && <div className="dr-card" role="alert"><h2>{unavailable ? 'Receipts temporarily unavailable' : 'Leadership access required'}</h2><p>{authError}</p><a className="dr-button" href="/leadership">Leadership login</a></div>}
    {session && <div className="dr-layout">
      <div className="dr-main">
        {error && <div id="dr-form-error" className="dr-alert" role="alert" tabIndex={-1} ref={errorRef}>{error}</div>}
        {notice && <div className="dr-notice" role="status">{notice}</div>}
        {stage === 'edit' && <form className="dr-card dr-form" onSubmit={reviewReceipt}>
          <div className="dr-section-heading"><span className="dr-step">1</span><div><h2>New receipt</h2><p>Required fields are marked *. Review before anything is issued.</p></div></div>
          <fieldset><legend>Donor</legend><div className="dr-fields">
            {field('donorName', 'Donor / organization name', { required: true, maxLength: 200, wide: true })}
            {field('donorEmail', 'Donor email', { type: 'email', maxLength: 254, wide: true, help: 'For your records. Download the receipt PDF and email the donor yourself.' })}
            {field('donorAddress', 'Mailing address', { multiline: true, maxLength: 1000, wide: true, rows: 2 })}
          </div></fieldset>
          <fieldset><legend>Contribution</legend><div className="dr-fields">
            {field('donationDate', 'Date received', { type: 'date', required: true, max: receiptToday(), help: 'The actual date the chapter received this gift.' })}
            <div className="dr-wide"><p className="dr-label">What did the donor give? <span className="dr-required">*</span></p><div className="dr-choice-row">
              <label className={`dr-choice ${moneyGift ? 'is-selected' : ''}`}><input type="checkbox" checked={moneyGift} onChange={(event) => { setMoneyGift(event.target.checked); setDirty(true); if (!event.target.checked) setFields((old) => ({ ...old, monetaryAmount: '', paymentMethod: 'cash', checkNumber: '' })); }} /><span>Money <small>Cash, check, or other payment</small></span></label>
              <label className={`dr-choice ${propertyGift ? 'is-selected' : ''}`}><input type="checkbox" checked={propertyGift} onChange={(event) => { setPropertyGift(event.target.checked); setDirty(true); if (!event.target.checked) update('propertyDescription', ''); }} /><span>Items / property <small>An in-kind contribution</small></span></label>
            </div></div>
            {moneyGift && <React.Fragment>
              {field('monetaryAmount', 'Monetary amount (USD)', { required: true, inputMode: 'decimal', maxLength: 11, help: 'For example, 250.00. Do not include a dollar sign.' })}
              <label className="dr-field" htmlFor="dr-paymentMethod"><span>Payment method <span className="dr-required">*</span></span><select id="dr-paymentMethod" value={fields.paymentMethod} onChange={(event) => { update('paymentMethod', event.target.value); if (event.target.value !== 'check') update('checkNumber', ''); }}><option value="cash">Cash</option><option value="check">Check</option><option value="other">Other monetary gift</option></select></label>
              {fields.paymentMethod === 'check' && field('checkNumber', 'Check number', { maxLength: 80 })}
            </React.Fragment>}
            {propertyGift && field('propertyDescription', 'Describe the donated items / property', { required: true, multiline: true, wide: true, maxLength: 4000, help: 'Include quantity and a clear description. Do not assign a dollar value. Donated services are not property.' })}
            {field('purpose', 'Designation / purpose', { maxLength: 1000, multiline: true, wide: true, rows: 2, help: 'For example, scholarship fund. Include only a designation accepted by the chapter.' })}
          </div></fieldset>
          <fieldset><legend>Did the donor receive anything in return? <span className="dr-required">*</span></legend><p className="dr-help">This means goods or services the chapter provided to the donor, such as a meal or event admission.</p>
            <div className="dr-choice-stack">
              <label className={`dr-choice ${fields.benefits === 'none' ? 'is-selected' : ''}`}><input type="radio" name="benefits" value="none" checked={fields.benefits === 'none'} required onChange={() => { update('benefits', 'none'); update('benefitsDescription', ''); update('benefitsValue', ''); }} /><span>No goods or services were provided.</span></label>
              <label className={`dr-choice ${fields.benefits === 'provided' ? 'is-selected' : ''}`}><input type="radio" name="benefits" value="provided" checked={fields.benefits === 'provided'} required onChange={() => update('benefits', 'provided')} /><span>Yes, goods or services were provided.</span></label>
            </div>
            {fields.benefits === 'provided' && <div className="dr-fields dr-benefits">
              {field('benefitsDescription', 'Describe what the donor received', { required: true, multiline: true, maxLength: 2000, wide: true })}
              {field('benefitsValue', 'Fair market value of what the donor received (USD)', { required: true, inputMode: 'decimal', maxLength: 11, wide: true, help: 'Give a good faith estimate of the benefit’s value. This is not the value of donated property.' })}
            </div>}
          </fieldset>
          <fieldset><legend>Officer acknowledgment</legend><div className="dr-fields">{field('issuedBy', 'Officer’s full name', { required: true, maxLength: 200, wide: true })}</div><p className="dr-help">Your signed-in email is recorded with the receipt for the chapter’s records.</p></fieldset>
          <details className="dr-guidance"><summary>Special gifts and IRS guidance</summary><p>Ask the treasurer to review vehicles, securities, real estate, unreimbursed expenses, donated services, or other unusual gifts and benefit arrangements before using this form. The intangible religious benefits exception is limited to qualifying religious organizations and is not a general chapter option.</p><p>For non-cash gifts, acknowledge the property without estimating its value. Donors may have additional appraisal or filing requirements.</p><a href="https://www.irs.gov/pub/irs-pdf/p1771.pdf" target="_blank" rel="noopener noreferrer">IRS Publication 1771 ↗</a></details>
          <div className="dr-actions"><button className="dr-button" type="submit">Review receipt <span aria-hidden="true">→</span></button>{dirty && <span className="dr-help">Unsaved draft</span>}</div>
        </form>}
        {stage === 'review' && <div className="dr-review" ref={viewRef} tabIndex={-1}>
          <div className="dr-section-heading"><span className="dr-step">2</span><div><h2>Review before issuing</h2><p>Check names, dates, amounts, and the goods or services statement.</p></div></div>
          <DonationReceiptPreview receipt={review} draft />
          <div className="dr-card dr-issue"><p>Issuing saves a permanent chapter record and a downloadable PDF, and requests a recordkeeping copy for <strong>treasurer@wkyhb.com</strong>. You will email the donor yourself.</p><p>To correct an issued receipt, mark it void and issue a replacement.</p>
            {!session.emailAvailable && <p className="dr-help">Treasurer email is not configured yet. The PDF will still be saved, and the treasurer’s copy will remain pending until an officer sends it from this saved record after setup.</p>}
            <label className="dr-check"><input type="checkbox" checked={confirmed} disabled={busy || saveUnknown} onChange={(event) => setConfirmed(event.target.checked)} /><span>I have checked this receipt and confirm the information is correct.</span></label>
            <div className="dr-actions"><button className="dr-button" type="button" disabled={!confirmed || busy} onClick={issueReceipt}>{busy ? 'Saving receipt…' : saveUnknown ? 'Retry saving same receipt' : 'Issue and save receipt'}</button><button className="dr-button dr-secondary" type="button" disabled={busy || saveUnknown} onClick={() => { setStage('edit'); setError(''); }}>Back to edit</button></div>
            {saveUnknown && <p className="dr-help">Keep this page open and retry to resolve the save before starting another receipt.</p>}
          </div>
        </div>}
        {stage === 'saved' && receipt && <div className="dr-saved" ref={viewRef} tabIndex={-1}>
          <div className="dr-saved-heading"><div><p className="dr-eyebrow">Saved chapter record</p><h2>{receipt.receiptNumber}</h2></div><span className={`dr-badge ${receipt.status === 'void' ? 'is-void' : ''}`}>{receipt.status === 'void' ? 'Void' : 'Issued'}</span></div>
          <div className="dr-card dr-delivery"><h3>Download or print</h3><div className="dr-actions">
            <button className="dr-button" type="button" onClick={downloadPdf} disabled={busy || receipt.pdfAvailable === false}>Download PDF</button>
            <a className="dr-button dr-secondary" href={`${receiptApiRoot}/receipts/${encodeURIComponent(receipt.id)}/print`} target="_blank" rel="noopener noreferrer" title="Open the print view in a new tab">Print receipt</a>
          </div>{receipt.pdfAvailable === false && <p className="dr-help">This older receipt has no stored PDF. Use Print receipt, then choose “Save as PDF” in your browser.</p>}<p className="dr-help">Attach the downloaded PDF to an email from your own account, or print a copy for the donor. The website sends only the treasurer’s recordkeeping copy.</p>
            <div className="dr-email" aria-label="Treasurer recordkeeping copy">
              <h4>Treasurer’s recordkeeping copy</h4><p className="dr-help">Recipient: treasurer@wkyhb.com</p>
              <p><strong>Status: </strong>{{ pending: session.emailAvailable ? 'Pending. The receipt is saved; the treasurer’s copy has not been requested successfully yet.' : 'Pending — treasurer email is not configured yet.', sending: 'Sending request in progress; delivery is not confirmed.', accepted: 'Accepted by the email provider; inbox delivery is not confirmed.', uncertain: 'Sending status is uncertain; delivery is not confirmed.', failed: 'Sending failed; delivery is not confirmed.', cancelled: 'Cancelled because this receipt was marked void.', unavailable: 'Automatic recordkeeping copies are unavailable for this older receipt.' }[copyStatus]}</p>
              {!session.emailAvailable && receipt.status !== 'void' && receipt.treasurerEmailStatus !== 'unavailable' && <p className="dr-help">Download the PDF for the donor now. After email setup, reopen this saved record to send the treasurer’s copy.</p>}
              {canRetryTreasurerCopy && <button className="dr-button dr-secondary" type="button" disabled={busy} onClick={retryTreasurerCopy}>{copyStatus === 'pending' ? 'Send treasurer’s copy' : 'Retry treasurer’s copy'}</button>}
              {session.emailAvailable && receipt.status !== 'void' && copyStatus === 'sending' && <React.Fragment><p className="dr-help">If sending appears stuck, wait two minutes and refresh to check for a safe retry.</p><button className="dr-text-button" type="button" disabled={busy} onClick={() => openReceipt(receipt.id)}>Refresh copy status</button></React.Fragment>}
              {receipt.status !== 'void' && receipt.treasurerCopyRetryAllowed === false && ['failed', 'uncertain'].includes(copyStatus) && <p className="dr-help">Automatic retries are unavailable. Ask the chapter website administrator to check whether the treasurer’s copy was sent before emailing the PDF manually.</p>}
            </div>
          </div>
          <DonationReceiptPreview receipt={receipt} />
          <div className="dr-record-actions"><button className="dr-button" type="button" disabled={busy} onClick={reset}>Create another receipt</button>
            {receipt.status !== 'void' && <button className="dr-text-button" type="button" disabled={busy} onClick={() => setVoidOpen(!voidOpen)}>Correct an issued receipt</button>}
          </div>
          {voidOpen && <form className="dr-card dr-void-form" onSubmit={voidReceipt}><h3>Mark this receipt void</h3><p>Keep the original record, mark it void, then create a replacement. A void does not recall copies already sent. Notify the donor and treasurer about the correction if they received a copy; the website does not email void notices.</p><label className="dr-field" htmlFor="dr-void-reason"><span>Reason for voiding <span className="dr-required">*</span></span><textarea id="dr-void-reason" required maxLength={1000} value={voidReason} onChange={(event) => setVoidReason(event.target.value)} /></label><div className="dr-actions"><button className="dr-button dr-danger" type="submit" disabled={busy || !voidReason.trim()}>Confirm: mark receipt void</button><button className="dr-button dr-secondary" type="button" disabled={busy} onClick={() => setVoidOpen(false)}>Cancel</button></div></form>}
          {receipt.status === 'void' && receipt.voidReason && <p className="dr-help">Void reason: {receipt.voidReason}</p>}
        </div>}
      </div>
      <aside className="dr-card dr-history" aria-labelledby="dr-history-title"><div className="dr-history-heading"><h2 id="dr-history-title">Saved receipts</h2><button className="dr-text-button" type="button" disabled={historyLoading || busy} onClick={() => loadHistory()}>Refresh</button></div>
        <p className="dr-help">Private chapter records. Reopen a receipt whenever you need another copy.</p>
        {historyError && <p className="dr-history-error" role="alert">{historyError}</p>}
        {!records.length && !historyLoading && !historyError && <p className="dr-empty">Your first issued receipt will appear here.</p>}
        <ul className="dr-record-list">{records.map((record) => <li key={record.id}><button className={`dr-record ${receipt?.id === record.id && stage === 'saved' ? 'is-current' : ''}`} type="button" disabled={busy || saveUnknown} onClick={() => openReceipt(record.id)}><span className="dr-record-number">{record.receiptNumber}<span className="dr-record-status">{record.status === 'void' ? 'Void' : 'Issued'}</span></span><strong>{record.donorName}</strong><span>Gift received {receiptDate(record.donationDate)}</span></button></li>)}</ul>
        {historyLoading && <p role="status">Loading saved receipts…</p>}
        {cursor && <button className="dr-button dr-secondary dr-load-more" type="button" disabled={historyLoading || busy} onClick={() => loadHistory(cursor)}>Load older receipts</button>}
      </aside>
    </div>}
  </section>;
}

window.DonationReceipts = DonationReceipts;
