// Hi-fi Routines (calendar), Contacts list + detail, To-Dos, Settings.

const { FONT_DISPLAY: SR_DISPLAY, FONT_BODY: SR_BODY, FONT_MONO: SR_MONO } = window.HIFI;

// ============================================================
// Routines — month calendar + rail
// ============================================================
const HifiRoutinesScreen = ({ t, nav }) => {
  const visible = ROUTINES;

  // ---- displayed month (navigable) ----
  const nowRef = new Date();
  const [cursor, setCursor] = React.useState(() => new Date(nowRef.getFullYear(), nowRef.getMonth(), 1));
  const year = cursor.getFullYear();
  const month = cursor.getMonth();
  const MONTHS = ['January','February','March','April','May','June','July','August','September','October','November','December'];
  const monthLabel = `${MONTHS[month]} ${year}`;
  const today = new Date(); today.setHours(0, 0, 0, 0);
  const isCurrentMonth = year === today.getFullYear() && month === today.getMonth();
  const todayDay = today.getDate();
  const firstWeekday = new Date(year, month, 1).getDay();
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const totalCells = Math.ceil((firstWeekday + daysInMonth) / 7) * 7;

  const goPrev = () => setCursor(new Date(year, month - 1, 1));
  const goNext = () => setCursor(new Date(year, month + 1, 1));
  const goToday = () => setCursor(new Date(today.getFullYear(), today.getMonth(), 1));

  // ---- expand each routine's recurrence into this month's day buckets ----
  const DAY_MS = 86400000;
  const sod = (d) => { const x = new Date(d); x.setHours(0, 0, 0, 0); return x; };
  // Per-occurrence status: the next-due anchor carries the real status; earlier
  // projected cycles read as muted/done; later cycles as upcoming.
  const occStatus = (occ, anchor) => {
    const od = +sod(occ), ad = +sod(anchor), td = +today;
    if (od === ad) { const diff = (ad - td) / DAY_MS; return diff < 0 ? 'overdue' : diff <= 14 ? 'soon' : 'ok'; }
    if (od < td) return 'done';
    const diff = (od - td) / DAY_MS;
    return diff <= 14 ? 'soon' : 'ok';
  };
  const occurrencesInMonth = (r) => {
    if (!r.date) return [];
    const anchor = sod(new Date(r.date + 'T00:00:00'));
    const iv = window.Hub.freqInterval(r.freq);
    const out = [];
    if (!iv) {
      if (anchor.getFullYear() === year && anchor.getMonth() === month) out.push(new Date(year, month, anchor.getDate()));
      return out;
    }
    if (iv.months) {
      const span = (year * 12 + month) - (anchor.getFullYear() * 12 + anchor.getMonth());
      if ((((span % iv.months) + iv.months) % iv.months) === 0) {
        out.push(new Date(year, month, Math.min(anchor.getDate(), daysInMonth)));
      }
      return out;
    }
    // day-based (weekly / every 2 weeks)
    const monthStart = new Date(year, month, 1);
    const monthEnd = new Date(year, month, daysInMonth);
    const k = Math.floor((+sod(monthStart) - +anchor) / (DAY_MS * iv.days));
    let occ = new Date(anchor); occ.setDate(occ.getDate() + k * iv.days);
    let guard = 0;
    while (occ < monthStart && guard++ < 60) occ.setDate(occ.getDate() + iv.days);
    guard = 0;
    while (occ <= monthEnd && guard++ < 60) { out.push(new Date(occ)); occ = new Date(occ); occ.setDate(occ.getDate() + iv.days); }
    return out;
  };

  const eventsByDay = {};
  visible.forEach(r => {
    if (!r.date) return;
    const anchor = sod(new Date(r.date + 'T00:00:00'));
    occurrencesInMonth(r).forEach(occ => {
      (eventsByDay[occ.getDate()] = eventsByDay[occ.getDate()] || []).push({ r, status: occStatus(occ, anchor), kind: 'due' });
    });
  });
  // Reminders for this month — distinct visual treatment.
  visible.forEach(r => {
    const rd = window.Hub.reminderDate(r);
    if (!rd) return;
    if (rd.getFullYear() === year && rd.getMonth() === month) {
      const day = rd.getDate();
      (eventsByDay[day] = eventsByDay[day] || []).push({ r, status: 'reminder', kind: 'reminder' });
    }
  });
  const rank = { overdue: 0, soon: 1, reminder: 2, ok: 3, done: 4 };
  Object.values(eventsByDay).forEach(list => list.sort((a, b) => rank[a.status] - rank[b.status]));

  const overdueRoutines = visible.filter(r => r.status === 'overdue');
  const usedCats = [...new Set(visible.map(r => (findAsset(r.asset) || {}).cat).filter(Boolean))];

  return (
    <>
      <TopBar t={t}
        title="Routines"
        sub={`${monthLabel} · click any event to open it`}
        actions={<>
          {(() => {
            const g = (window.Account.current().calendar || {}).google;
            return g ? (
              <span onClick={() => nav.go('profile')} title="Manage calendar sync" style={{ cursor: 'pointer', display: 'inline-flex' }}>
                <Pill t={t} color={t.ok} bg={t.okBg}><HIcon kind="sync" size={12}/> Synced to Google Calendar</Pill>
              </span>
            ) : (
              <Btn t={t} onClick={() => nav.go('profile')}><HIcon kind="cal" size={14}/> Connect calendar</Btn>
            );
          })()}
          <Btn t={t} onClick={goPrev} title="Previous month"><HIcon kind="chev" size={14} style={{ transform: 'rotate(180deg)' }}/></Btn>
          <Btn t={t} onClick={goToday} title="Jump to the current month">Today</Btn>
          <Btn t={t} onClick={goNext} title="Next month"><HIcon kind="chev" size={14}/></Btn>
          <Btn t={t} primary onClick={() => nav.openAdd('routine')}><HIcon kind="plus" size={14}/> Routine</Btn>
        </>}
      />
      {ROUTINES.length === 0 ? (
        <EmptyState t={t} icon="repeat"
          title="No routines yet"
          body="Routines are the recurring upkeep that keeps your home running — filter changes, services, seasonal tasks."
          primaryLabel="Add a routine" onPrimary={() => nav.openAdd('routine')}
          secondaryLabel="Browse assets" onSecondary={() => nav.go('assets')}/>
      ) : (
      <>
      <div className="hh-routines" style={{ padding: '20px 28px 28px', display: 'grid', gridTemplateColumns: '1fr 280px', gap: 16, alignItems: 'flex-start' }}>
        {/* Calendar */}
        <Card t={t} pad={14}>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', marginBottom: 6 }}>
            {['Sun','Mon','Tue','Wed','Thu','Fri','Sat'].map((d, i) => (
              <div key={i} style={{ textAlign: 'center', fontSize: 11, color: t.inkFaint, fontWeight: 600, letterSpacing: 0.5, paddingBottom: 6 }}>{d.toUpperCase()}</div>
            ))}
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gridAutoRows: '110px', gap: 6 }}>
            {Array.from({ length: totalCells }, (_, i) => {
              const dayNum = i - firstWeekday + 1;
              const inMonth = dayNum >= 1 && dayNum <= daysInMonth;
              const events = inMonth ? (eventsByDay[dayNum] || []) : [];
              const isToday = inMonth && isCurrentMonth && dayNum === todayDay;
              const shown = events.slice(0, 3);
              const extra = events.length - shown.length;
              return (
                <div key={i} style={{
                  border: `1px solid ${isToday ? t.accent : t.divider}`,
                  borderRadius: 9, padding: 7,
                  background: isToday ? t.okBg : (inMonth ? t.card : 'transparent'),
                  opacity: inMonth ? 1 : 0.4, overflow: 'hidden',
                  display: 'flex', flexDirection: 'column', gap: 3,
                }}>
                  <div style={{
                    fontSize: 12, fontFamily: SR_MONO,
                    color: isToday ? t.accentDeep : t.inkSoft,
                    fontWeight: isToday ? 700 : 500,
                  }}>{inMonth ? dayNum : ''}</div>
                  {shown.map(({ r, status, kind }, k) => {
                    const isReminder = kind === 'reminder';
                    const isDone = status === 'done';
                    const tone = isReminder
                      ? { c: t.info || t.inkSoft, bg: t.infoBg }
                      : isDone ? { c: t.inkFaint, bg: t.inputBg } : statusTone(t, status);
                    const a = findAsset(r.asset);
                    const icon = isReminder ? 'bell' : a ? (CAT_ICON[a.cat] || 'repeat') : 'repeat';
                    const reminderLbl = isReminder ? window.Hub.reminderLabel(r) : '';
                    return (
                      <div key={r.id + '-' + k + '-' + kind} onClick={() => nav.openRoutine(r.id)} style={{
                        fontSize: 11, padding: '2px 6px', borderRadius: 5, cursor: 'pointer',
                        background: isReminder ? 'transparent' : tone.bg,
                        color: isDone ? t.inkFaint : t.ink, fontWeight: 500,
                        border: isReminder ? `1px dashed ${tone.c}` : '1px solid transparent',
                        display: 'flex', alignItems: 'center', gap: 5,
                      }} title={isReminder
                        ? `Reminder · ${r.task}${a ? ' · ' + a.name : ''} · ${reminderLbl} · due ${r.nextLabel}`
                        : `${r.task}${a ? ' · ' + a.name : ''} · ${r.nextLabel}${r.synced ? ' · on calendar' : ''}`}>
                        <HIcon kind={icon} size={11} style={{ color: tone.c, flex: '0 0 auto' }}/>
                        <span style={{ flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{r.task}</span>
                        {!isReminder && r.synced && <HIcon kind="cal" size={10} style={{ flex: '0 0 auto', opacity: 0.6 }}/>}
                      </div>
                    );
                  })}
                  {extra > 0 && <div style={{ fontSize: 10.5, color: t.inkFaint, paddingLeft: 3 }}>+{extra} more</div>}
                </div>
              );
            })}
          </div>
        </Card>

        {/* Rail */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <Card t={t} pad={16}>
            <PanelHeader t={t} title={<span style={{ color: t.overdue }}>Overdue · {overdueRoutines.length}</span>}/>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
              {overdueRoutines.map(r => {
                const a = findAsset(r.asset);
                return (
                  <div key={r.id} onClick={() => nav.openRoutine(r.id)} style={{ display: 'flex', gap: 10, cursor: 'pointer', alignItems: 'center' }}>
                    <StatusDot color={t.overdue} size={8} style={{ marginTop: 5, flex: '0 0 auto' }}/>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 13, color: t.ink, fontWeight: 500 }}>{r.task}</div>
                      <div style={{ fontSize: 12, color: t.inkSoft }}>{a ? a.name + ' · ' : ''}{r.nextLabel}</div>
                    </div>
                  </div>
                );
              })}
              {overdueRoutines.length === 0 && <div style={{ fontSize: 13, color: t.inkFaint }}>Nothing overdue here.</div>}
            </div>
          </Card>
          <Card t={t} pad={16}>
            <PanelHeader t={t} title="Legend"/>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8, fontSize: 13, color: t.inkSoft }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 9, whiteSpace: 'nowrap' }}><StatusDot color={t.overdue} size={8}/> Overdue</div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 9, whiteSpace: 'nowrap' }}><StatusDot color={t.soon} size={8}/> Due soon</div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 9, whiteSpace: 'nowrap' }}><StatusDot color={t.ok} size={8}/> On track</div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 9, whiteSpace: 'nowrap' }}>
                <span style={{ width: 14, height: 10, borderRadius: 3, border: `1px dashed ${t.info || t.inkSoft}`, flex: '0 0 auto' }}/> Reminder
              </div>
            </div>
            {usedCats.length > 0 && (
              <>
                <div style={{ height: 1, background: t.divider, margin: '13px 0' }}/>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 9, fontSize: 13, color: t.ink }}>
                  {usedCats.map(c => (
                    <div key={c} style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
                      <HIcon kind={CAT_ICON[c] || 'grid'} size={15} style={{ color: t.inkSoft }}/>
                      {c}
                    </div>
                  ))}
                </div>
              </>
            )}
          </Card>
          <UpcomingPanel t={t} nav={nav}/>
        </div>
      </div>
      </>
      )}
    </>
  );
};

// ============================================================
// Contacts — shared bits (tappable links, logo, AI enrichment)
// ============================================================
const telHref = (s) => 'tel:' + String(s || '').replace(/[^+\d]/g, '');

const PhoneValue = ({ t, value, mono = true }) => isGap(value)
  ? <span style={{ fontSize: 13, color: t.soon, fontFamily: mono ? SR_MONO : 'inherit' }}>{value}</span>
  : <a href={telHref(value)} title={`Call ${value}`}
      onMouseEnter={e => e.currentTarget.style.color = t.accentDeep}
      onMouseLeave={e => e.currentTarget.style.color = t.ink}
      style={{ fontSize: 13, color: t.ink, fontFamily: mono ? SR_MONO : 'inherit', textDecoration: 'none' }}>{value}</a>;

const EmailValue = ({ t, value }) => isGap(value)
  ? <span style={{ fontSize: 13, color: t.soon }}>{value}</span>
  : <a href={'mailto:' + value} title={`Email ${value}`}
      onMouseEnter={e => e.currentTarget.style.color = t.accentDeep}
      onMouseLeave={e => e.currentTarget.style.color = t.ink}
      style={{ fontSize: 13, color: t.ink, textDecoration: 'none', wordBreak: 'break-all' }}>{value}</a>;

const CompanyLogo = ({ t, c, size = 44, radius = 11 }) => {
  const [ok, setOk] = React.useState(true);
  const initials = c.co.split(' ').slice(0, 2).map(w => w[0]).join('');
  // Use an explicit logo if set, otherwise derive one for free from the
  // website domain (no API key, falls back to initials if it doesn't load).
  const domain = (c.website || '').replace(/^https?:\/\//i, '').replace(/^www\./i, '').replace(/\/.*$/, '').trim();
  const src = c.logo || (domain ? 'https://logo.clearbit.com/' + domain : '');
  if (src && ok) {
    return <img src={src} alt="" onError={() => setOk(false)} style={{
      width: size, height: size, borderRadius: radius, objectFit: 'contain',
      background: '#fff', border: `1px solid ${t.border}`, flex: '0 0 auto', padding: 4, boxSizing: 'border-box',
    }}/>;
  }
  return <div style={{
    width: size, height: size, borderRadius: radius, flex: '0 0 auto',
    background: t.inputBg, border: `1px solid ${t.border}`,
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    color: t.inkSoft, fontWeight: 600, fontSize: Math.round(size * 0.32), fontFamily: SR_DISPLAY,
  }}>{initials}</div>;
};

// One labelled contact-method row in the Company card.
const CompanyInfoRow = ({ t, icon, children }) => (
  <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
    <span style={{ width: 28, height: 28, borderRadius: 8, flex: '0 0 auto', background: t.inputBg, border: `1px solid ${t.border}`, color: t.inkSoft, display: 'flex', alignItems: 'center', justifyContent: 'center' }}><HIcon kind={icon} size={14}/></span>
    <div style={{ flex: 1, minWidth: 0 }}>{children}</div>
  </div>
);

// ============================================================
// Contacts — card grid
// ============================================================
const HifiContactsScreen = ({ t, nav }) => (
  <>
    <TopBar t={t}
      title="Contacts"
      sub={`${CONTACTS.length} companies`}
      actions={<>
        <Btn t={t} onClick={() => nav.openSearch()}><HIcon kind="search" size={14}/> Find</Btn>
        <Btn t={t} primary onClick={() => nav.openAdd('contact')}><HIcon kind="plus" size={14}/> Contact</Btn>
      </>}
    />
    {CONTACTS.length === 0 ? (
      <EmptyState t={t} icon="phone"
        title="No contacts yet"
        body="Keep the companies and people who service your home in one place — plumbers, electricians, the pool company — and link them to the assets they look after."
        primaryLabel="Add your first contact" onPrimary={() => nav.openAdd('contact')}/>
    ) : (
    <div className="hh-cols-3" style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 16, padding: '20px 28px 28px', alignContent: 'flex-start' }}>
      {CONTACTS.map(c => {
        const linkedAssets = assetsByContact(c.id);
        return (
          <Card key={c.id} t={t} pad={18} onClick={() => nav.openContact(c.id)} style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            <div style={{ display: 'flex', alignItems: 'flex-start', gap: 13 }}>
              <CompanyLogo t={t} c={c} size={44} radius={11}/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <Eyebrow t={t}>{c.cat}</Eyebrow>
                <div style={{ fontFamily: SR_DISPLAY, fontSize: 19, fontWeight: 600, letterSpacing: -0.3, color: t.ink, lineHeight: 1.15, marginTop: 3 }}>{c.co}</div>
              </div>
            </div>
            <div style={{ fontSize: 13, color: c.people.length ? t.inkSoft : t.soon }}>
              {c.people.length > 0 ? `${c.people.length} contact${c.people.length > 1 ? 's' : ''}` : '? add phone & email'}
            </div>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginTop: 'auto' }}>
              {linkedAssets.slice(0, 3).map(a => <Pill t={t} key={a.id}>{a.name}</Pill>)}
              {linkedAssets.length === 0 && <Pill t={t}>no linked assets</Pill>}
              {linkedAssets.length > 3 && <Pill t={t}>+{linkedAssets.length - 3}</Pill>}
            </div>
          </Card>
        );
      })}
    </div>
    )}
  </>
);

// ============================================================
// Contact detail
// ============================================================
const HifiContactDetailScreen = ({ t, nav, contactId }) => {
  const c = findContact(contactId);
  if (!c) return null;
  const linkedAssets = assetsByContact(c.id);
  const linkedRoutines = routinesByContact(c.id);
  const hasCompanyInfo = c.website || c.phone || c.email || c.address || c.description;
  return (
    <>
      <TopBar t={t}
        title={c.co}
        breadcrumb={<><TLink t={t} onClick={() => nav.go('contacts')}>Contacts</TLink> <span style={{ color: t.inkFaint }}>/</span> {c.cat} <span style={{ color: t.inkFaint }}>/</span> {c.co}</>}
        sub={`${c.cat} · service & maintenance`}
        actions={<>
          <Btn t={t} onClick={() => nav.openEdit('contact', c)}>Edit</Btn>
          <Btn t={t} primary onClick={() => nav.openPerson(c.id)}><HIcon kind="plus" size={14}/> Person</Btn>
        </>}
      />
      <div className="hh-split-2" style={{ padding: '20px 28px 28px', display: 'grid', gridTemplateColumns: '1.7fr 1fr', gap: 16, alignItems: 'flex-start' }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <Card t={t} pad={18}>
            <PanelHeader t={t} title="People" action={<Btn t={t} onClick={() => nav.openPerson(c.id)} style={{ padding: '5px 10px', fontSize: 12 }}><HIcon kind="plus" size={12}/> add person</Btn>}/>
            {c.people.length === 0 && (
              <div style={{ color: t.inkSoft, fontSize: 13, padding: '20px 0', textAlign: 'center' }}>
                No individuals saved yet. <TLink t={t} onClick={() => nav.openPerson(c.id)}>Add the first one.</TLink>
              </div>
            )}
            {c.people.map((p, i) => (
              <div key={i} style={{
                display: 'flex', gap: 12, alignItems: 'center',
                padding: '12px 0', borderTop: i ? `1px solid ${t.divider}` : 'none',
              }}>
                <div className="hh-person-info" style={{ flex: 1, minWidth: 0, display: 'grid', gridTemplateColumns: '1.1fr 0.9fr 1fr 1.2fr', gap: 14, alignItems: 'center' }}>
                  <span style={{ fontSize: 14, color: t.ink, fontWeight: 500 }}>{p.name}</span>
                  <span style={{ fontSize: 13, color: p.role ? t.inkSoft : t.inkFaint }}>{p.role || '—'}</span>
                  <PhoneValue t={t} value={p.phone}/>
                  <EmailValue t={t} value={p.email}/>
                </div>
                <div style={{ display: 'flex', gap: 4, flex: '0 0 auto' }}>
                  <IconBtn t={t} kind="pencil" title="Edit person" onClick={() => nav.openPerson(c.id, i)} style={{ width: 30, height: 30, borderRadius: 8 }}/>
                  <IconBtn t={t} kind="trash" title="Remove person" onClick={() => nav.removePerson(c.id, i)} style={{ width: 30, height: 30, borderRadius: 8 }}/>
                </div>
              </div>
            ))}
          </Card>
          <Card t={t} pad={18}>
            <PanelHeader t={t} title="Notes"/>
            <EditableNote t={t} value={c.notes} placeholder="Add account numbers, what they handle, scheduling notes…"
              onSave={(v) => { window.Hub.update('contact', c.id, { notes: v }); nav.refresh(); }}/>
          </Card>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <Card t={t} pad={18}>
            <PanelHeader t={t} title="Company"/>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: hasCompanyInfo ? 14 : 12 }}>
              <CompanyLogo t={t} c={c} size={48} radius={12}/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <Eyebrow t={t}>{c.cat}</Eyebrow>
                <div style={{ fontFamily: SR_DISPLAY, fontSize: 16, fontWeight: 600, color: t.ink, lineHeight: 1.15, marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{c.co}</div>
              </div>
            </div>
            {c.description && <div style={{ fontSize: 13, color: t.inkSoft, lineHeight: 1.5, marginBottom: 14 }}>{c.description}</div>}
            {hasCompanyInfo ? (
              <div style={{ display: 'flex', flexDirection: 'column', gap: 11 }}>
                {c.website && (
                  <CompanyInfoRow t={t} icon="globe">
                    <a href={(/^https?:\/\//i.test(c.website) ? c.website : 'https://' + c.website)} target="_blank" rel="noopener noreferrer"
                      style={{ fontSize: 13, color: t.ink, textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 5 }}
                      onMouseEnter={e => e.currentTarget.style.color = t.accentDeep} onMouseLeave={e => e.currentTarget.style.color = t.ink}>
                      {c.website.replace(/^https?:\/\//i, '')} <HIcon kind="external" size={12} style={{ opacity: 0.6 }}/>
                    </a>
                  </CompanyInfoRow>
                )}
                {c.phone && <CompanyInfoRow t={t} icon="phone"><PhoneValue t={t} value={c.phone} mono={false}/></CompanyInfoRow>}
                {c.email && <CompanyInfoRow t={t} icon="mail"><EmailValue t={t} value={c.email}/></CompanyInfoRow>}
                {c.address && (
                  <CompanyInfoRow t={t} icon="home">
                    <a href={'https://www.google.com/maps/search/?api=1&query=' + encodeURIComponent(c.address)} target="_blank" rel="noopener noreferrer"
                      style={{ fontSize: 13, color: t.ink, textDecoration: 'none', lineHeight: 1.4 }}
                      onMouseEnter={e => e.currentTarget.style.color = t.accentDeep} onMouseLeave={e => e.currentTarget.style.color = t.ink}>
                      {c.address}
                    </a>
                  </CompanyInfoRow>
                )}
                <Btn t={t} onClick={() => nav.openEdit('contact', c)} style={{ marginTop: 3, padding: '6px 11px', fontSize: 12, alignSelf: 'flex-start' }}><HIcon kind="pencil" size={12}/> edit details</Btn>
              </div>
            ) : (
              <div>
                <div style={{ fontSize: 12.5, color: t.inkFaint, lineHeight: 1.5, marginBottom: 12 }}>
                  No company details yet. Add the website, phone, email, and address — the logo fills in from the website automatically.
                </div>
                <Btn t={t} onClick={() => nav.openEdit('contact', c)} style={{ padding: '7px 12px', fontSize: 12.5 }}><HIcon kind="plus" size={13}/> Add company details</Btn>
              </div>
            )}
          </Card>
          <Card t={t} pad={18}>
            <PanelHeader t={t} title={`Linked assets · ${linkedAssets.length}`}/>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {linkedAssets.map(a => (
                <div key={a.id} onClick={() => nav.openAsset(a.id)} style={{ display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer' }}>
                  <HIcon kind={CAT_ICON[a.cat] || 'grid'} size={16} style={{ color: t.inkSoft }}/>
                  <TLink t={t} style={{ fontSize: 14 }}>{a.name}</TLink>
                </div>
              ))}
              {linkedAssets.length === 0 && <div style={{ color: t.inkFaint, fontSize: 13 }}>None linked yet.</div>}
            </div>
            <Btn t={t} onClick={() => nav.openLink(c.id)} style={{ marginTop: 12, padding: '6px 11px', fontSize: 12 }}><HIcon kind="plus" size={12}/> link asset</Btn>
          </Card>
          <Card t={t} pad={18}>
            <PanelHeader t={t} title={`Routines they handle · ${linkedRoutines.length}`}/>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 11 }}>
              {linkedRoutines.map(r => {
                const tone = statusTone(t, r.status);
                return (
                  <div key={r.id} onClick={() => nav.openRoutine(r.id)} style={{ display: 'flex', gap: 10, cursor: 'pointer' }}>
                    <StatusDot color={tone.c} size={8} style={{ marginTop: 5 }}/>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 13, color: t.ink, fontWeight: 500 }}>{r.task}</div>
                      <div style={{ fontSize: 12, color: t.inkSoft }}>{findAsset(r.asset) ? findAsset(r.asset).name : '—'}</div>
                    </div>
                  </div>
                );
              })}
              {linkedRoutines.length === 0 && <div style={{ color: t.inkFaint, fontSize: 13 }}>None.</div>}
            </div>
          </Card>
        </div>
      </div>
    </>
  );
};

// ============================================================
// To-Dos — filter chips + table
// ============================================================
const HifiTodosScreen = ({ t, nav }) => {
  const [filter, setFilter] = React.useState('open');
  const openN = TODOS.filter(td => td.status !== 'Done').length;
  const doneN = TODOS.filter(td => td.status === 'Done').length;
  const taskN = TODOS.filter(td => td.type === 'Task').length;
  const gapN  = TODOS.filter(td => td.type === 'Info Gap').length;
  const filtered = TODOS.filter(td => {
    if (filter === 'open') return td.status !== 'Done';
    if (filter === 'done') return td.status === 'Done';
    if (filter === 'tasks') return td.type === 'Task';
    if (filter === 'gaps') return td.type === 'Info Gap';
    if (filter === 'high') return td.priority === 'High';
    return true;
  });
  const prioTone = p => p === 'High' ? { c: t.overdue, bg: t.overdueBg } : p === 'Normal' ? { c: t.inkSoft, bg: t.infoBg } : { c: t.inkFaint, bg: t.infoBg };
  return (
    <>
      <TopBar t={t}
        title="To-Dos"
        sub={`${openN} open · ${doneN} done · ${taskN} tasks · ${gapN} info gaps`}
        actions={<>
          <Btn t={t} onClick={() => nav.openSearch()}><HIcon kind="search" size={14}/> Search</Btn>
          <Btn t={t} primary onClick={() => nav.openAdd('todo')}><HIcon kind="plus" size={14}/> New</Btn>
        </>}
      />
      {TODOS.length === 0 ? (
        <EmptyState t={t} icon="check"
          title="No to-dos yet"
          body="One-off tasks and missing-info reminders land here — like tracking down a model number or scheduling a repair. Add your first one."
          primaryLabel="Add a to-do" onPrimary={() => nav.openAdd('todo')}/>
      ) : (
      <>
      <div style={{ display: 'flex', gap: 8, padding: '16px 28px 4px', flexWrap: 'wrap', alignItems: 'center' }}>
        <FilterChip t={t} active={filter === 'open'} onClick={() => setFilter('open')}>Open · {openN}</FilterChip>
        <FilterChip t={t} active={filter === 'done'} color={t.ok} onClick={() => setFilter('done')}>Done · {doneN}</FilterChip>
        <FilterChip t={t} active={filter === 'tasks'} onClick={() => setFilter('tasks')}>Tasks · {taskN}</FilterChip>
        <FilterChip t={t} active={filter === 'gaps'} color={t.soon} onClick={() => setFilter('gaps')}>Info gaps · {gapN}</FilterChip>
        <FilterChip t={t} active={filter === 'high'} color={t.overdue} onClick={() => setFilter('high')}>High priority</FilterChip>
        <span style={{ flex: 1 }}/>
        <Btn t={t}><HIcon kind="filter" size={14}/> Sort: priority</Btn>
      </div>
      <div style={{ padding: '16px 28px 28px' }}>
        <Card t={t} pad={0} className="hh-scroll-x" style={{ overflow: 'hidden' }}>
          {/* header */}
          <div style={{
            display: 'grid', gridTemplateColumns: '24px 1fr 92px 90px 140px 92px', gap: 14, alignItems: 'center',
            padding: '12px 18px', borderBottom: `1px solid ${t.border}`, background: t.paper,
          }}>
            <span/>
            <span style={{ fontSize: 11, color: t.inkFaint, fontWeight: 600, letterSpacing: 0.6 }}>TASK</span>
            <span style={{ fontSize: 11, color: t.inkFaint, fontWeight: 600, letterSpacing: 0.6 }}>TYPE</span>
            <span style={{ fontSize: 11, color: t.inkFaint, fontWeight: 600, letterSpacing: 0.6 }}>PRIORITY</span>
            <span style={{ fontSize: 11, color: t.inkFaint, fontWeight: 600, letterSpacing: 0.6 }}>ASSET</span>
            <span style={{ fontSize: 11, color: t.inkFaint, fontWeight: 600, letterSpacing: 0.6 }}>STATUS</span>
          </div>
          {filtered.map((td, i) => {
            const a = td.asset ? findAsset(td.asset) : null;
            const pt = prioTone(td.priority);
            const done = td.status === 'Done';
            return (
              <div key={td.id} style={{
                display: 'grid', gridTemplateColumns: '24px 1fr 92px 90px 140px 92px', gap: 14, alignItems: 'center',
                padding: '13px 18px', borderTop: i ? `1px solid ${t.divider}` : 'none',
                opacity: done ? 0.6 : 1,
              }}>
                <span onClick={() => nav.toggleTodo(td.id)} style={{
                  width: 18, height: 18, borderRadius: 5, cursor: 'pointer',
                  border: `1.5px solid ${done ? t.ok : t.border}`, background: done ? t.ok : t.inputBg,
                  display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff',
                }}>{done && <HIcon kind="check" size={12}/>}</span>
                <span style={{ fontSize: 14, color: done ? t.inkFaint : t.ink, fontWeight: 500, textDecoration: done ? 'line-through' : 'none' }}>{td.title}</span>
                <span><Pill t={t} color={td.type === 'Info Gap' ? t.soon : t.inkSoft} bg={td.type === 'Info Gap' ? t.soonBg : t.infoBg}>{td.type}</Pill></span>
                <span><Pill t={t} color={pt.c} bg={pt.bg}>{td.priority}</Pill></span>
                <span style={{ fontSize: 13 }}>{a ? <TLink t={t} onClick={() => nav.openAsset(a.id)}>{a.name}</TLink> : <span style={{ color: t.inkFaint }}>—</span>}</span>
                <span style={{ fontSize: 13, color: done ? t.ok : t.inkSoft, fontWeight: done ? 600 : 400 }}>{td.status}</span>
              </div>
            );
          })}
          {filtered.length === 0 && (
            <div style={{ padding: '34px 18px', textAlign: 'center', fontSize: 13, color: t.inkFaint }}>Nothing matches this filter.</div>
          )}
        </Card>
      </div>
      </>
      )}
    </>
  );
};

// ============================================================
// Settings — minimal but real (profile, appearance, notifications)
// ============================================================
const ToggleRow = ({ t, label, sub, on }) => {
  const [v, setV] = React.useState(on);
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '14px 0', borderTop: `1px solid ${t.divider}` }}>
      <div style={{ flex: 1 }}>
        <div style={{ fontSize: 14, color: t.ink, fontWeight: 500 }}>{label}</div>
        {sub && <div style={{ fontSize: 12, color: t.inkSoft, marginTop: 2 }}>{sub}</div>}
      </div>
      <button onClick={() => setV(!v)} style={{
        width: 42, height: 24, borderRadius: 999, border: 'none', cursor: 'pointer', padding: 2,
        background: v ? t.accent : t.border, transition: 'background 0.15s ease',
        display: 'flex', justifyContent: v ? 'flex-end' : 'flex-start',
      }}>
        <span style={{ width: 20, height: 20, borderRadius: '50%', background: t.card, boxShadow: '0 1px 2px rgba(0,0,0,0.2)' }}/>
      </button>
    </div>
  );
};

const HifiSettingsScreen = ({ t, nav, themeId, onTheme }) => (
  <>
    <TopBar t={t} title="Settings" sub="Account, appearance, and notifications"/>
    <div style={{ padding: '20px 28px 28px', maxWidth: 760, display: 'flex', flexDirection: 'column', gap: 16 }}>
      <Card t={t} pad={20}>
        <PanelHeader t={t} title="Profile"/>
        <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
          <div style={{
            width: 56, height: 56, borderRadius: '50%',
            background: `linear-gradient(135deg, ${t.accent} 0%, ${t.accentDeep} 100%)`,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: t.accentInk, fontWeight: 600, fontSize: 22, flex: '0 0 auto',
          }}>R</div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 16, color: t.ink, fontWeight: 600 }}>Robert</div>
            <div style={{ fontSize: 13, color: t.inkSoft }}>Homeowner · Milton, ON</div>
          </div>
          <Btn t={t}>Edit profile</Btn>
        </div>
      </Card>

      <Card t={t} pad={20}>
        <PanelHeader t={t} title="Appearance"/>
        <div style={{ fontSize: 13, color: t.inkSoft, marginBottom: 14 }}>Choose a palette for the whole app.</div>
        <div style={{ display: 'flex', gap: 12 }}>
          {Object.values(window.HIFI.THEMES).map(th => (
            <button key={th.id} onClick={() => onTheme(th.id)} style={{
              flex: 1, textAlign: 'left', cursor: 'pointer',
              border: `1.5px solid ${themeId === th.id ? t.ink : t.border}`,
              borderRadius: 12, padding: 14, background: t.card,
            }}>
              <div style={{ display: 'flex', gap: 6, marginBottom: 10 }}>
                <span style={{ width: 22, height: 22, borderRadius: 6, background: th.accent }}/>
                <span style={{ width: 22, height: 22, borderRadius: 6, background: th.paper, border: `1px solid ${t.border}` }}/>
                <span style={{ width: 22, height: 22, borderRadius: 6, background: th.soon }}/>
              </div>
              <div style={{ fontSize: 14, color: t.ink, fontWeight: 600 }}>{th.name}</div>
              <div style={{ fontSize: 12, color: t.inkSoft, marginTop: 3, lineHeight: 1.4 }}>{th.blurb}</div>
            </button>
          ))}
        </div>
      </Card>

      <Card t={t} pad={20}>
        <PanelHeader t={t} title="Notifications"/>
        <ToggleRow t={t} label="Overdue reminders" sub="Email me when a routine becomes overdue" on={true}/>
        <ToggleRow t={t} label="Due-soon digest" sub="Weekly summary of what's coming up" on={true}/>
        <ToggleRow t={t} label="Info-gap nudges" sub="Remind me to fill in missing make/model details" on={false}/>
      </Card>
    </div>
  </>
);

Object.assign(window, {
  HifiRoutinesScreen, HifiContactsScreen, HifiContactDetailScreen,
  HifiTodosScreen, HifiSettingsScreen,
});
