/* ============================================================================
   MOWDEW — Water chemistry across all three personas
   The pool's chemistry doubles as a HOMEOWNER TRUST signal: competitors keep
   it pro-side; Mowdew shows the homeowner a plain, reassuring verdict.
     • PRO   ProLogChem        — fast numeric entry inside a visit (mobile)
     • HOME  ChemVerdictHero   — "Water: Balanced ✓" star card (used by h_chem)
     • OWNER OwnerChemHistory  — per-property reading timeline + chronic flag
     • OWNER OwnerConfigReadings — toggle tracked readings / units / ideal ranges
   Extends the chemistry primitives in mowdew-kit.jsx (READINGS, computeLSI…).
   ========================================================================= */

/* 8 verified visits for 88 Crestline Ave (Emma) — newest first. Two early
   blips the pro already handled; CYA quietly creeping high (chronic, owner-side). */
const POOL_CHEM_LOG = [
  { id: 'k1', date: 'Today · May 12',  short: 'May 12', visit: 'v1', live: true,
    ph: 7.4, cl: 1.8, alk: 100, cya: 58, salt: 3200, ch: 300, temp: 80 },
  { id: 'k2', date: 'Mon · May 5',     short: 'May 5',  visit: 'v2',
    ph: 7.5, cl: 2.1, alk: 110, cya: 55, salt: 3150, ch: 290, temp: 79 },
  { id: 'k3', date: 'Mon · Apr 28',    short: 'Apr 28', visit: 'v3', handled: 'cl',
    ph: 7.2, cl: 0.8, alk: 95,  cya: 53, salt: 3100, ch: 295, temp: 78 },
  { id: 'k4', date: 'Mon · Apr 21',    short: 'Apr 21', visit: 'v4', handled: 'ph',
    ph: 7.8, cl: 2.6, alk: 120, cya: 50, salt: 3250, ch: 310, temp: 77 },
  { id: 'k5', date: 'Mon · Apr 14',    short: 'Apr 14', visit: 'v4',
    ph: 7.6, cl: 1.9, alk: 105, cya: 47, salt: 3200, ch: 300, temp: 76 },
  { id: 'k6', date: 'Mon · Apr 7',     short: 'Apr 7',  visit: 'v4',
    ph: 7.3, cl: 1.2, alk: 90,  cya: 45, salt: 3050, ch: 285, temp: 75 },
  { id: 'k7', date: 'Mon · Mar 31',    short: 'Mar 31', visit: 'v4',
    ph: 7.5, cl: 2.0, alk: 100, cya: 46, salt: 3180, ch: 305, temp: 74 },
  { id: 'k8', date: 'Mon · Mar 24',    short: 'Mar 24', visit: 'v4',
    ph: 7.4, cl: 1.6, alk: 108, cya: 44, salt: 3120, ch: 300, temp: 73 },
];

/* default tracked set + which readings the homeowner verdict leans on */
const CHEM_TRACKED = ['ph', 'cl', 'alk', 'cya', 'salt', 'ch', 'temp'];
const CHEM_SANITIZER = ['ph', 'cl', 'alk']; // the readings that drive the homeowner verdict

function chemTone(key, val) {
  const st = chemState(key, val);
  return st === 'ideal' ? 'ideal' : st === 'low' ? 'low' : st === 'high' ? 'high' : 'empty';
}
const CHEM_STATE_C = {
  ideal: { bg: 'var(--green-50)',  bd: 'var(--green-100)',  fg: 'var(--green-700)' },
  low:   { bg: 'var(--yellow-50)', bd: 'var(--yellow-100)', fg: 'var(--yellow-700)' },
  high:  { bg: '#FBEAE3',          bd: '#F6D6C8',           fg: 'var(--coral-700,#C2410C)' },
  empty: { bg: 'var(--ink-50)',    bd: 'var(--ink-100)',    fg: 'var(--ink-500)' },
};

/* ─── LSI chip — balance verdict, labelled an estimate ──────────────── */
function LsiChip({ lsi, size = 'md' }) {
  const v = lsiVerdict(lsi);
  const c = v.key === 'balanced' ? ['var(--green-50)', 'var(--green-100)', 'var(--green-700)']
    : v.key === 'corrosive' ? ['var(--yellow-50)', 'var(--yellow-100)', 'var(--yellow-700)']
    : v.key === 'scaling' ? ['var(--chem-50)', '#DDD7FA', '#5847d6']
    : ['var(--ink-50)', 'var(--ink-100)', 'var(--ink-500)'];
  const big = size === 'lg';
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, background: c[0], border: `1px solid ${c[1]}`, borderRadius: 12, padding: big ? '9px 13px' : '6px 11px' }}>
      <Icon name={v.key === 'balanced' ? 'check-circle' : 'flask'} size={big ? 18 : 15} style={{ color: c[2] }} />
      <span>
        <span style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: big ? 15 : 13, color: c[2], letterSpacing: '-0.01em' }}>{v.label}</span>
        {lsi != null && <span style={{ fontFamily: 'var(--font-mono)', fontSize: big ? 11 : 10, color: c[2], opacity: .8, marginLeft: 7 }}>LSI {lsi >= 0 ? '+' : ''}{lsi.toFixed(2)}</span>}
      </span>
      <span style={{ fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '.08em', color: c[2], opacity: .7, borderLeft: `1px solid ${c[1]}`, paddingLeft: 8 }}>EST</span>
    </span>
  );
}

/* ─── HOMEOWNER verdict hero — the star. Plain, reassuring, never scary. ─ */
function ChemVerdictHero({ reading, size = 'lg' }) {
  const lsi = computeLSI(reading);
  const v = lsiVerdict(lsi);
  // any sanitizer reading out of range?
  const outs = CHEM_SANITIZER.filter(k => reading[k] != null && chemState(k, reading[k]) !== 'ideal');
  const handledKey = reading.handled;
  const allGood = outs.length === 0 && v.key === 'balanced';
  const headline = allGood ? 'Water: Balanced' : v.key === 'balanced' ? 'Water: Looked after' : `Water: ${v.label}`;
  let line;
  if (allGood) line = "Everything's in range — your pool's healthy.";
  else if (handledKey) {
    const r = READINGS[handledKey];
    const word = handledKey === 'cl' ? 'Chlorine was a touch low today' : handledKey === 'ph' ? 'pH ran a little high today' : `${r.label} was off today`;
    line = `${word} — Diego ${handledKey === 'cl' ? 'added tablets' : 'balanced it'} on the visit. All set now.`;
  } else if (outs.length) {
    line = "A couple of levels are settling in — your pro's on it. Nothing for you to do.";
  } else line = "Your pool's in good shape.";

  return (
    <div className="card card-feature" style={{ padding: size === 'lg' ? 20 : 16, borderColor: 'var(--aqua-100)', background: 'var(--aqua-50)' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
        <Dewy size={size === 'lg' ? 72 : 56} mood={allGood ? 'happy' : 'wink'} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <span style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: size === 'lg' ? 23 : 19, letterSpacing: '-0.025em', color: 'var(--ink-900)', lineHeight: 1.05 }}>{headline}</span>
            {allGood && <Icon name="check-circle" size={size === 'lg' ? 22 : 19} style={{ color: 'var(--green-600)', flexShrink: 0 }} />}
          </div>
          <div style={{ fontFamily: 'var(--font-mono)', fontSize: 10.5, letterSpacing: '.08em', color: 'var(--aqua-700)', marginTop: 5 }}>{(reading.date || 'TODAY').toUpperCase()} · VERIFIED ON-SITE</div>
        </div>
      </div>
      <p style={{ fontSize: size === 'lg' ? 15 : 13.5, color: 'var(--ink-700)', lineHeight: 1.5, margin: '13px 0 0' }}>{line}</p>
      <div style={{ marginTop: 13, display: 'flex', alignItems: 'center', gap: 9, flexWrap: 'wrap' }}>
        <LsiChip lsi={lsi} size={size} />
        <span style={{ fontSize: 11.5, color: 'var(--ink-500)' }}>Water-balance estimate · your pro confirms it</span>
      </div>
    </div>
  );
}

/* ─── Reading display row — used by homeowner detail + owner timeline ── */
function ChemRow({ rkey, value, note, showBand = true }) {
  const r = READINGS[rkey];
  const st = chemState(rkey, value);
  const c = CHEM_STATE_C[st];
  const txt = st === 'ideal' ? 'In range' : st === 'low' ? 'Low' : st === 'high' ? 'High' : '—';
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px' }}>
      <span style={{ width: 9, height: 36, borderRadius: 3, background: c.fg, flexShrink: 0, opacity: st === 'ideal' ? .9 : 1 }} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontWeight: 700, fontSize: 13.5 }}>{r.label}</div>
        <div style={{ fontSize: 11, color: 'var(--ink-500)', fontFamily: 'var(--font-mono)' }}>{showBand ? `IDEAL ${r.band}` : ''}{note ? (showBand ? ' · ' : '') + note : ''}</div>
      </div>
      <div style={{ textAlign: 'right', flexShrink: 0 }}>
        <span style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 18, letterSpacing: '-0.02em', fontVariantNumeric: 'tabular-nums', color: st === 'ideal' ? 'var(--ink-900)' : c.fg }}>
          {value == null ? '—' : value.toFixed(r.dp)}{r.unit && value != null ? <span style={{ fontSize: 10.5, color: 'var(--ink-500)', fontWeight: 600 }}> {r.unit}</span> : null}
        </span>
      </div>
      <span style={{ fontFamily: 'var(--font-mono)', fontSize: 9.5, fontWeight: 700, letterSpacing: '.06em', color: c.fg, background: c.bg, border: `1px solid ${c.bd}`, borderRadius: 7, padding: '3px 7px', flexShrink: 0, minWidth: 54, textAlign: 'center' }}>{txt.toUpperCase()}</span>
    </div>
  );
}

/* ============================================================================
   PRO — Log water chemistry (mobile, inside a visit)
   ========================================================================= */
function ProLogChem({ go, params, toast }) {
  const stop = (window.PRO_STOPS || []).find(s => s.id === params.id) || { label: 'Crestline Ave', vert: 'pool', in: '10:12 AM' };
  const tracked = CHEM_TRACKED;
  const [vals, setVals] = React.useState(() => Object.fromEntries(tracked.map(k => [k, ''])));
  const [photo, setPhoto] = React.useState(false);
  const [added, setAdded] = React.useState({});      // dosing keys marked done
  const set = (k, v) => setVals(s => ({ ...s, [k]: v }));

  const num = (k) => { const n = parseFloat(vals[k]); return isNaN(n) ? null : n; };
  const reading = Object.fromEntries(tracked.map(k => [k, num(k)]));
  const entered = tracked.filter(k => num(k) != null);
  const filled = entered.length;
  const lsi = reading.ph != null ? computeLSI(reading) : null;
  const outKeys = tracked.filter(k => num(k) != null && chemState(k, num(k)) !== 'ideal');
  const dosing = dosingFor(reading).filter(d => !added[d.key]);
  const allIn = filled === tracked.length && outKeys.length === 0;

  const scan = () => {
    // "snap test kit" autofill — one reading comes in a touch low to show the calm out-of-range + dosing flow
    setVals({ ph: '7.4', cl: '0.8', alk: '100', cya: '45', salt: '3200', ch: '300', temp: '80' });
    setPhoto(true);
    toast('Test kit read · check the values', 'blue');
  };
  const markAdded = (d) => {
    setAdded(a => ({ ...a, [d.key]: true }));
    // optimistic: bring that reading into range so the celebratory state can show
    if (d.key === 'cl') set('cl', '2.0');
    if (d.key === 'ph') set('ph', '7.4');
    if (d.key === 'alk') set('alk', '100');
    toast('Marked as added · re-test after circulation', 'green');
  };
  const save = () => { toast('Readings saved · shared with the homeowner', 'green'); go('pro_visit', { id: params.id }); };

  return (
    <Screen padBottom={26} footer={
      <ActionBar>
        <button onClick={save} disabled={filled === 0} className="btn btn-primary btn-lg btn-block">
          <Icon name="check-circle" size={20} />{filled === 0 ? 'Enter a reading to save' : `Save ${filled} reading${filled > 1 ? 's' : ''}`}
        </button>
      </ActionBar>}>
      <TopBar title="Log water chemistry" subtitle={`${stop.label} pool`} onBack={() => go('pro_visit', { id: params.id })}
        right={<span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, background: 'var(--ink-50)', borderRadius: 99, padding: '5px 10px', fontSize: 11, fontWeight: 700, color: 'var(--ink-500)' }}><Icon name="lock" size={12} />Private</span>} />

      {/* scan / photo */}
      <div style={{ padding: '4px 18px 0' }}>
        <div onClick={scan} style={{ cursor: 'pointer', border: '1.5px dashed var(--aqua-200)', background: 'var(--aqua-50)', borderRadius: 'var(--radius-xl)', padding: 14, display: 'flex', alignItems: 'center', gap: 13 }}>
          <span style={{ width: 46, height: 46, borderRadius: 13, background: 'var(--aqua-500)', display: 'grid', placeItems: 'center', color: '#fff', flexShrink: 0 }}><Icon name="camera" size={23} /></span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 15 }}>{photo ? 'Test kit photo attached' : 'Snap the test kit'}</div>
            <div style={{ fontSize: 12, color: 'var(--aqua-700)' }}>{photo ? 'Values pre-filled — confirm below' : 'Auto-fills the readings · or enter by hand'}</div>
          </div>
          {photo ? <Icon name="check-circle" size={22} style={{ color: 'var(--aqua-700)' }} /> : <Icon name="arrow-right" size={20} style={{ color: 'var(--aqua-700)' }} />}
        </div>
      </div>

      {/* numeric entry list */}
      <div style={{ padding: '18px 18px 0' }}>
        <SectionHead tone="aqua" icon="flask" style={{ marginBottom: 10 }} meta={`${filled}/${tracked.length} entered`}>Readings</SectionHead>
        <div className="card" style={{ overflow: 'hidden' }}>
          {tracked.map((k, i) => <ChemEntryRow key={k} rkey={k} value={vals[k]} onChange={(v) => set(k, v)} top={i > 0} />)}
        </div>
        <div style={{ fontSize: 11.5, color: 'var(--ink-500)', padding: '9px 2px 0', display: 'flex', alignItems: 'center', gap: 6 }}>
          <Icon name="shield" size={13} style={{ color: 'var(--aqua-700)' }} />Saved readings are shared with the homeowner as a plain verdict.
        </div>
      </div>

      {/* state banner */}
      {filled === 0 ? (
        <div style={{ padding: '16px 18px 0' }}>
          <div className="card" style={{ padding: 16, display: 'flex', alignItems: 'center', gap: 12, background: 'var(--ink-50)' }}>
            <Sprout size={48} mood="default" />
            <div style={{ fontSize: 13, color: 'var(--ink-600,#6E6B60)', lineHeight: 1.45 }}>Enter readings as you test — or snap the kit to fill them in. The balance verdict appears here.</div>
          </div>
        </div>
      ) : (
        <>
          {/* LSI balance verdict */}
          <div style={{ padding: '16px 18px 0' }}>
            <div className="card" style={{ padding: 14 }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, flexWrap: 'wrap' }}>
                <div>
                  <div style={{ fontSize: 12.5, color: 'var(--ink-500)', fontWeight: 600 }}>Water balance</div>
                  <div style={{ fontSize: 11, color: 'var(--ink-400,#A8A498)', fontFamily: 'var(--font-mono)', marginTop: 2 }}>LANGELIER INDEX · ESTIMATE</div>
                </div>
                <LsiChip lsi={lsi} size="lg" />
              </div>
            </div>
          </div>

          {/* all-in-range celebration OR calm out-of-range */}
          {allIn ? (
            <div style={{ padding: '14px 18px 0' }}>
              <div className="card" style={{ padding: 16, borderColor: 'var(--green-100)', background: 'var(--green-50)', display: 'flex', alignItems: 'center', gap: 13 }}>
                <Dewy size={58} mood="happy" />
                <div>
                  <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 16, color: 'var(--green-800)' }}>All readings in range</div>
                  <div style={{ fontSize: 13, color: 'var(--ink-700)', marginTop: 2 }}>Nice — this pool's dialed in. Save and the homeowner sees a clean bill.</div>
                </div>
              </div>
            </div>
          ) : outKeys.length > 0 && (
            <div style={{ padding: '14px 18px 0' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
                <Icon name="flask" size={15} style={{ color: 'var(--yellow-700)' }} />
                <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10.5, fontWeight: 600, letterSpacing: '.12em', color: 'var(--yellow-700)' }}>{outKeys.length} TO ADJUST · NOT URGENT</span>
              </div>
              {dosing.length > 0 ? (
                <div style={{ display: 'grid', gap: 10 }}>
                  {dosing.map(d => (
                    <div key={d.key} className="card" style={{ padding: 14, borderColor: 'var(--yellow-100)' }}>
                      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 11 }}>
                        <span style={{ width: 38, height: 38, borderRadius: 11, background: 'var(--yellow-50)', display: 'grid', placeItems: 'center', color: 'var(--yellow-700)', flexShrink: 0 }}><Icon name="flask" size={19} /></span>
                        <div style={{ flex: 1, minWidth: 0 }}>
                          <div style={{ fontWeight: 700, fontSize: 14 }}>{d.text}</div>
                          <div style={{ fontSize: 11.5, color: 'var(--ink-500)', marginTop: 2 }}>{d.why} · <span style={{ fontFamily: 'var(--font-mono)' }}>EST for ~15k gal</span></div>
                        </div>
                      </div>
                      <button onClick={() => markAdded(d)} className="btn btn-secondary btn-block" style={{ marginTop: 11, minHeight: 42 }}><Icon name="check" size={17} />Mark as added</button>
                    </div>
                  ))}
                </div>
              ) : (
                <div className="card" style={{ padding: 14, display: 'flex', alignItems: 'center', gap: 11, background: 'var(--green-50)', borderColor: 'var(--green-100)' }}>
                  <Icon name="check-circle" size={18} style={{ color: 'var(--green-700)', flexShrink: 0 }} />
                  <div style={{ fontSize: 13, color: 'var(--ink-700)' }}>Treatments marked added. Re-test after the water circulates.</div>
                </div>
              )}
            </div>
          )}
        </>
      )}
    </Screen>
  );
}

/* fast numeric entry row — label + big value + unit + ideal band + live tint */
function ChemEntryRow({ rkey, value, onChange, top }) {
  const r = READINGS[rkey];
  const n = value === '' || value == null ? null : parseFloat(value);
  const st = n == null || isNaN(n) ? 'empty' : chemState(rkey, n);
  const c = CHEM_STATE_C[st];
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '10px 14px', borderTop: top ? '1px solid var(--ink-100)' : 'none', background: st === 'empty' ? '#fff' : c.bg, transition: 'background .15s' }}>
      <span style={{ width: 9, height: 38, borderRadius: 3, background: st === 'empty' ? 'var(--ink-100)' : c.fg, flexShrink: 0 }} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontWeight: 700, fontSize: 14 }}>{r.label}</div>
        <div style={{ fontFamily: 'var(--font-mono)', fontSize: 10.5, color: st === 'empty' ? 'var(--ink-500)' : c.fg, letterSpacing: '.04em' }}>
          {st === 'empty' ? `IDEAL ${r.band}` : st === 'ideal' ? 'IN RANGE' : st === 'low' ? `LOW · IDEAL ${r.band}` : `HIGH · IDEAL ${r.band}`}
        </div>
      </div>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 5, flexShrink: 0 }}>
        <input
          type="text" inputMode="decimal" value={value} onChange={e => onChange(e.target.value.replace(/[^0-9.]/g, ''))}
          placeholder="—" aria-label={r.label}
          style={{ width: 74, textAlign: 'right', border: `1.5px solid ${st === 'empty' ? 'var(--ink-200)' : c.bd}`, borderRadius: 11, padding: '9px 10px', fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 20, letterSpacing: '-0.02em', color: st === 'empty' ? 'var(--ink-900)' : c.fg, background: '#fff', outline: 'none', fontVariantNumeric: 'tabular-nums' }}
        />
        {r.unit ? <span style={{ fontSize: 11, color: 'var(--ink-500)', fontWeight: 600, width: 28 }}>{r.unit}</span> : <span style={{ width: 28 }} />}
      </div>
    </div>
  );
}

/* ============================================================================
   OWNER — Chemistry history per property (web + mobile)
   ========================================================================= */
function chronicFlags(log) {
  const recent = log.slice(0, 6);
  const flags = {};
  CHEM_TRACKED.forEach(k => {
    if (READINGS[k].soft) return;
    const out = recent.filter(r => r[k] != null && chemState(k, r[k]) !== 'ideal').length;
    if (out >= 3) flags[k] = out;
  });
  return flags;
}
function OwnerChemHistory({ go, params, toast }) {
  const log = POOL_CHEM_LOG;
  const cols = ['ph', 'cl', 'alk', 'cya']; // compact grid columns; full set in expand
  const [openId, setOpenId] = React.useState(null);
  const flags = chronicFlags(log);
  const flagKeys = Object.keys(flags);
  const latest = log[0];

  return (
    <Screen padBottom={26} footer={
      <ActionBar>
        <button onClick={() => go('o_chem_config')} className="btn btn-secondary" style={{ flex: 1 }}><Icon name="settings" size={18} />Configure readings</button>
        <button onClick={() => toast('Chemistry report exported', 'green')} className="btn btn-primary" style={{ flex: 1 }}><Icon name="file" size={18} />Export</button>
      </ActionBar>}>
      <TopBar title="Water chemistry" subtitle="Crestline Ave · weekly pool" onBack={() => go('o_customer', { id: params.id || 'c2' })} />

      {/* latest snapshot */}
      <div style={{ padding: '4px 18px 0' }}>
        <div className="card" style={{ padding: 14, borderColor: 'var(--aqua-100)' }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, marginBottom: 10 }}>
            <div>
              <div style={{ fontSize: 12, color: 'var(--ink-500)', fontWeight: 600 }}>Latest · {latest.date.replace('Today · ', '')}</div>
              <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 18, letterSpacing: '-0.02em' }}>Verified on-site</div>
            </div>
            <LsiChip lsi={computeLSI(latest)} />
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 8 }}>
            {cols.map(k => {
              const st = chemState(k, latest[k]); const c = CHEM_STATE_C[st];
              return (
                <div key={k} style={{ background: c.bg, border: `1px solid ${c.bd}`, borderRadius: 12, padding: '9px 8px', textAlign: 'center' }}>
                  <div style={{ fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '.06em', color: c.fg }}>{READINGS[k].abbr}</div>
                  <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 17, color: st === 'ideal' ? 'var(--ink-900)' : c.fg, letterSpacing: '-0.02em' }}>{latest[k].toFixed(READINGS[k].dp)}</div>
                </div>
              );
            })}
          </div>
        </div>
      </div>

      {/* chronic warning */}
      {flagKeys.length > 0 && (
        <div style={{ padding: '14px 18px 0' }}>
          <div className="card" style={{ padding: 14, borderColor: 'var(--yellow-100)', background: 'var(--yellow-50)' }}>
            <div style={{ display: 'flex', alignItems: 'flex-start', gap: 11 }}>
              <span style={{ width: 38, height: 38, borderRadius: 11, background: '#fff', border: '1px solid var(--yellow-100)', display: 'grid', placeItems: 'center', color: 'var(--yellow-700)', flexShrink: 0 }}><Icon name="nudge" size={19} /></span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontWeight: 700, fontSize: 14, color: 'var(--ink-900)' }}>{flagKeys.map(k => READINGS[k].label).join(' & ')} chronically out of range</div>
                <div style={{ fontSize: 12.5, color: 'var(--ink-700)', marginTop: 3, lineHeight: 1.45 }}>
                  {flagKeys.includes('cya') ? 'CYA has crept above 50 ppm for three visits running — stabilizer builds up over time. Plan a partial drain & refill to reset it.' : 'Out of range on 3+ recent visits — worth a closer look on the next service.'}
                </div>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* per-visit timeline */}
      <div style={{ padding: '16px 18px 0' }}>
        <SectionHead tone="aqua" icon="ledger" style={{ marginBottom: 10 }} meta={`${log.length} visits`}>Every visit, on the record</SectionHead>
        <div className="card" style={{ overflow: 'hidden' }}>
          {log.map((r, i) => {
            const open = openId === r.id;
            const outs = cols.filter(k => chemState(k, r[k]) !== 'ideal');
            return (
              <div key={r.id} style={{ borderTop: i ? '1px solid var(--ink-100)' : 'none' }}>
                <div onClick={() => setOpenId(open ? null : r.id)} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '11px 14px', cursor: 'pointer', background: open ? 'var(--ink-50)' : '#fff' }}>
                  <div style={{ width: 64, flexShrink: 0 }}>
                    <div style={{ fontWeight: 700, fontSize: 13 }}>{r.short}</div>
                    {r.live && <div style={{ fontFamily: 'var(--font-mono)', fontSize: 8.5, letterSpacing: '.08em', color: 'var(--aqua-700)' }}>TODAY</div>}
                  </div>
                  {/* compact cells */}
                  <div style={{ flex: 1, display: 'flex', gap: 6 }}>
                    {cols.map(k => {
                      const st = chemState(k, r[k]); const c = CHEM_STATE_C[st];
                      return (
                        <div key={k} style={{ flex: 1, textAlign: 'center', background: st === 'ideal' ? 'transparent' : c.bg, border: st === 'ideal' ? '1px solid var(--ink-100)' : `1px solid ${c.bd}`, borderRadius: 8, padding: '5px 2px' }}>
                          <div style={{ fontFamily: 'var(--font-mono)', fontSize: 8, color: 'var(--ink-400,#A8A498)' }}>{READINGS[k].abbr}</div>
                          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 13, color: st === 'ideal' ? 'var(--ink-700)' : c.fg }}>{r[k].toFixed(READINGS[k].dp)}</div>
                        </div>
                      );
                    })}
                  </div>
                  <Icon name="chevron-down" size={16} style={{ color: 'var(--ink-300)', transform: open ? 'rotate(180deg)' : 'none', transition: 'transform .18s', flexShrink: 0 }} />
                </div>
                {open && (
                  <div style={{ padding: '2px 8px 10px', background: 'var(--ink-50)' }}>
                    <div className="card" style={{ overflow: 'hidden' }}>
                      {CHEM_TRACKED.map((k, j) => <ChemRow key={k} rkey={k} value={r[k]} />)}
                    </div>
                    {r.handled && (
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 8, padding: '9px 12px', background: 'var(--green-50)', border: '1px solid var(--green-100)', borderRadius: 11, fontSize: 12, color: 'var(--green-800)', fontWeight: 600 }}>
                        <Icon name="check-circle" size={15} style={{ flexShrink: 0 }} />Handled on-site — {READINGS[r.handled].label} brought back in range that visit.
                      </div>
                    )}
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>
    </Screen>
  );
}

/* ============================================================================
   OWNER — Configure readings (setting): toggle tracked, units, ideal ranges
   ========================================================================= */
function OwnerConfigReadings({ go, toast }) {
  const POOL_DEFAULT = ['ph', 'cl', 'alk', 'cya', 'salt', 'ch', 'temp'];
  const [on, setOn] = React.useState(() => Object.fromEntries(CHEM_TRACKED.map(k => [k, true])));
  const toggle = (k) => setOn(s => ({ ...s, [k]: !s[k] }));
  const count = Object.values(on).filter(Boolean).length;
  return (
    <Screen padBottom={26} footer={
      <ActionBar>
        <button onClick={() => { toast('Reading set saved · applies to new pool visits', 'green'); go('o_settings'); }} className="btn btn-primary btn-lg btn-block"><Icon name="check-circle" size={20} />Save reading set</button>
      </ActionBar>}>
      <TopBar title="Configure readings" subtitle="What your Pros log on pool visits" onBack={() => go('o_settings')} />

      <div style={{ padding: '4px 18px 0' }}>
        <div className="card" style={{ padding: 13, display: 'flex', alignItems: 'center', gap: 11, background: 'var(--aqua-50)', borderColor: 'var(--aqua-100)' }}>
          <Dewy size={42} mood="happy" />
          <div style={{ flex: 1, fontSize: 12.5, color: 'var(--ink-700)', lineHeight: 1.45 }}><b>{count} readings tracked.</b> Sensible pool defaults are on. Toggle what your crew measures, with ideal ranges.</div>
        </div>
      </div>

      <div style={{ padding: '16px 18px 0' }}>
        <SectionHead tone="aqua" icon="flask" style={{ marginBottom: 10 }} meta="ideal range · unit">Tracked readings</SectionHead>
        <div className="card" style={{ overflow: 'hidden' }}>
          {CHEM_TRACKED.map((k, i) => {
            const r = READINGS[k];
            const active = on[k];
            return (
              <div key={k} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '13px 14px', borderTop: i ? '1px solid var(--ink-100)' : 'none', opacity: active ? 1 : .55 }}>
                <span style={{ width: 36, height: 36, borderRadius: 10, background: active ? 'var(--aqua-50)' : 'var(--ink-50)', display: 'grid', placeItems: 'center', color: active ? 'var(--aqua-700)' : 'var(--ink-400,#A8A498)', flexShrink: 0, fontFamily: 'var(--font-mono)', fontSize: 10, fontWeight: 700 }}>{r.abbr}</span>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 700, fontSize: 14 }}>{r.label}</div>
                  <div style={{ fontSize: 11.5, color: 'var(--ink-500)', fontFamily: 'var(--font-mono)' }}>{r.band}{r.soft ? ' · reference only' : ''}</div>
                </div>
                <Toggle on={active} onChange={() => toggle(k)} tone="green" />
              </div>
            );
          })}
        </div>
        <div style={{ fontSize: 11.5, color: 'var(--ink-500)', padding: '10px 2px 0', lineHeight: 1.45 }}>Ranges follow industry pool norms. The homeowner only ever sees a plain verdict — not the raw set.</div>
      </div>
    </Screen>
  );
}

Object.assign(window, {
  POOL_CHEM_LOG, CHEM_TRACKED, CHEM_SANITIZER, chemTone, CHEM_STATE_C,
  LsiChip, ChemVerdictHero, ChemRow, ChemEntryRow,
  ProLogChem, OwnerChemHistory, OwnerConfigReadings, chronicFlags,
});
