/* Source brand tag colors (text labels only — no logos) */
const SRC_COLOR = (k) => {
  const s = k.toLowerCase();
  if (s.includes('zillow') || s.includes('zestimate')) return '#1277e1';
  if (s.includes('redfin')) return '#d4502e';
  if (s.includes('realtor')) return '#c8102e';
  if (s.includes('homes')) return '#1c7d6f';
  if (s.includes('rentometer')) return '#7a55c4';
  return '#5a8f7a';
};
const SRC_ABBR = (k) => {
  const s = k.toLowerCase();
  if (s.includes('zillow') || s.includes('zestimate')) return 'Z';
  if (s.includes('redfin')) return 'R';
  if (s.includes('realtor')) return 'Re';
  if (s.includes('homes')) return 'H';
  if (s.includes('rentometer')) return 'Rm';
  return '·';
};

/* ============ Address auto-fill (live APIs) ============ */
function AddressLookup({ deal, update }) {
  const [addr, setAddr] = React.useState(
    [deal.property.address, deal.property.city, (deal.property.state || '') + ' ' + (deal.property.zip || '')].filter(Boolean).join(', ').trim()
  );
  const [loading, setLoading] = React.useState(false);
  const [status, setStatus] = React.useState(null); // {sources:[{name,live}], msg}
  const [sugg, setSugg] = React.useState([]);
  const [showSugg, setShowSugg] = React.useState(false);
  const acTimer = React.useRef(null);

  const onType = (v) => {
    setAddr(v);
    if (acTimer.current) clearTimeout(acTimer.current);
    if (v.length < 4) { setSugg([]); return; }
    acTimer.current = setTimeout(async () => {
      const list = await autocomplete(v);
      setSugg(list); setShowSugg(true);
    }, 280);
  };
  const pick = (s) => {
    setAddr(s.full); setShowSugg(false); setSugg([]);
  };

  const run = async () => {
    if (loading || !addr.trim()) return;
    setLoading(true);
    setStatus(null);
    const sources = [];

    // 1) Geocode + satellite photo
    const geo = await geocode(addr);
    const prop = { ...deal.property };
    if (geo.ok) {
      sources.push({ name: geo.via, live: true });
      if (geo.house || geo.road) prop.address = (geo.house ? geo.house + ' ' : '') + (geo.road || prop.address);
      if (geo.city) prop.city = geo.city;
      if (geo.state) prop.state = geo.state;
      if (geo.zip) prop.zip = geo.zip;
      prop.lat = geo.lat; prop.lon = geo.lon;
      const photo = staticMapUrl(geo.lat, geo.lon);
      if (photo) prop.photoUrl = photo;
    } else {
      const parts = addr.split(',').map((s) => s.trim());
      if (parts[0]) prop.address = parts[0];
      if (parts[1]) prop.city = parts[1];
      if (parts[2]) { const m = parts[2].match(/([A-Za-z]{2})\s*(\d{5})?/); if (m) { prop.state = (m[1] || prop.state).toUpperCase(); if (m[2]) prop.zip = m[2]; } }
      sources.push({ name: 'Geocoder', live: false });
    }

    // 2) Property record (RentCast)
    const rec = await fetchProperty(addr);
    if (rec.ok) {
      if (rec.beds != null) prop.beds = rec.beds;
      if (rec.baths != null) prop.baths = rec.baths;
      if (rec.sqft != null) prop.sqft = rec.sqft;
      if (rec.lotSize != null) prop.lotSize = rec.lotSize;
      sources.push({ name: 'RentCast records', live: true });
    }

    // 3) Value AVM + 4) Rent AVM
    const [val, rent] = await Promise.all([fetchValue(addr), fetchRent(addr)]);
    const market = structuredClone(deal.market);
    const estimates = structuredClone(deal.estimates);
    const rental = structuredClone(deal.rental);
    const patch = { property: prop };

    if (val.ok) {
      market.value = { low: Math.round(val.low), mid: Math.round(val.mid), high: Math.round(val.high), comps: val.comps, source: 'live' };
      estimates[0] = { k: 'RentCast AVM', v: Math.round(val.mid) };
      patch.terms = { ...deal.terms, sellingPrice: Math.round(val.mid) };
      sources.push({ name: 'RentCast value', live: true });
    } else {
      const d = DEFAULT_DEAL;
      market.value = { ...d.market.value, source: 'sample' };
    }

    if (rent.ok) {
      market.rent = { low: Math.round(rent.low), mid: Math.round(rent.mid), high: Math.round(rent.high), comps: rent.comps, source: 'live' };
      rental[0] = { k: 'RentCast Rent', v: Math.round(rent.mid) };
      patch.capRate = { ...deal.capRate, monthlyRent: Math.round(rent.mid) };
      sources.push({ name: 'RentCast rent', live: true });
    } else {
      const d = DEFAULT_DEAL;
      market.rent = { ...d.market.rent, source: 'sample' };
    }

    patch.market = market;
    patch.estimates = estimates;
    patch.rental = rental;
    patch.meta = { fetchedFrom: sources.some((s) => s.live) ? 'live' : 'sample' };
    update(patch);

    const anyLive = sources.some((s) => s.live);
    const liveNames = sources.filter((s) => s.live).map((s) => s.name);
    const gotRC = val.ok || rent.ok || rec.ok;
    const rcErr = val.error || rent.error || rec.error;
    setStatus({
      sources,
      ok: anyLive,
      msg: gotRC
        ? 'Live data pulled from ' + liveNames.join(' · ')
        : (geo.ok
          ? 'Located & mapped live via ' + geo.via + '. ' + rentcastHint(rcErr)
          : 'Could not reach the data services from the browser. Sample data loaded — edit any field.'),
    });
    setLoading(false);
  };

  return (
    <div className="lookup">
      <div className="lookup-row">
        <svg className="pin" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" /><circle cx="12" cy="10" r="3" /></svg>
        <div className="ac-wrap">
          <input className="addr" value={addr} placeholder="Start typing an address — e.g. 209 Nacoochee Dr, Woodstock, GA"
            autoComplete="off"
            onChange={(e) => onType(e.target.value)}
            onFocus={() => sugg.length && setShowSugg(true)}
            onBlur={() => setTimeout(() => setShowSugg(false), 180)}
            onKeyDown={(e) => { if (e.key === 'Enter') { setShowSugg(false); run(); } }} />
          {showSugg && sugg.length ? (
            <div className="ac-list">
              {sugg.map((s, i) => (
                <button key={i} className="ac-item" onMouseDown={(e) => { e.preventDefault(); pick(s); }}>
                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" /><circle cx="12" cy="10" r="3" /></svg>
                  <span>{s.label}</span>
                </button>
              ))}
            </div>
          ) : null}
        </div>
        <button className="btn primary" onClick={() => { setShowSugg(false); run(); }} disabled={loading}>
          {loading ? <span className="spin"></span> : <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 21l-4.3-4.3" /><circle cx="11" cy="11" r="7" /></svg>}
          {loading ? 'Fetching…' : 'Auto-fill'}
        </button>
      </div>
      {loading ? (
        <div className="lookup-note"><span className="spin" style={{ borderTopColor: 'var(--green-600)', borderColor: 'rgba(63,122,95,.3)' }}></span> Geocoding, mapping &amp; pulling value/rent estimates…</div>
      ) : status ? (
        <div className={'fetch-status ' + (status.ok ? 'ok' : 'warn')}>
          <div className="fs-chips">
            {status.sources.map((s, i) => (
              <span key={i} className={'fs-chip ' + (s.live ? 'live' : 'sample')}>
                <span className="d"></span>{s.name}
              </span>
            ))}
          </div>
          <div className="fs-msg">{status.msg}</div>
        </div>
      ) : (
        <div className="lookup-note">
          <svg className="info" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><circle cx="12" cy="12" r="9" /><path d="M12 8h.01M11 12h1v4h1" /></svg>
          Pulls location &amp; a satellite photo (LocationIQ), property facts and value/rent ranges (RentCast). Anything that can’t be reached falls back to editable sample data.
        </div>
      )}
    </div>
  );
}

/* ============ Range bar (min · median · max) ============ */
function RangeBar({ low, mid, high, fmt, color }) {
  const span = high - low || 1;
  const midPct = Math.max(0, Math.min(100, ((mid - low) / span) * 100));
  return (
    <div className="rangebar">
      <div className="rb-track">
        <div className="rb-fill" style={{ background: color }}></div>
        <div className="rb-mid" style={{ left: midPct + '%', borderColor: color }}>
          <span className="rb-mid-val" style={{ color }}>{fmt(mid)}</span>
        </div>
      </div>
      <div className="rb-ends">
        <span><b>{fmt(low)}</b><small>Low</small></span>
        <span style={{ textAlign: 'right' }}><b>{fmt(high)}</b><small>High</small></span>
      </div>
    </div>
  );
}

/* ============ Market estimates + offer guidance ============ */
function MarketPanel({ deal, calc, update }) {
  const v = deal.market.value, r = deal.market.rent;
  const offer = computeOffer(deal, calc);
  const within = deal.terms.acceptedPrice <= offer.atGoal;
  return (
    <div className="market-grid">
      <div className="card">
        <div className="card-head"><h3>Market Estimates</h3>
          <span className={'src-pill ' + (v.source === 'live' ? 'live' : 'sample')}>{v.source === 'live' ? 'Live · RentCast' : 'Sample'}</span>
        </div>
        <div className="card-body">
          <div className="mp-block">
            <div className="mp-h"><span>Estimated Value &middot; ARV</span><span className="mp-mid">{fmtMoney(v.mid)}</span></div>
            <RangeBar low={v.low} mid={v.mid} high={v.high} fmt={(x) => fmtMoney(x)} color="var(--green-700)" />
            <div className="mp-foot">
              {v.comps ? v.comps + ' comparable sales' : 'Comp-based AVM range'}
              <button className="use-btn" onClick={() => update({ terms: { ...deal.terms, sellingPrice: v.mid } })}>Use as ARV →</button>
            </div>
          </div>
          <div className="mp-block" style={{ marginTop: 18 }}>
            <div className="mp-h"><span>Estimated Rent</span><span className="mp-mid">{fmtMoney(r.mid)}<small>/mo</small></span></div>
            <RangeBar low={r.low} mid={r.mid} high={r.high} fmt={(x) => fmtMoney(x)} color="#3f6f8c" />
            <div className="mp-foot">
              {r.comps ? r.comps + ' rental comps' : 'Rent AVM range'}
              <button className="use-btn" onClick={() => update({ capRate: { ...deal.capRate, monthlyRent: r.mid } })}>Use as rent →</button>
            </div>
          </div>
        </div>
      </div>

      <div className="card">
        <div className="card-head"><h3>Offer Guidance</h3>
          <span className={'src-pill ' + (within ? 'live' : 'warn-pill')}>{within ? 'On target' : 'Above target'}</span>
        </div>
        <div className="card-body">
          <div style={{ fontSize: 12.5, color: 'var(--muted)', lineHeight: 1.5, marginBottom: 12 }}>
            Back-solved from your ARV, rehab, fees &amp; holding cost — the most you should pay at each threshold.
          </div>
          <div className="offer-row best">
            <div><div className="ol-l">Offer for {deal.terms.profitGoalPct}% goal</div><div className="ol-s">Hits your profit target</div></div>
            <button className="offer-v" onClick={() => update({ terms: { ...deal.terms, acceptedPrice: Math.round(offer.atGoal) } })} title="Apply as accepted price">{fmtMoney(offer.atGoal)}</button>
          </div>
          <div className="offer-row">
            <div><div className="ol-l">70% rule (MAO)</div><div className="ol-s">70% × ARV − rehab</div></div>
            <button className="offer-v" onClick={() => update({ terms: { ...deal.terms, acceptedPrice: Math.round(offer.mao70) } })}>{fmtMoney(offer.mao70)}</button>
          </div>
          <div className="offer-row">
            <div><div className="ol-l">Break-even offer</div><div className="ol-s">Zero-profit ceiling</div></div>
            <button className="offer-v" onClick={() => update({ terms: { ...deal.terms, acceptedPrice: Math.round(offer.breakeven) } })}>{fmtMoney(offer.breakeven)}</button>
          </div>
          <div className="offer-current">
            <span>Your accepted price</span>
            <b className={within ? 'pos' : 'neg'}>{fmtMoney(deal.terms.acceptedPrice)}</b>
          </div>
          <div className="offer-hint">{within
            ? '✓ At or below the max for your goal — room of ' + fmtMoney(offer.atGoal - deal.terms.acceptedPrice) + '.'
            : '▲ ' + fmtMoney(deal.terms.acceptedPrice - offer.atGoal) + ' over the max for your goal. Tap a number to apply it.'}</div>
          <div style={{ marginTop: 14 }}>
            <OfferLetterButton deal={deal} calc={calc} />
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { RangeBar, MarketPanel });

/* ============ Value estimate comparison ============ */
function EstimateList({ title, subtitle, items, listKey, updateList, suffix, onUse, useLabel, avgLabel }) {
  const vals = items.map((i) => Number(i.v) || 0).filter((v) => v > 0);
  const avg = vals.length ? vals.reduce((a, b) => a + b, 0) / vals.length : 0;
  const lo = vals.length ? Math.min(...vals) : 0;
  const hi = vals.length ? Math.max(...vals) : 1;
  const setVal = (idx, v) => updateList(listKey, idx, v);

  return (
    <div className="card">
      <div className="card-head"><h3>{title}</h3>{avg ? <span className="head-total">avg {fmtMoney(avg)}</span> : null}</div>
      <div className="card-body">
        {subtitle ? <div style={{ fontSize: 12, color: 'var(--muted)', margin: '2px 0 10px', lineHeight: 1.5 }}>{subtitle}</div> : null}
        {items.map((it, i) => {
          const v = Number(it.v) || 0;
          const pct = hi > lo ? 14 + ((v - lo) / (hi - lo)) * 86 : (v > 0 ? 100 : 0);
          return (
            <div className="est-row" key={i}>
              <div className="src">
                <span className="tag" style={{ background: SRC_COLOR(it.k) }}>{SRC_ABBR(it.k)}</span>
                {it.k}
              </div>
              <div className="est-bar-track"><div className="est-bar-fill" style={{ width: pct + '%', background: SRC_COLOR(it.k) }}></div></div>
              <MoneyInput value={it.v} onChange={(val) => setVal(i, val)} />
            </div>
          );
        })}
        <div className="est-avg">
          <div>
            <div className="l">{avgLabel}</div>
            <div className="v">{fmtMoney(avg)}{suffix ? <span style={{ fontSize: 12, fontWeight: 600, color: 'var(--muted)' }}>{suffix}</span> : null}</div>
            {vals.length > 1 ? <div style={{ fontSize: 11.5, color: 'var(--muted)', marginTop: 3 }}>Range {fmtMoney(lo)} – {fmtMoney(hi)}</div> : null}
          </div>
          <button className="use-btn" onClick={() => onUse(Math.round(avg))}>{useLabel}</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { AddressLookup, EstimateList });
