/* global React, BrainMark, I, Progress, StepHead, Opt, Field, CheckRow, NavFooter, Helper, HelpLink, ZipField */
const { useState: usePF, useEffect: usePFE } = React;

/* ---------------- helpers ---------------- */
const onlyDigits = s => (s || '').replace(/[^\d]/g, '');
const money = s => { const d = onlyDigits(s); return d ? Number(d).toLocaleString('en-US') : ''; };
const toNum = s => Number(onlyDigits(s)) || 0;
const emailOk = e => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);
const phoneOk = p => onlyDigits(p).length === 10;
const fmtPhone = s => {
  const d = onlyDigits(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 '';
};

/* ordered steps + which belong to the "Purchase Details" section */
const STEPS = ['app-start', 'agreements', 'agent-q', 'agent-info', 'buying', 'address', 'use', 'type', 'price', 'review'];
const SECTION_STEPS = ['agent-q', 'agent-info', 'buying', 'address', 'use', 'type', 'price'];
const PRE_APP = ['app-start', 'agreements'];

const BUYING = { 'very-early': 'Very early', 'signed': "I've signed a purchase contract", 'asap': 'As soon as possible' };
const USE = { primary: 'Primary Residence', second: 'Second Home', investment: 'Investment Property' };
const PTYPE = { single: 'Single-Family Home', condo: 'Condo', multi: 'Multi-Family Home (2 to 4 Units)', manufactured: 'Manufactured Home', coop: 'Co-op' };

function emptyPurchaseData() {
  return {
    profile: {
      name: '',
      dob: '',
      current: '',
      mailingSame: false,
    },
    agree: { electronic: false, privacy: false, origination: false },
    hasAgent: null,
    agent: { first: '', last: '', email: '', phone: '' },
    buying: null,
    addr: { street: '', unit: '', city: '', state: '', zip: '', noAddr: false },
    use: null,
    ptype: null,
    price: '', dpPct: '', dpAmt: '',
    taxes: '', insurance: '', hoa: '', noHoa: false,
    touched: false,
  };
}

const LS = 'bevri_purchase_v1';

function loadSavedPurchase() {
  try {
    return JSON.parse(localStorage.getItem(LS));
  } catch { return null; }
}

/* ===================================================================== */
function PurchaseFlow({ onExit, onContinue, onProgress }) {
  const saved = loadSavedPurchase();
  const emptyData = emptyPurchaseData();
  const savedData = saved?.data ? { ...emptyData, ...saved.data, profile: { ...emptyData.profile, ...(saved.data.profile || {}) }, touched: false } : null;
  // Resume at the saved step; the retired 'review-info' profile card maps to
  // 'app-start' so legacy saved sessions don't land on a removed step.
  // Borrower identity (name, DOB, addresses) is collected and edited in the
  // Borrower Info section, which has a working review/edit summary.
  const initialPurchaseStep = savedData && saved?.step && saved.step !== 'review-info' ? saved.step : 'app-start';
  const [step, setStep] = usePF(initialPurchaseStep);
  const [data, setData] = usePF(savedData || emptyData);
  const [editReturn, setEditReturn] = usePF(false);
  const [showAgentErr, setShowAgentErr] = usePF(false);

  usePFE(() => {
    try { localStorage.setItem(LS, JSON.stringify({ step, data })); } catch {}
  }, [step, data]);
  usePFE(() => {
    function onAutoFill(e) {
      if (!(e.detail?.posKeys || []).includes(LS)) return;
      const updated = loadSavedPurchase();
      if (updated?.data) setData(d => {
        const merged = { ...d, ...updated.data, addr: { ...d.addr, ...updated.data.addr } };
        // A chat/document-provided street supersedes an earlier "I don't
        // have an address yet"; otherwise both states show at once.
        if (updated.data.addr?.street) merged.addr = { ...merged.addr, noAddr: false };
        return merged;
      });
    }
    window.addEventListener('bevri:fields-autofilled', onAutoFill);
    return () => window.removeEventListener('bevri:fields-autofilled', onAutoFill);
  }, []);

  const set = patch => setData(d => ({ ...d, ...patch }));
  const flowTop = () => { const el = document.querySelector('.flow'); if (el) el.scrollTop = 0; };

  // ZIP-first autofill for the subject-property address. Functional updater
  // reads the live draft, so an in-flight lookup can never clobber a value
  // the borrower typed meanwhile; a re-fill only replaces our previous fill.
  const zipFillRef = React.useRef({ city: '', state: '' });
  const applyZipFill = hit => setData(d => {
    const a = d.addr;
    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; }
    return Object.keys(patch).length ? { ...d, addr: { ...a, ...patch } } : d;
  });

  function goTo(key) { setData(d => ({ ...d, touched: false })); setStep(key); flowTop(); }

  // Consent is normally collected by the AgreementsGate before Borrower Info
  // (borrower-first order); the in-flow step remains only for legacy drafts
  // that predate the gate and is skipped once consent exists.
  const pfAgreed = d => Boolean(d.agree && d.agree.electronic && d.agree.privacy && d.agree.origination);

  function next() {
    if (editReturn) { setEditReturn(false); return goTo('review'); }
    if (step === 'agent-q') return goTo(data.hasAgent === 'yes' ? 'agent-info' : 'buying');
    const i = STEPS.indexOf(step);
    let n = STEPS[i + 1];
    if (n === 'agreements' && pfAgreed(data)) n = 'agent-q';
    if (n === 'agent-info' && data.hasAgent !== 'yes') n = 'buying';
    goTo(n);
  }
  function back() {
    if (editReturn) { setEditReturn(false); return goTo('review'); }
    if (step === 'app-start') return onExit();
    if (step === 'buying') return goTo(data.hasAgent === 'yes' ? 'agent-info' : 'agent-q');
    const i = STEPS.indexOf(step);
    let p = STEPS[i - 1];
    if (p === 'agent-info' && data.hasAgent !== 'yes') p = 'agent-q';
    if (p === 'agreements' && pfAgreed(data)) p = 'app-start';
    goTo(p);
  }
  function edit(key) { setEditReturn(true); goTo(key); }

  // progress (reported up to the shell rail)
  const allSteps = STEPS;
  const di = allSteps.indexOf(step);
  const fill = di >= 0 ? Math.round((di / (allSteps.length - 1)) * 100) : 0;
  usePFE(() => { onProgress && onProgress({ fill, stepTitle: step }); }, [step, fill]);

  const nextLabel = editReturn ? 'Save changes' : 'Next';

  // -------- per-step content --------
  let body = null;

  if (step === 'agreements') {
    const a = data.agree;
    const all = a.electronic && a.privacy && a.origination;
    const tgl = k => setData(d => ({ ...d, agree: { ...d.agree, [k]: !d.agree[k] } }));
    body = <>
      <StepHead title="Let's get started"
        sub="Please review and agree to the following before we continue. Tap a title to read the full document." />
      <div className="sum-card">
        <div className="agree-list">
          <CheckRow checked={a.electronic} onToggle={() => tgl('electronic')}>
            I have read and agree to the <a className="agree-link" href="/terms" target="_blank" rel="noopener noreferrer" onClick={e => e.stopPropagation()}>Electronic Communication Agreement</a>.
          </CheckRow>
          <CheckRow checked={a.privacy} onToggle={() => tgl('privacy')}>
            I have read and agree to Bevri's <a className="agree-link" href="/privacy" target="_blank" rel="noopener noreferrer" onClick={e => e.stopPropagation()}>Privacy Policy</a>.
          </CheckRow>
          <CheckRow checked={a.origination} onToggle={() => tgl('origination')}>
            I have read and agree to Bevri's <a className="agree-link" href="/terms" target="_blank" rel="noopener noreferrer" onClick={e => e.stopPropagation()}>Mortgage Loan Origination Agreement</a>.
          </CheckRow>
        </div>
      </div>
      <NavFooter onBack={back} onNext={next} nextLabel="Confirm and Continue" nextDisabled={!all} />
    </>;
  }

  else if (step === 'app-start') {
    body = <>
      <div className="start-card">
        <div className="start-burst">{I.checkDark(34)}</div>
        <h1 className="step-title" style={{ fontSize: 28 }}>Your application is off to a great start</h1>
        <p className="step-sub" style={{ marginTop: 14 }}>
          Please continue providing your purchase details so we can further evaluate your loan options.
        </p>
        <button className="start-cta" onClick={next}>
          <span className="opt-icon">{I.home(24)}</span>
          <span className="start-cta-text">
            <span className="start-cta-title">Add Purchase Details</span>
            <span className="start-cta-sub">About 2 minutes · 7 quick questions</span>
          </span>
          <span style={{ color: 'var(--sage)' }}>{I.arrow(18)}</span>
        </button>
      </div>
      <div className="step-nav">
        <button className="btn btn-secondary btn-block" onClick={back}>{I.back(16)}Back</button>
      </div>
    </>;
  }

  else if (step === 'agent-q') {
    body = <>
      <StepHead title="Are you working with a real estate agent?"
        sub="If you already have an agent helping with your home search, we'll keep them in the loop." />
      <div className="opt-list two-up">
        <Opt icon={I.yes(24)} title="Yes" twoUp selected={data.hasAgent === 'yes'} onClick={() => set({ hasAgent: 'yes' })} />
        <Opt icon={I.no(22)} title="No" twoUp selected={data.hasAgent === 'no'} onClick={() => set({ hasAgent: 'no' })} />
      </div>
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} nextDisabled={!data.hasAgent} />
    </>;
  }

  else if (step === 'agent-info') {
    const g = data.agent;
    const setG = patch => set({ agent: { ...g, ...patch } });
    const t = data.touched;
    const errFirst = t && !g.first.trim() ? 'Required' : '';
    const errLast = t && !g.last.trim() ? 'Required' : '';
    const errEmail = t && g.email && !emailOk(g.email) ? 'Enter a valid email' : (t && !g.email ? 'Required' : '');
    const errPhone = t && g.phone && !phoneOk(g.phone) ? 'Enter a valid phone number' : (t && !g.phone ? 'Required' : '');
    const valid = g.first.trim() && g.last.trim() && emailOk(g.email) && phoneOk(g.phone);
    const onNext = () => { if (!valid) { set({ touched: true }); return; } next(); };
    body = <>
      <StepHead title="Tell us about your real estate agent"
        sub="We'll use this to coordinate paperwork and closing details." />
      <div className="field-row">
        <Field label="First name" value={g.first} onChange={v => setG({ first: v })} placeholder="Jane" error={errFirst} />
        <Field label="Last name" value={g.last} onChange={v => setG({ last: v })} placeholder="Doe" error={errLast} />
      </div>
      <Field label="Email address" type="email" inputMode="email" value={g.email} onChange={v => setG({ email: v })} placeholder="jane@realty.com" error={errEmail} />
      <Field label="Phone number" inputMode="tel" value={g.phone} onChange={v => setG({ phone: fmtPhone(v) })} placeholder="(555) 555-0123" error={errPhone} />
      <NavFooter onBack={back} onNext={onNext} nextLabel={nextLabel} />
    </>;
  }

  else if (step === 'buying') {
    body = <>
      <StepHead title="Where are you in the home buying process?"
        sub="This helps us prioritize the right next steps for you." />
      <div className="opt-list">
        <Opt icon={I.seedling(24)} title="Very early" sub="I'm just starting and not ready to make a move yet." selected={data.buying === 'very-early'} onClick={() => set({ buying: 'very-early' })} />
        <Opt icon={I.doc(22)} title="I've signed a purchase contract" sub="I already have a signed agreement on a property." selected={data.buying === 'signed'} onClick={() => set({ buying: 'signed' })} />
        <Opt icon={I.rocket(22)} title="As soon as possible" sub="I need a pre-approval so I can start making offers." selected={data.buying === 'asap'} onClick={() => set({ buying: 'asap' })} />
      </div>
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} nextDisabled={!data.buying} />
    </>;
  }

  else if (step === 'address') {
    const ad = data.addr;
    const setA = patch => set({ addr: { ...ad, ...patch } });
    const t = data.touched;
    const needStreet = !ad.noAddr;
    const errStreet = t && needStreet && !ad.street.trim() ? 'Required' : '';
    const errCity = t && !ad.city.trim() ? 'Required' : '';
    const errState = t && !ad.state.trim() ? 'Required' : '';
    const errZip = t && !/^\d{5}$/.test(onlyDigits(ad.zip)) ? 'Enter a 5-digit ZIP' : '';
    const valid = (!needStreet || ad.street.trim()) && ad.city.trim() && ad.state.trim() && /^\d{5}$/.test(onlyDigits(ad.zip));
    const onNext = () => { if (!valid) { set({ touched: true }); return; } next(); };
    body = <>
      <StepHead title="What's the address of the property you're looking to buy?"
        sub="Don't have one picked out yet? No problem. Just tell us where you're searching." />
      {!ad.noAddr && <>
        <Field label="Street address" value={ad.street} onChange={v => setA({ street: v })} placeholder="123 Main Street" error={errStreet} />
        <Field label="Apartment / unit number" optional value={ad.unit} onChange={v => setA({ unit: v })} placeholder="Unit 4B" />
      </>}
      <ZipField value={ad.zip} onChange={v => setA({ zip: onlyDigits(v).slice(0, 5) })} onFill={applyZipFill} error={errZip} />
      <div className="field-row">
        <Field label="City" value={ad.city} onChange={v => setA({ city: v })} placeholder="San Mateo" error={errCity} />
        <Field label="State" value={ad.state} onChange={v => setA({ state: v.toUpperCase().slice(0, 2) })} placeholder="CA" error={errState} />
      </div>
      <CheckRow checked={ad.noAddr} onToggle={() => setA({ noAddr: !ad.noAddr, street: '', unit: '' })}>
        I don't have a property address yet
      </CheckRow>
      <NavFooter onBack={back} onNext={onNext} nextLabel={nextLabel} />
    </>;
  }

  else if (step === 'use') {
    body = <>
      <StepHead title="How do you intend to use this property?" />
      <div className="opt-list">
        <Opt icon={I.home(24)} title="Primary Residence" sub="A home you plan to live in most of the year." selected={data.use === 'primary'} onClick={() => set({ use: 'primary' })} />
        <Opt icon={I.building(22)} title="Second Home" sub="A home you'll use personally, but not as your main residence." selected={data.use === 'second'} onClick={() => set({ use: 'second' })} />
        <Opt icon={I.invest(22)} title="Investment Property" sub="A property you plan to rent out or use to generate income." selected={data.use === 'investment'} onClick={() => set({ use: 'investment' })} />
      </div>
      <Helper items={[
        { t: 'Primary residence', d: 'This will be your main home, where you live most of the year.' },
        { t: 'Second home', d: "You'll use it personally (like a vacation home), but live somewhere else most of the year." },
        { t: 'Investment property', d: 'You intend to rent it out or use it to generate income.' },
      ]} />
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} nextDisabled={!data.use} />
    </>;
  }

  else if (step === 'type') {
    body = <>
      <StepHead title="What type of property are you looking for?" />
      <div className="opt-list">
        <Opt icon={I.home(24)} title="Single-Family Home" selected={data.ptype === 'single'} onClick={() => set({ ptype: 'single' })} />
        <Opt icon={I.condo(22)} title="Condo" selected={data.ptype === 'condo'} onClick={() => set({ ptype: 'condo' })} />
        <Opt icon={I.units(22)} title="Multi-Family Home" sub="2 to 4 units" selected={data.ptype === 'multi'} onClick={() => set({ ptype: 'multi' })} />
        <Opt icon={I.factory(22)} title="Manufactured Home" selected={data.ptype === 'manufactured'} onClick={() => set({ ptype: 'manufactured' })} />
        <Opt icon={I.coop(22)} title="Co-op" selected={data.ptype === 'coop'} onClick={() => set({ ptype: 'coop' })} />
      </div>
      <Helper items={[
        { t: 'Single-family home', d: 'A standalone home for one household.' },
        { t: 'Condo', d: 'A unit in a building or community where some areas may be shared.' },
        { t: 'Multi-family home', d: 'A property with 2 to 4 separate living units.' },
        { t: 'Manufactured home', d: 'A factory-built home placed on land or in a community.' },
        { t: 'Co-op', d: 'You own shares in a building or association rather than owning the unit directly.' },
      ]} />
      <NavFooter onBack={back} onNext={next} nextLabel={nextLabel} nextDisabled={!data.ptype} />
    </>;
  }

  else if (step === 'price') {
    const t = data.touched;
    const price = toNum(data.price);
    const amt = toNum(data.dpAmt);
    const pct = Number(data.dpPct) || 0;
    const onPrice = v => {
      const np = toNum(v);
      let patch = { price: money(v) };
      if (pct > 0) patch.dpAmt = np ? money(String(Math.round(np * pct / 100))) : '';
      set(patch);
    };
    const onPct = v => {
      const p = Math.min(100, Number(v.replace(/[^\d.]/g, '')) || 0);
      set({ dpPct: v === '' ? '' : String(p), dpAmt: price ? money(String(Math.round(price * p / 100))) : data.dpAmt });
    };
    const onAmt = v => {
      const a = toNum(v);
      set({ dpAmt: money(v), dpPct: price ? String(Math.round((a / price) * 1000) / 10) : data.dpPct });
    };
    const errPrice = t && !price ? 'Enter your target home price' : '';
    const errDp = t && !amt && !pct ? 'Enter a down payment' : (amt > price && price ? 'Cannot exceed home price' : (pct > 100 ? 'Cannot exceed 100%' : ''));
    const valid = price > 0 && (amt > 0 || pct > 0) && amt <= price && pct <= 100;
    const onNext = () => { if (!valid) { set({ touched: true }); return; } next(); };
    body = <>
      <StepHead title="What are your target home price and down payment?"
        sub="Estimates are fine. You can refine these later." />
      <Field label="Target home price" prefix="$" inputMode="numeric" value={data.price} onChange={onPrice} placeholder="400,000" error={errPrice} />
      <div className="dp-grid">
        <Field label="Down payment %" suffix="%" inputMode="decimal" value={data.dpPct} onChange={onPct} placeholder="5" />
        <div className="dp-eq">=</div>
        <Field label="Down payment amount" prefix="$" inputMode="numeric" value={data.dpAmt} onChange={onAmt} placeholder="20,000" />
      </div>
      {errDp && <div className="field-err" style={{ marginTop: -6 }}>{errDp}</div>}
      <div className="step" style={{ marginTop: 18 }}>
        <StepHead title="Estimated monthly housing expenses" sub="Optional estimates help calculate payment and DTI more accurately." />
        <Field label="Annual property taxes" optional prefix="$" inputMode="numeric" value={data.taxes} onChange={v => set({ taxes: money(v) })} placeholder="5,000" />
        <Field label="Annual homeowners insurance" optional prefix="$" inputMode="numeric" value={data.insurance} onChange={v => set({ insurance: money(v) })} placeholder="1,500" />
        <Field label="Monthly HOA dues" optional prefix="$" inputMode="numeric" value={data.noHoa ? '0' : data.hoa} onChange={v => set({ hoa: money(v), noHoa: false })} placeholder="250" />
        <CheckRow checked={data.noHoa} onToggle={() => set({ noHoa: !data.noHoa, hoa: !data.noHoa ? '' : data.hoa })}>This property does not have HOA dues.</CheckRow>
        <HelpLink q="What is DTI?"
          a="Debt-to-income ratio, or DTI, compares your monthly debt payments with your gross monthly income. Lenders use it to help determine how much you may be able to afford." />
      </div>
      <div style={{ marginTop: 18 }}>
        <HelpLink q="What if I'm not sure about my target home price?"
          a="Enter your best estimate. You can update this anytime as your search narrows. It won't lock you into anything." />
        <HelpLink q="How much money will I need to put down?"
          a="Your down payment depends on your loan program, credit profile, and purchase price. Some options allow lower down payments, while others may require more. We'll help you find the right fit." />
      </div>
      <NavFooter onBack={back} onNext={onNext} nextLabel={nextLabel} />
    </>;
  }

  else if (step === 'review') {
    const ad = data.addr;
    const addrVal = ad.noAddr
      ? <span><span className="muted">No property address yet</span>{(ad.city || ad.state || ad.zip) ? `\n${[ad.city, ad.state].filter(Boolean).join(', ')} ${ad.zip}` : ''}</span>
      : `${ad.street}${ad.unit ? ', ' + ad.unit : ''}\n${[ad.city, ad.state].filter(Boolean).join(', ')} ${ad.zip}`;
    const sections = [
      { key: 'agent-q', label: 'Real Estate Agent', q: 'Are you working with a real estate agent?',
        value: data.hasAgent === 'yes'
          ? `Yes\n${data.agent.first} ${data.agent.last}\n${data.agent.email}\n${data.agent.phone}`
          : 'No' },
      { key: 'buying', label: 'Home Buying Process', q: 'Where are you in the home buying process?', value: BUYING[data.buying] || '—' },
      { key: 'address', label: 'Property Address', q: "The property you're looking to buy", value: addrVal },
      { key: 'use', label: 'Property Use', q: 'How you intend to use the property', value: USE[data.use] || '—' },
      { key: 'type', label: 'Property Type', q: 'What type of property', value: PTYPE[data.ptype] || '—' },
      { key: 'price', label: 'Price & Down Payment', q: 'Target price and down payment',
        value: `$${data.price || '0'} home price\n$${data.dpAmt || '0'} down${data.dpPct ? ` · ${data.dpPct}%` : ''}` },
      { key: 'price', label: 'Taxes / Insurance / HOA', q: 'Estimated housing expenses', value: [`Taxes $${data.taxes || '0'}/yr`, `Insurance $${data.insurance || '0'}/yr`, data.noHoa ? 'No HOA' : `HOA $${data.hoa || '0'}/mo`].join('\n') },
    ];
    body = <>
      <StepHead title="Review your purchase details"
        sub="Make sure everything looks right. You can edit any answer before we continue." />
      <div className="summary">
        {sections.map(s => (
          <div className="sum-card" key={s.key}>
            <div className="sum-head">
              <div style={{ flex: 1 }}>
                <div className="sum-label">{s.label}</div>
                <div className="sum-q">{s.q}</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={back} onNext={() => onContinue && onContinue()} nextLabel="Confirm and Continue" />
    </>;
  }

  const pfQIdx = SECTION_STEPS.indexOf(step);

  return (
    <main className="flow">
      <div className="flow-col">
        <div className="step" key={step}>
          {pfQIdx >= 0 && (
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
              <div style={{ flex: 1, height: 3, borderRadius: 2, background: 'var(--line)' }}>
                <div style={{ height: '100%', borderRadius: 2, background: 'var(--sage)', width: `${(pfQIdx / (SECTION_STEPS.length - 1)) * 100}%`, transition: 'width .35s' }} />
              </div>
              <span style={{ fontSize: 11, fontWeight: 600, letterSpacing: '.06em', color: 'var(--muted)', whiteSpace: 'nowrap', fontFamily: 'monospace' }}>
                {pfQIdx + 1} / {SECTION_STEPS.length}
              </span>
            </div>
          )}
          <div className="step-anim" key={step}>{body}</div>
        </div>
      </div>
    </main>
  );
}

window.PurchaseFlow = PurchaseFlow;
