/* global React, BrainMark, I, StepHead, Field, Select, Opt, CheckRow, NavFooter, Helper, ZipField */
const { useState: useCB, useEffect: useCBE } = React;

/* ---- constants (CB-prefixed to avoid cross-script collisions) ---- */
const CB_STATES = ['AL','AK','AZ','AR','CA','CO','CT','DE','FL','GA','HI','ID','IL','IN','IA','KS','KY','LA','ME','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','OH','OK','OR','PA','RI','SC','SD','TN','TX','UT','VT','VA','WA','WV','WI','WY','DC'];
const CB_COUNTRIES = ['Canada','Mexico','United Kingdom','Australia','Germany','France','India','China','Japan','Other'];
const CB_SUFFIXES = ['Jr.','Sr.','II','III','IV','V','Other'];
const CB_MONTHS = ['0','1','2','3','4','5','6','7','8','9','10','11'];
const CB_BRANCH = ['Army','Navy','Air Force','Marine Corps','Coast Guard','Space Force','National Guard','Reserves','Other'];
const CB_CITIZENSHIP = [
  { value: 'U.S. Citizen', sub: 'A citizen of the United States.' },
  { value: 'Permanent Resident Alien', sub: 'Holds a green card / permanent residency.' },
  { value: 'Non-Permanent Resident Alien', sub: 'Lives in the U.S. on a visa or other status.' },
];
const CB_MARITAL = [
  { value: 'Married', sub: 'Legally married.' },
  { value: 'Separated', sub: 'Legally separated from a spouse.' },
  { value: 'Unmarried', sub: 'Single, divorced, or widowed.' },
];
const CB_MIL = [
  { value: 'none', title: 'No Military Service' },
  { value: 'active', title: 'Active Duty' },
  { value: 'retired', title: 'Retired, Discharged, or Separated from Service' },
  { value: 'reserve', title: 'Reserve / National Guard Only' },
  { value: 'surviving', title: 'Surviving Spouse' },
];
const CB_MIL_LABEL = { none: 'No Military Service', active: 'Active Duty', retired: 'Retired, Discharged, or Separated from Service', reserve: 'Reserve / National Guard Only', surviving: 'Surviving Spouse' };
const CB_HOUSING = [
  { value: 'Own', sub: 'Owns their current home.', icon: () => I.home(22) },
  { value: 'Rent', sub: 'Rents their current home.', icon: () => I.condo(20) },
  { value: 'Living Rent Free', sub: 'Living rent free.', icon: () => I.seedling(20) },
];
const CB_CREDIT = [
  { value: '760+', title: 'Excellent', sub: '760 and above' },
  { value: '720-759', title: 'Very Good', sub: '720 – 759' },
  { value: '680-719', title: 'Good', sub: '680 – 719' },
  { value: '640-679', title: 'Fair', sub: '640 – 679' },
  { value: '580-639', title: 'Needs Work', sub: '580 – 639' },
  { value: 'not-sure', title: 'Not Sure', sub: "Don't know the score? That's okay." },
];
const CB_CREDIT_LABEL = { '760+': 'Excellent · 760+', '720-759': 'Very Good · 720–759', '680-719': 'Good · 680–719', '640-679': 'Fair · 640–679', '580-639': 'Needs Work · 580–639', 'not-sure': 'Not Sure' };

const CB_STEPS = ['name', 'contact', 'personal', 'marital', 'military', 'address', 'housing', 'time', 'credit', 'review'];

const cbDigits = s => (s || '').replace(/[^\d]/g, '');
const cbMoney = s => { const d = cbDigits(s); return d ? Number(d).toLocaleString('en-US') : ''; };
const cbEmailOk = e => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);
const cbPhoneOk = p => cbDigits(p).length === 10;
const cbFmtPhone = s => {
  const d = cbDigits(s).slice(0, 10);
  if (d.length > 6) return `(${d.slice(0,3)}) ${d.slice(3,6)}-${d.slice(6)}`;
  if (d.length > 3) return `(${d.slice(0,3)}) ${d.slice(3)}`;
  if (d.length > 0) return `(${d}`;
  return '';
};
function cbFmtDob(s) { if (!s) return '—'; const [y, m, d] = s.split('-'); return `${m}/${d}/${y}`; }

const CB_DEFAULT = {
  name: { first: '', middle: '', last: '', suffix: '', suffixOther: '' },
  email: '', phone: '',
  citizenship: '', dob: '',
  marital: '', marriedToBorrower: null,
  milService: '', milBranch: '', milBranchOther: '',
  sharedAddress: false,
  curAddr: { intl: false, street: '', unit: '', city: '', state: '', zip: '', province: '', postal: '', country: '' },
  mailingSame: false,
  mailAddr: { intl: false, street: '', unit: '', city: '', state: '', zip: '', province: '', postal: '', country: '' },
  housing: '',
  // Renter follow-up (URLA parity: monthly rent is required when renting).
  rent: '',
  // 0 yr 0 mo is a valid answer (just moved in); no forced interaction.
  timeAt: { years: '0', months: '0' },
  credit: '',
  touched: false,
};

/* ---- address block ---- */
function CBAddress({ a, setA, t }) {
  // ZIP-first autofill; hook above the intl early-return (stable hook order).
  const zipFillRef = React.useRef({ city: '', state: '' });
  const applyZipFill = hit => {
    const patch = {};
    if (!String(a.city || '').trim() || a.city === zipFillRef.current.city) { patch.city = hit.city; zipFillRef.current.city = hit.city; }
    if (!a.state || a.state === zipFillRef.current.state) { patch.state = hit.state; zipFillRef.current.state = hit.state; }
    if (Object.keys(patch).length) setA(patch);
  };
  if (a.intl) {
    const e = f => t && !String(a[f] || '').trim();
    return <>
      <Field label="Street address" value={a.street} onChange={v => setA({ street: v })} placeholder="221B Baker Street" error={e('street') ? 'Required' : ''} />
      <Field label="Apartment / unit number" optional value={a.unit} onChange={v => setA({ unit: v })} placeholder="Flat 2" />
      <div className="field-row">
        <Field label="City / locality" value={a.city} onChange={v => setA({ city: v })} placeholder="London" error={e('city') ? 'Required' : ''} />
        <Field label="State / province / region" value={a.province} onChange={v => setA({ province: v })} placeholder="Greater London" error={e('province') ? 'Required' : ''} />
      </div>
      <div className="field-row">
        <Field label="Postal code" value={a.postal} onChange={v => setA({ postal: v })} placeholder="NW1 6XE" error={e('postal') ? 'Required' : ''} />
        <Select label="Country" value={a.country} onChange={v => setA({ country: v })} options={CB_COUNTRIES} placeholder="Select country" error={e('country') ? 'Required' : ''} />
      </div>
    </>;
  }
  return <>
    <Field label="Street address" value={a.street} onChange={v => setA({ street: v })} placeholder="123 Main Street" error={t && !a.street.trim() ? 'Required' : ''} />
    <Field label="Apartment / unit number" optional value={a.unit} onChange={v => setA({ unit: v })} placeholder="Unit 4B" />
    <ZipField value={a.zip} onChange={v => setA({ zip: cbDigits(v).slice(0, 5) })} onFill={applyZipFill}
      error={t && !/^\d{5}$/.test(cbDigits(a.zip)) ? 'Enter a 5-digit ZIP' : ''} />
    <div className="field-row">
      <Field label="City" value={a.city} onChange={v => setA({ city: v })} placeholder="San Mateo" error={t && !a.city.trim() ? 'Required' : ''} />
      <Select label="State" value={a.state} onChange={v => setA({ state: v })} options={CB_STATES} placeholder="State" error={t && !a.state ? 'Required' : ''} />
    </div>
  </>;
}
function cbAddrValid(a) {
  if (a.intl) return a.street.trim() && a.city.trim() && a.province.trim() && a.postal.trim() && a.country;
  return a.street.trim() && a.city.trim() && a.state && /^\d{5}$/.test(cbDigits(a.zip));
}
function cbAddrSummary(a) {
  if (a.intl) return `${a.street}${a.unit ? ', ' + a.unit : ''}\n${[a.city, a.province].filter(Boolean).join(', ')} ${a.postal}\n${a.country}`;
  return `${a.street}${a.unit ? ', ' + a.unit : ''}\n${[a.city, a.state].filter(Boolean).join(', ')} ${a.zip}`;
}

/* ---- per-step validity ---- */
function cbStepValid(step, d) {
  switch (step) {
    case 'name': return d.name.first.trim() && d.name.last.trim() && (d.name.suffix !== 'Other' || d.name.suffixOther.trim());
    case 'contact': return cbEmailOk(d.email) && cbPhoneOk(d.phone);
    case 'personal': return d.citizenship && d.dob;
    case 'marital': return d.marital && (d.marital !== 'Married' || d.marriedToBorrower);
    case 'military':
      if (!d.milService) return false;
      if (d.milService === 'active') return d.milBranch && (d.milBranch !== 'Other' || d.milBranchOther.trim());
      return true;
    case 'address': return d.sharedAddress || cbAddrValid(d.curAddr);
    // Renters must provide monthly rent (URLA parity); Own and Living Rent
    // Free have no follow-ups by design.
    case 'housing': return !!d.housing && (d.housing !== 'Rent' || d.rent !== '');
    // Empty means 0 (older drafts started blank); 0 yr 0 mo is always valid.
    case 'time': return true;
    case 'credit': return !!d.credit;
    default: return true;
  }
}

/* ===================================================================== */
function CoBorrowerFlow({ initial, primaryName, primaryAddr, onCancel, onSave, onProgress }) {
  const [data, setData] = useCB(initial ? { ...CB_DEFAULT, ...initial, touched: false } : CB_DEFAULT);
  const enteredEditing = !!initial;
  const [step, setStep] = useCB(initial ? 'review' : 'name');
  const [editReturn, setEditReturn] = useCB(false);

  const set = patch => setData(d => ({ ...d, ...patch }));
  const setName = patch => set({ name: { ...data.name, ...patch } });
  const setCur = patch => set({ curAddr: { ...data.curAddr, ...patch } });
  const setMail = patch => set({ mailAddr: { ...data.mailAddr, ...patch } });
  const setTime = patch => set({ timeAt: { ...data.timeAt, ...patch } });
  const t = data.touched;

  const flowTop = () => { const el = document.querySelector('.flow'); if (el) el.scrollTop = 0; };
  function goTo(key) { setData(d => ({ ...d, touched: false })); setStep(key); flowTop(); }
  function next() {
    if (!cbStepValid(step, data)) { set({ touched: true }); return; }
    if (editReturn) { setEditReturn(false); return goTo('review'); }
    const i = CB_STEPS.indexOf(step);
    goTo(CB_STEPS[i + 1]);
  }
  function back() {
    if (editReturn) { setEditReturn(false); return goTo('review'); }
    if (step === 'name') return onCancel();
    const i = CB_STEPS.indexOf(step);
    goTo(CB_STEPS[i - 1]);
  }
  function edit(key) { setEditReturn(true); goTo(key); }

  const di = CB_STEPS.indexOf(step);
  const fill = Math.round((di / (CB_STEPS.length - 1)) * 100);
  useCBE(() => { onProgress && onProgress({ fill, stepTitle: 'co-' + step }); }, [step, fill]);

  const who = data.name.first.trim() || 'the co-borrower';
  const whoP = data.name.first.trim() ? `${data.name.first}'s` : "the co-borrower's";
  const nextLabel = editReturn ? 'Save changes' : 'Next';
  const ynErr = v => t && !v ? 'Please select an option' : '';
  const eyebrow = 'ADD CO-BORROWER';

  let body = null;

  if (step === 'name') {
    body = <>
      <StepHead eyebrow={eyebrow} title="What is the co-borrower's name?" sub="Enter their legal name as it appears on their government ID." />
      <div className="field-row">
        <Field label="First name" value={data.name.first} onChange={v => setName({ first: v })} placeholder="Sarah" error={t && !data.name.first.trim() ? 'Required' : ''} />
        <Field label="Middle name" optional value={data.name.middle} onChange={v => setName({ middle: v })} placeholder="M." />
      </div>
      <div className="field-row">
        <Field label="Last name" value={data.name.last} onChange={v => setName({ last: v })} placeholder="Haddad" error={t && !data.name.last.trim() ? 'Required' : ''} />
        <Select label="Suffix" optional value={data.name.suffix} onChange={v => setName({ suffix: v })} options={CB_SUFFIXES} placeholder="None" />
      </div>
      {data.name.suffix === 'Other' &&
        <Field label="Enter suffix" value={data.name.suffixOther} onChange={v => setName({ suffixOther: v })} placeholder="Their suffix" error={t && !data.name.suffixOther.trim() ? 'Required' : ''} />}
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} backLabel={editReturn ? 'Back' : 'Cancel'} />
    </>;
  }

  else if (step === 'contact') {
    const errEmail = t && data.email && !cbEmailOk(data.email) ? 'Enter a valid email' : (t && !data.email ? 'Required' : '');
    const errPhone = t && data.phone && !cbPhoneOk(data.phone) ? 'Enter a valid phone number' : (t && !data.phone ? 'Required' : '');
    body = <>
      <StepHead eyebrow={eyebrow} title={`What are ${whoP} contact details?`} sub="We'll use these to keep them informed about the application." />
      <Field label="Email address" type="email" inputMode="email" value={data.email} onChange={v => set({ email: v })} placeholder="sarah@email.com" error={errEmail} />
      <Field label="Phone number" inputMode="tel" value={data.phone} onChange={v => set({ phone: cbFmtPhone(v) })} placeholder="(555) 555-0123" error={errPhone} />
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} />
    </>;
  }

  else if (step === 'personal') {
    body = <>
      <StepHead eyebrow={eyebrow} title={`Tell us a little bit more about ${who}`} sub="We just need their citizenship status and date of birth." />
      <Select label="Citizenship" value={data.citizenship} onChange={v => set({ citizenship: v })} options={CB_CITIZENSHIP.map(c => c.value)} placeholder="Select citizenship status" error={t && !data.citizenship ? 'Required' : ''} />
      <Field label="Date of birth" type="date" value={data.dob} onChange={v => set({ dob: v })} error={t && !data.dob ? 'Required' : ''} />
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} />
    </>;
  }

  else if (step === 'marital') {
    const isMarried = data.marital === 'Married';
    body = <>
      <StepHead eyebrow={eyebrow} title={`What is ${whoP} marital status?`} />
      <div className="opt-list">
        {CB_MARITAL.map(m => (
          <Opt key={m.value} title={m.value} sub={m.sub}
            selected={data.marital === m.value}
            onClick={() => set({ marital: m.value, marriedToBorrower: m.value === 'Married' ? data.marriedToBorrower : null })} />
        ))}
      </div>
      {isMarried && <div className="step" style={{ marginTop: 22 }}>
        <p className="bi-q">Is {who} married to {primaryName || 'the borrower on this loan'}?</p>
        <div className="bi-yesno">
          <Opt icon={I.yes(20)} title="Yes" twoUp selected={data.marriedToBorrower === 'yes'} onClick={() => set({ marriedToBorrower: 'yes' })} />
          <Opt icon={I.no(18)} title="No" twoUp selected={data.marriedToBorrower === 'no'} onClick={() => set({ marriedToBorrower: 'no' })} />
        </div>
        {ynErr(data.marriedToBorrower) && <div className="field-err" style={{ marginTop: -6 }}>{ynErr(data.marriedToBorrower)}</div>}
      </div>}
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} nextDisabled={!data.marital} />
    </>;
  }

  else if (step === 'military') {
    const isActive = data.milService === 'active';
    body = <>
      <StepHead eyebrow={eyebrow} title={`Does ${who} have any military service status?`} />
      <div className="opt-list">
        {CB_MIL.map(m => (
          <Opt key={m.value} icon={m.value === 'none' ? I.no(20) : I.yes(20)} title={m.title}
            selected={data.milService === m.value} onClick={() => set({ milService: m.value })} />
        ))}
      </div>
      {isActive && <div className="step" style={{ marginTop: 20 }}>
        <Select label="Military branch" value={data.milBranch} onChange={v => set({ milBranch: v })} options={CB_BRANCH} placeholder="Select branch" error={t && !data.milBranch ? 'Required' : ''} />
        {data.milBranch === 'Other' &&
          <Field label="Enter branch or service type" value={data.milBranchOther} onChange={v => set({ milBranchOther: v })} placeholder="Their branch" error={t && !data.milBranchOther.trim() ? 'Required' : ''} />}
      </div>}
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} nextDisabled={!data.milService} />
    </>;
  }

  else if (step === 'address') {
    const shared = data.sharedAddress;
    body = <>
      <StepHead eyebrow={eyebrow} title={`What is the address where ${who} currently lives?`} />
      <div className="bi-inline-check">
        <CheckRow checked={shared} onToggle={() => set({ sharedAddress: !shared })}>
          {who} shares the same address as {primaryName || 'the borrower'}.
        </CheckRow>
      </div>
      {shared
        ? <div className="sum-card" style={{ marginBottom: 4 }}>
            <div className="sum-label">Address</div>
            <div className="sum-value" style={{ whiteSpace: 'pre-line' }}>{primaryAddr ? cbAddrSummary(primaryAddr) : '—'}</div>
          </div>
        : <>
            <div className="bi-inline-check">
              <CheckRow checked={data.curAddr.intl} onToggle={() => setCur({ intl: !data.curAddr.intl })}>
                This address is outside of the U.S.
              </CheckRow>
            </div>
            <CBAddress a={data.curAddr} setA={setCur} t={t} />
            <div className="bi-inline-check" style={{ marginTop: 4 }}>
              <CheckRow checked={data.mailingSame} onToggle={() => set({ mailingSame: !data.mailingSame })}>
                Mailing address is the same as the current address above.
              </CheckRow>
            </div>
            {!data.mailingSame && <div className="step">
              <div className="bi-inline-check">
                <CheckRow checked={data.mailAddr.intl} onToggle={() => setMail({ intl: !data.mailAddr.intl })}>
                  This mailing address is outside of the U.S.
                </CheckRow>
              </div>
              <CBAddress a={data.mailAddr} setA={setMail} t={t} />
            </div>}
          </>}
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} />
    </>;
  }

  else if (step === 'housing') {
    body = <>
      <StepHead eyebrow={eyebrow} title={`Does ${who} rent or own where they currently live?`} />
      <div className="opt-list">
        {CB_HOUSING.map(h => (
          <Opt key={h.value} icon={h.icon()} title={h.value} sub={h.sub}
            selected={data.housing === h.value} onClick={() => set({ housing: h.value })} />
        ))}
      </div>
      {/* Renter-specific follow-up: only rent needs a dollar amount. */}
      {data.housing === 'Rent' && (
        <div className="step-anim" style={{ marginTop: 14 }}>
          <Field label="Monthly rent" prefix="$" inputMode="numeric" value={data.rent}
            onChange={v => set({ rent: cbMoney(v) })} placeholder="1,800" />
        </div>
      )}
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} nextDisabled={!cbStepValid('housing', data)} />
    </>;
  }

  else if (step === 'time') {
    body = <>
      <StepHead eyebrow={eyebrow} title={`How long has ${who} lived at their current address?`} />
      <div className="field-row">
        <Field label="Years" inputMode="numeric" value={data.timeAt.years}
          onChange={v => setTime({ years: cbDigits(v).slice(0, 2) })} placeholder="0" />
        <Select label="Months" value={data.timeAt.months} onChange={v => setTime({ months: v })} options={CB_MONTHS} placeholder="0" />
      </div>
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} />
    </>;
  }

  else if (step === 'credit') {
    body = <>
      <StepHead eyebrow={eyebrow} title={`What is ${whoP} estimated credit score range?`}
        sub="Credit is only one part of the mortgage process. If it isn't perfect, that doesn't automatically mean there are no options." />
      <div className="opt-list">
        {CB_CREDIT.map(c => (
          <Opt key={c.value} title={c.title} sub={c.sub}
            selected={data.credit === c.value} onClick={() => set({ credit: c.value })} />
        ))}
      </div>
      <Helper label="Why is credit important?" items={[
        { t: 'Credit is one part of the picture', d: 'Credit helps lenders understand borrowing history and may impact loan options, interest rate, and required down payment.' },
        { t: "It's not the only thing that matters", d: 'Income, assets, property type, loan program, and overall financial profile are also reviewed.' },
      ]} />
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} nextDisabled={!data.credit} />
    </>;
  }

  else if (step === 'review') {
    const nm = `${data.name.first}${data.name.middle ? ' ' + data.name.middle : ''} ${data.name.last}${data.name.suffix ? ' ' + (data.name.suffix === 'Other' ? data.name.suffixOther : data.name.suffix) : ''}`;
    const maritalVal = data.marital === 'Married'
      ? `Married\nMarried to ${primaryName || 'the borrower'}: ${data.marriedToBorrower === 'yes' ? 'Yes' : 'No'}`
      : (data.marital || '—');
    const milVal = data.milService === 'active'
      ? `Active Duty\n${data.milBranch === 'Other' ? data.milBranchOther : data.milBranch}`
      : (CB_MIL_LABEL[data.milService] || '—');
    const addrVal = data.sharedAddress
      ? `Shared with ${primaryName || 'the borrower'}\n${primaryAddr ? cbAddrSummary(primaryAddr) : ''}`
      : cbAddrSummary(data.curAddr);
    const mailVal = data.sharedAddress || data.mailingSame ? 'Same as current address' : cbAddrSummary(data.mailAddr);
    const rows = [
      { key: 'name', label: 'Name', value: nm },
      { key: 'contact', label: 'Contact Details', value: `${data.email}\n${data.phone}` },
      { key: 'personal', label: 'Personal Details', value: `${data.citizenship}\n${cbFmtDob(data.dob)}`, mono: false },
      { key: 'marital', label: 'Marital Status', value: maritalVal },
      { key: 'military', label: 'Military Service', value: milVal },
      { key: 'address', label: 'Current Address', value: addrVal },
      { key: 'address', label: 'Mailing Address', value: mailVal, alt: 'mail' },
      { key: 'housing', label: 'Housing Type', value: data.housing === 'Rent' && data.rent ? `Rent · $${data.rent}/mo` : (data.housing || '—') },
      { key: 'time', label: 'Time at Address', value: `${data.timeAt.years || '0'} yr ${data.timeAt.months || '0'} mo` },
      { key: 'credit', label: 'Credit Score Range', value: CB_CREDIT_LABEL[data.credit] || '—' },
    ];
    body = <>
      <StepHead eyebrow={eyebrow} title={`Review ${whoP} information`}
        sub="Make sure everything looks right. You can edit any answer before adding them to the loan." />
      <div className="summary">
        {rows.map((s, i) => (
          <div className="sum-card" key={s.label + i}>
            <div className="sum-head">
              <div style={{ flex: 1 }}>
                <div className="sum-label">{s.label}</div>
                <div className="sum-value" style={{ whiteSpace: 'pre-line' }}>{s.value}</div>
              </div>
              <button className="sum-edit" onClick={() => edit(s.key)}>{I.pencil(13)}Edit</button>
            </div>
          </div>
        ))}
      </div>
      <NavFooter onBack={enteredEditing ? onCancel : back} onNext={() => onSave(data)} nextLabel="Confirm and Continue" backLabel={enteredEditing ? 'Cancel' : 'Back'} />
    </>;
  }

  return (
    <main className="flow">
      <div className="flow-col">
        <div className="step step-anim" key={step}>{body}</div>
      </div>
    </main>
  );
}

window.CoBorrowerFlow = CoBorrowerFlow;
window.cbAddrSummary = cbAddrSummary;
window.CB_CREDIT_LABEL = CB_CREDIT_LABEL;
