/* global React, I, StepHead, Field, Select, Opt, CheckRow, NavFooter, ZipField */
const { useState: useREOF } = React;

const REO_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 REO_PTYPES = ['Single-Family Home','Condo','Townhouse','Multi-Family 2 to 4 Units','Multi-Family More Than 4 Units','Co-op','Mobile Home','Commercial','Home and Business Combined','Mixed Use','Farm','Land'];
const REO_FREQ = ['Monthly','Quarterly','Semi-Annually','Annually'];
const REO_USAGE = [
  { value: 'Primary Residence', sub: 'Lived in most of the year.', icon: () => I.home(22) },
  { value: 'Second Home', sub: 'Used personally, but not the main home.', icon: () => I.building(20) },
  { value: 'Investment Property', sub: 'Rented out or used to generate income.', icon: () => I.invest(20) },
];
const REO_STATUS = [
  { value: 'Retained', sub: 'Keeping this property after closing.' },
  { value: 'Pending Sale', sub: 'Under contract or expected to sell.' },
  { value: 'Sold', sub: 'Already sold.' },
];

const reoDigits = s => (s || '').replace(/[^\d]/g, '');
const reoMoney = s => { const d = reoDigits(s); return d ? Number(d).toLocaleString('en-US') : ''; };
const reoNum = s => Number(reoDigits(s)) || 0;

const REO_PROP_DEFAULT = {
  auto: false, autoLabel: '',
  street: '', unit: '', city: '', state: '', zip: '',
  ptype: '', usage: '', rentalIncome: '',
  value: '',
  status: '',
  intendedOccupancy: '', intendedRental: '',
  taxes: '', taxesFreq: 'Annually',
  insurance: '', insuranceFreq: 'Annually',
  hoa: '', hoaFreq: 'Monthly', noHoa: false,
  otherExp: { on: false, amt: '', desc: '', freq: 'Monthly' },
};

function reoAddrLine(p) {
  const l1 = `${p.street || ''}${p.unit ? ', ' + p.unit : ''}`;
  const l2 = `${[p.city, p.state].filter(Boolean).join(', ')} ${p.zip || ''}`.trim();
  return [l1, l2].filter(Boolean).join(', ');
}

/* ===================================================================== */
function PropertyFlow({ mode = 'add', borrowerName, initial, onCancel, onSave, onProgress }) {
  const [data, setData] = useREOF(initial ? { ...REO_PROP_DEFAULT, ...initial, touched: false } : { ...REO_PROP_DEFAULT, touched: false });
  const startStep = mode === 'edit' ? 'edit-choose' : 'add-confirm';
  const [step, setStep] = useREOF(startStep);
  const [confirmAdd, setConfirmAdd] = useREOF(false);
  const set = patch => setData(d => ({ ...d, ...patch }));
  const setOther = patch => setData(d => ({ ...d, otherExp: { ...d.otherExp, ...patch } }));
  const t = data.touched;
  const who = borrowerName || 'this borrower';

  const flowTop = () => { const el = document.querySelector('.flow'); if (el) el.scrollTop = 0; };
  function goTo(key) { setData(d => ({ ...d, touched: false })); setStep(key); flowTop(); }

  const ADD_CHAIN = ['add-confirm', 'add-address', 'add-type', 'add-value', 'add-usage', 'add-status'];

  function valid(s) {
    switch (s) {
      case 'add-confirm': return confirmAdd;
      case 'add-address':
      case 'edit-details':
        return data.street.trim() && data.city.trim() && data.state && /^\d{5}$/.test(reoDigits(data.zip))
          && (s !== 'edit-details' || (data.ptype && data.usage && data.status && (data.usage !== 'Investment Property' || reoNum(data.rentalIncome) > 0)));
      case 'add-type': return !!data.ptype;
      case 'add-value': return reoNum(data.value) > 0;
      case 'add-usage': return data.usage && (data.usage !== 'Investment Property' || reoNum(data.rentalIncome) > 0);
      case 'add-status': return !!data.status;
      case 'edit-occupancy': return data.intendedOccupancy && (data.intendedOccupancy !== 'Investment Property' || reoNum(data.intendedRental) > 0);
      case 'edit-finances': return true;
      default: return true;
    }
  }

  function next() {
    if (!valid(step)) { set({ touched: true }); return; }
    if (mode === 'add') {
      const i = ADD_CHAIN.indexOf(step);
      if (i === ADD_CHAIN.length - 1) return onSave({ ...data, id: data.id || Math.random().toString(36).slice(2), auto: false });
      return goTo(ADD_CHAIN[i + 1]);
    }
    // edit
    if (step === 'edit-details') return goTo('edit-occupancy');
    if (step === 'edit-occupancy' || step === 'edit-finances') return onSave({ ...data });
  }
  function back() {
    if (mode === 'add') {
      if (step === 'add-confirm') return onCancel();
      const i = ADD_CHAIN.indexOf(step);
      return goTo(ADD_CHAIN[i - 1]);
    }
    if (step === 'edit-choose') return onCancel();
    if (step === 'edit-details') return goTo('edit-choose');
    if (step === 'edit-occupancy') return goTo('edit-details');
    if (step === 'edit-finances') return goTo('edit-choose');
  }

  const chainLen = mode === 'add' ? ADD_CHAIN.length : 3;
  const di = mode === 'add' ? ADD_CHAIN.indexOf(step) : (step === 'edit-choose' ? 0 : step === 'edit-finances' ? 2 : (step === 'edit-details' ? 1 : 2));
  React.useEffect(() => { onProgress && onProgress({ fill: Math.round((Math.max(0, di) / (chainLen - 1)) * 100), stepTitle: 'reo-' + step }); }, [step]);

  const eyebrow = mode === 'edit' ? 'EDIT PROPERTY' : 'ADD PROPERTY';
  const addrErr = f => t && (f === 'zip' ? !/^\d{5}$/.test(reoDigits(data.zip)) : !String(data[f] || '').trim());

  // ZIP-first autofill (editable; never overwrites typed values, a re-fill
  // only replaces our own previous fill). Shared by add and edit steps.
  const zipFillRef = React.useRef({ city: '', state: '' });
  const applyZipFill = hit => setData(d => {
    const patch = {};
    if (!String(d.city || '').trim() || d.city === zipFillRef.current.city) { patch.city = hit.city; zipFillRef.current.city = hit.city; }
    if (!d.state || d.state === zipFillRef.current.state) { patch.state = hit.state; zipFillRef.current.state = hit.state; }
    return Object.keys(patch).length ? { ...d, ...patch } : d;
  });
  const AddressFields = (
    <>
      <Field label="Street address" value={data.street} onChange={v => set({ street: v })} placeholder="123 Main Street" error={addrErr('street') ? 'Required' : ''} />
      <Field label="Apartment / unit number" optional value={data.unit} onChange={v => set({ unit: v })} placeholder="Unit 4B" />
      <ZipField value={data.zip} onChange={v => set({ zip: reoDigits(v).slice(0, 5) })} onFill={applyZipFill} error={addrErr('zip') ? 'Enter a 5-digit ZIP' : ''} placeholder="48374" />
      <div className="field-row">
        <Field label="City" value={data.city} onChange={v => set({ city: v })} placeholder="Novi" error={addrErr('city') ? 'Required' : ''} />
        <Select label="State" value={data.state} onChange={v => set({ state: v })} options={REO_STATES} placeholder="State" error={addrErr('state') ? 'Required' : ''} />
      </div>
    </>
  );

  let body = null;

  /* ---------- ADD ---------- */
  if (step === 'add-confirm') {
    body = <>
      <StepHead eyebrow={eyebrow} title={`Does ${who} own another property not listed here?`} />
      <div className="opt-list">
        <Opt icon={I.home(22)} title="I own another property not listed here"
          sub="Add a property you own that isn't already shown." selected={confirmAdd} onClick={() => setConfirmAdd(true)} />
      </div>
      <NavFooter onBack={back} onNext={next} nextLabel="Next" nextDisabled={!confirmAdd} backLabel="Cancel" />
    </>;
  }
  else if (step === 'add-address') {
    body = <><StepHead eyebrow={eyebrow} title="What is the address of this property?" />{AddressFields}<NavFooter onBack={back} onNext={next} nextLabel="Next" /></>;
  }
  else if (step === 'add-type') {
    body = <>
      <StepHead eyebrow={eyebrow} title="What type of property is this?" />
      <Select label="Property type" value={data.ptype} onChange={v => set({ ptype: v })} options={REO_PTYPES} placeholder="Select property type" error={t && !data.ptype ? 'Required' : ''} />
      <NavFooter onBack={back} onNext={next} nextLabel="Next" nextDisabled={!data.ptype} />
    </>;
  }
  else if (step === 'add-value') {
    body = <>
      <StepHead eyebrow={eyebrow} title="What is the estimated property value?" sub="Enter your best estimate. You can update this later if needed." />
      <Field label="Estimated property value" prefix="$" inputMode="numeric" value={data.value} onChange={v => set({ value: reoMoney(v) })} placeholder="400,000" error={t && !reoNum(data.value) ? 'Required' : ''} />
      <NavFooter onBack={back} onNext={next} nextLabel="Next" />
    </>;
  }
  else if (step === 'add-usage') {
    body = <>
      <StepHead eyebrow={eyebrow} title="How is this property used?" />
      <div className="opt-list">
        {REO_USAGE.map(u => <Opt key={u.value} icon={u.icon()} title={u.value} sub={u.sub} selected={data.usage === u.value} onClick={() => set({ usage: u.value })} />)}
      </div>
      {data.usage === 'Investment Property' && <div className="step" style={{ marginTop: 16 }}>
        <Field label="Monthly rental income" prefix="$" inputMode="numeric" value={data.rentalIncome} onChange={v => set({ rentalIncome: reoMoney(v) })} placeholder="2,000" error={t && !reoNum(data.rentalIncome) ? 'Required' : ''} />
        <p className="bi-helper-text">Enter the monthly rental income this property currently generates.</p>
      </div>}
      <NavFooter onBack={back} onNext={next} nextLabel="Next" nextDisabled={!data.usage} />
    </>;
  }
  else if (step === 'add-status') {
    body = <>
      <StepHead eyebrow={eyebrow} title="By the time this loan closes, what will be the status of this property?" />
      <div className="opt-list">
        {REO_STATUS.map(s => <Opt key={s.value} title={s.value} sub={s.sub} selected={data.status === s.value} onClick={() => set({ status: s.value })} />)}
      </div>
      <NavFooter onBack={back} onNext={next} nextLabel="Confirm and Continue" nextDisabled={!data.status} />
    </>;
  }

  /* ---------- EDIT ---------- */
  else if (step === 'edit-choose') {
    body = <>
      <StepHead eyebrow={eyebrow} title="Edit property" sub={reoAddrLine(data) || 'Update this property.'} />
      <div className="opt-list">
        <Opt icon={I.home(22)} title="Edit Property Details" sub="Address, property type, current usage, and status at closing." onClick={() => goTo('edit-details')} />
        <Opt icon={I.cash(22)} title="Edit Property Finances" sub="Property taxes, insurance, HOA dues, and other expenses." onClick={() => goTo('edit-finances')} />
      </div>
      <div className="step-nav"><button className="btn btn-secondary btn-block" onClick={back}>{I.back(16)}Back</button></div>
    </>;
  }
  else if (step === 'edit-details') {
    body = <>
      <StepHead eyebrow={eyebrow} title="Edit property details" />
      {AddressFields}
      <Select label="Property type" value={data.ptype} onChange={v => set({ ptype: v })} options={REO_PTYPES} placeholder="Select property type" error={t && !data.ptype ? 'Required' : ''} />
      <p className="bi-q" style={{ marginTop: 6 }}>How is this property currently used?</p>
      <div className="opt-list">
        {REO_USAGE.map(u => <Opt key={u.value} icon={u.icon()} title={u.value} sub={u.sub} selected={data.usage === u.value} onClick={() => set({ usage: u.value })} />)}
      </div>
      {data.usage === 'Investment Property' && <div className="step" style={{ marginTop: 14 }}>
        <Field label="Monthly rental income" prefix="$" inputMode="numeric" value={data.rentalIncome} onChange={v => set({ rentalIncome: reoMoney(v) })} placeholder="2,000" error={t && !reoNum(data.rentalIncome) ? 'Required' : ''} />
        <p className="bi-helper-text">Enter the monthly rental income this property currently generates.</p>
      </div>}
      <p className="bi-q" style={{ marginTop: 6 }}>By the time this loan closes, what will be the status of this property?</p>
      <div className="opt-list">
        {REO_STATUS.map(s => <Opt key={s.value} title={s.value} sub={s.sub} selected={data.status === s.value} onClick={() => set({ status: s.value })} />)}
      </div>
      {t && !data.status && <div className="field-err" style={{ marginTop: -6 }}>Please select a status</div>}
      <NavFooter onBack={back} onNext={next} nextLabel="Next" />
    </>;
  }
  else if (step === 'edit-occupancy') {
    body = <>
      <StepHead eyebrow={eyebrow} title="What is the intended occupancy type?" sub="How this property will be classified going forward." />
      <div className="opt-list">
        {REO_USAGE.map(u => <Opt key={u.value} icon={u.icon()} title={u.value} sub={u.sub} selected={data.intendedOccupancy === u.value} onClick={() => set({ intendedOccupancy: u.value })} />)}
      </div>
      {data.intendedOccupancy === 'Investment Property' && <div className="step" style={{ marginTop: 14 }}>
        <Field label="Expected monthly rental income" prefix="$" inputMode="numeric" value={data.intendedRental} onChange={v => set({ intendedRental: reoMoney(v) })} placeholder="2,000" error={t && !reoNum(data.intendedRental) ? 'Required' : ''} />
        <p className="bi-helper-text">Enter the expected monthly rental income for this property.</p>
      </div>}
      <NavFooter onBack={back} onNext={next} nextLabel="Confirm and Continue" nextDisabled={!data.intendedOccupancy} />
    </>;
  }
  else if (step === 'edit-finances') {
    const ExpRow = ({ label, amtKey, freqKey, freqDefault }) => (
      <div className="field-row">
        <Field label={label} optional prefix="$" inputMode="numeric" value={data[amtKey]} onChange={v => set({ [amtKey]: reoMoney(v) })} placeholder="0" />
        <Select label="How often?" value={data[freqKey] || freqDefault} onChange={v => set({ [freqKey]: v })} options={REO_FREQ} />
      </div>
    );
    body = <>
      <StepHead eyebrow={eyebrow} title="Edit property finances" sub="Tell us about the property taxes, insurance, HOA dues, and any other property expenses." />
      <ExpRow label="Property taxes" amtKey="taxes" freqKey="taxesFreq" freqDefault="Annually" />
      <ExpRow label="Homeowners insurance" amtKey="insurance" freqKey="insuranceFreq" freqDefault="Annually" />
      {!data.noHoa && <ExpRow label="HOA dues" amtKey="hoa" freqKey="hoaFreq" freqDefault="Monthly" />}
      <div className="bi-inline-check">
        <CheckRow checked={data.noHoa} onToggle={() => set({ noHoa: !data.noHoa, hoa: !data.noHoa ? '' : data.hoa })}>This property does not have HOA dues.</CheckRow>
      </div>
      <div className={'inc-toggle' + (data.otherExp.on ? ' on' : '')} style={{ marginTop: 4 }}>
        <CheckRow checked={data.otherExp.on} onToggle={() => setOther({ on: !data.otherExp.on })}>Add other property-related expense</CheckRow>
        {data.otherExp.on && <div className="inc-toggle-body">
          <Field label="Other expense amount" prefix="$" inputMode="numeric" value={data.otherExp.amt} onChange={v => setOther({ amt: reoMoney(v) })} placeholder="0" error={t && data.otherExp.on && !reoNum(data.otherExp.amt) ? 'Required' : ''} />
          <Field label="Other expense description" value={data.otherExp.desc} onChange={v => setOther({ desc: v })} placeholder="Example: Supplemental property insurance" error={t && data.otherExp.on && !data.otherExp.desc.trim() ? 'Required' : ''} />
          <Select label="How often is this expense paid?" value={data.otherExp.freq} onChange={v => setOther({ freq: v })} options={REO_FREQ} />
        </div>}
      </div>
      <NavFooter onBack={back} onNext={() => { if (data.otherExp.on && (!reoNum(data.otherExp.amt) || !data.otherExp.desc.trim())) { set({ touched: true }); return; } onSave({ ...data }); }} nextLabel="Confirm and Continue" />
    </>;
  }

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

window.PropertyFlow = PropertyFlow;
window.reoAddrLine = reoAddrLine;
window.REO_PROP_DEFAULT = REO_PROP_DEFAULT;
