// Rules (conversational), Scenes, Activity, Cameras, Devices, Family, Settings, Waste detail

// ── RULES ────────────────────────────────────────────────────
function RulesScreen({ store, cfg, onBack }) {
  const { rules, family, geofences, devices } = store;
  const [composing, setComposing] = React.useState(false);
  const trackedFamily = family.filter(f => f.tracker_id);
  const roomOptions = [...new Set(devices.map(d => d.room).filter(Boolean))];

  const makeDraft = React.useCallback(() => ({
    name: '',
    conditionType: trackedFamily[0]?.tracker_id && geofences[0]?.id ? 'user_in_zone' : 'all_users_away',
    conditionUser: trackedFamily[0]?.tracker_id || '',
    conditionZone: geofences[0]?.id || 'home',
    conditionDeviceId: devices[0]?.id || '',
    conditionValue: 20,
    conditionTime: '22:00',
    includeTimeGate: false,
    gateTime: '22:00',
    actionType: roomOptions[0] ? 'room_control' : 'notify',
    actionRoom: roomOptions[0] || 'Living Room',
    actionDeviceId: devices[0]?.id || '',
    actionName: 'off',
    actionValue: 50,
    notifyTitle: 'HomeHub automation',
    notifyMessage: 'A smart rule was triggered.',
    cooldown: 5,
  }), [trackedFamily, geofences, devices, roomOptions]);

  const [draft, setDraft] = React.useState(makeDraft);

  const openComposer = () => {
    setDraft(makeDraft());
    setComposing(true);
  };

  const applyPreset = (preset) => {
    setDraft(prev => ({ ...makeDraft(), ...prev, ...preset }));
    setComposing(true);
  };

  const presets = [
    {
      label: 'Nobody home → turn off a room',
      data: { conditionType: 'all_users_away', actionType: 'room_control', actionRoom: roomOptions[0] || 'Living Room', actionName: 'off', notifyTitle: 'Everyone is away', notifyMessage: `Switched off ${roomOptions[0] || 'the room'}.` },
    },
    {
      label: 'Someone arrives home → send alert',
      data: { conditionType: 'user_in_zone', conditionUser: trackedFamily[0]?.tracker_id || '', conditionZone: geofences[0]?.id || 'home', actionType: 'notify', notifyTitle: `${trackedFamily[0]?.name || 'Someone'} arrived`, notifyMessage: `${trackedFamily[0]?.name || 'A family member'} entered ${geofences[0]?.name || 'home'}.` },
    },
    {
      label: 'Battery low → notify',
      data: { conditionType: 'battery_below', conditionUser: trackedFamily[0]?.tracker_id || '', conditionValue: 20, actionType: 'notify', notifyTitle: 'Battery low', notifyMessage: `${trackedFamily[0]?.name || 'Family member'} battery dropped below 20%.` },
    },
  ];

  const buildCondition = () => {
    switch (draft.conditionType) {
      case 'all_users_away':
        return { type: 'all_users_away', label: 'Nobody is home' };
      case 'any_user_home':
        return { type: 'any_user_home', label: 'Someone is home' };
      case 'user_in_zone':
        return draft.conditionUser && draft.conditionZone ? { type: 'user_in_zone', user: draft.conditionUser, zone: draft.conditionZone, label: `${trackedFamily.find(f => f.tracker_id === draft.conditionUser)?.name || draft.conditionUser} is in ${geofences.find(g => g.id === draft.conditionZone)?.name || draft.conditionZone}` } : null;
      case 'user_not_in_zone':
        return draft.conditionUser && draft.conditionZone ? { type: 'user_not_in_zone', user: draft.conditionUser, zone: draft.conditionZone, label: `${trackedFamily.find(f => f.tracker_id === draft.conditionUser)?.name || draft.conditionUser} is not in ${geofences.find(g => g.id === draft.conditionZone)?.name || draft.conditionZone}` } : null;
      case 'zone_empty':
        return draft.conditionZone ? { type: 'zone_empty', zone: draft.conditionZone, label: `${geofences.find(g => g.id === draft.conditionZone)?.name || draft.conditionZone} is empty` } : null;
      case 'zone_occupied':
        return draft.conditionZone ? { type: 'zone_occupied', zone: draft.conditionZone, label: `${geofences.find(g => g.id === draft.conditionZone)?.name || draft.conditionZone} is occupied` } : null;
      case 'device_on':
        return draft.conditionDeviceId ? { type: 'device_on', deviceId: Number(draft.conditionDeviceId), label: `${devices.find(d => String(d.id) === String(draft.conditionDeviceId))?.name || 'Device'} is on` } : null;
      case 'device_off':
        return draft.conditionDeviceId ? { type: 'device_off', deviceId: Number(draft.conditionDeviceId), label: `${devices.find(d => String(d.id) === String(draft.conditionDeviceId))?.name || 'Device'} is off` } : null;
      case 'time_after':
        return draft.conditionTime ? { type: 'time_after', time: draft.conditionTime, label: `After ${draft.conditionTime}` } : null;
      case 'time_before':
        return draft.conditionTime ? { type: 'time_before', time: draft.conditionTime, label: `Before ${draft.conditionTime}` } : null;
      case 'battery_below':
        return draft.conditionUser ? { type: 'battery_below', user: draft.conditionUser, value: Number(draft.conditionValue) || 20, label: `${trackedFamily.find(f => f.tracker_id === draft.conditionUser)?.name || draft.conditionUser} battery below ${Number(draft.conditionValue) || 20}%` } : null;
      default:
        return null;
    }
  };

  const buildAction = () => {
    switch (draft.actionType) {
      case 'room_control':
        return draft.actionRoom ? { type: 'room_control', room: draft.actionRoom, action: draft.actionName, value: draft.actionName === 'brightness' ? Number(draft.actionValue) || 50 : undefined, label: `${draft.actionName === 'on' ? 'Turn on' : draft.actionName === 'off' ? 'Turn off' : 'Adjust'} ${draft.actionRoom}` } : null;
      case 'device_control':
        return draft.actionDeviceId ? { type: 'device_control', deviceId: Number(draft.actionDeviceId), action: draft.actionName, value: ['brightness', 'setpoint', 'temperature'].includes(draft.actionName) ? Number(draft.actionValue) || 50 : undefined, label: `${draft.actionName} ${devices.find(d => String(d.id) === String(draft.actionDeviceId))?.name || 'device'}` } : null;
      case 'notify':
        return { type: 'notify', title: draft.notifyTitle || 'HomeHub automation', message: draft.notifyMessage || 'A smart rule was triggered.', label: draft.notifyTitle || 'Send notification' };
      default:
        return null;
    }
  };

  const primaryCondition = buildCondition();
  const timeGate = draft.includeTimeGate && draft.gateTime ? { type: 'time_after', time: draft.gateTime, label: `After ${draft.gateTime}` } : null;
  const primaryAction = buildAction();
  const rulePayload = primaryCondition && primaryAction ? {
    name: (draft.name || `${primaryCondition.label} → ${primaryAction.label}`).slice(0, 80),
    description: `${primaryCondition.label}${timeGate ? ` and ${timeGate.label.toLowerCase()}` : ''} → ${primaryAction.label}`,
    conditions: timeGate ? [primaryCondition, timeGate] : [primaryCondition],
    actions: [primaryAction],
    cooldown_minutes: Number(draft.cooldown) || 5,
    enabled: true,
  } : null;

  const selectStyle = { height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 10px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none', width: '100%' };
  const inputStyle = { height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 10px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none', width: '100%' };

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <SubHeader title="Smart Rules" onBack={onBack} trailing={
        <button onClick={openComposer} className="press hh-btn accent" style={{ height: 36, padding: '0 14px' }}>
          <Icon name="plus" size={14} color="#fff"/>New
        </button>
      }/>

      <div className="hh-scroll" style={{ flex: 1, overflow: 'auto', paddingBottom: 20 }}>
        {/* Hero compose */}
        <div style={{ padding: '8px 20px 16px' }}>
          <div className="hh-card" style={{ padding: 16, background: 'linear-gradient(135deg, var(--hh-accent-tint), var(--hh-surface))' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
              <Icon name="sparkle" size={18} color="var(--hh-accent)" variant={cfg.iconVariant}/>
              <div style={{ fontSize: 12, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--hh-accent)' }}>Build a real automation</div>
            </div>
            <div className="hh-serif" style={{ fontSize: 20, lineHeight: 1.2, color: 'var(--hh-ink)' }}>Choose a trigger, choose a real action, and send it straight to the rules engine.</div>
            <div style={{ display: 'flex', gap: 8, marginTop: 14, flexWrap: 'wrap' }}>
              {presets.map(preset => (
                <button key={preset.label} onClick={() => applyPreset(preset.data)} className="press" style={{ padding: '10px 14px', borderRadius: 999, background: 'var(--hh-surface)', border: '1px solid var(--hh-line-soft)', fontSize: 12, color: 'var(--hh-ink-soft)' }}>
                  {preset.label}
                </button>
              ))}
            </div>
          </div>
        </div>

        <div className="hh-section-h">Your rules · {rules.length}</div>
        <div style={{ padding: '0 20px', display: 'flex', flexDirection: 'column', gap: 10 }}>
          {rules.map(r => (
            <div key={r.id} className="hh-card" style={{ padding: 14, opacity: r.active ? 1 : 0.65 }}>
              <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>
                <div style={{ width: 34, height: 34, borderRadius: 10, background: r.active ? 'var(--hh-accent-tint)' : 'var(--hh-surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                  <Icon name="sparkle" size={16} color={r.active ? 'var(--hh-accent)' : 'var(--hh-ink-mute)'} variant={cfg.iconVariant}/>
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 4 }}>{r.name}</div>
                  <div className="hh-serif" style={{ fontSize: 14, color: 'var(--hh-ink-soft)', lineHeight: 1.35, fontStyle: 'italic' }}>"{r.text}"</div>
                  <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginTop: 8 }}>
                    {r.then.map((t, i) => (
                      <span key={i} className="hh-pill" style={{ fontSize: 10 }}>{t}</span>
                    ))}
                  </div>
                  <div style={{ display: 'flex', gap: 10, marginTop: 8, fontSize: 11, color: 'var(--hh-ink-mute)' }}>
                    <span>{r.runs} runs</span><span>·</span><span>Last: {r.lastRun}</span>
                  </div>
                </div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6, alignItems: 'flex-end' }}>
                  <Toggle on={r.active} onChange={() => store.toggleRule(r.id)}/>
                  <button onClick={() => store.removeRule(r.id)} className="press" style={{ width: 26, height: 26, borderRadius: 7, background: '#fee2e2', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                    <Icon name="trash2" size={11} color="#ef4444"/>
                  </button>
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* Compose sheet */}
      <Sheet open={composing} onClose={() => setComposing(false)} title="New rule" presentation="modal" width="min(760px, calc(100vw - 20px))">
        <div style={{ padding: '0 20px 20px' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 12 }}>
            <div>
              <div style={{ fontSize: 12, color: 'var(--hh-ink-mute)', marginBottom: 6 }}>Rule name</div>
              <input value={draft.name} onChange={(e) => setDraft(d => ({ ...d, name: e.target.value }))} placeholder="Night shutdown" style={inputStyle}/>
            </div>
            <div>
              <div style={{ fontSize: 12, color: 'var(--hh-ink-mute)', marginBottom: 6 }}>Cooldown</div>
              <input type="number" min="1" max="1440" value={draft.cooldown} onChange={(e) => setDraft(d => ({ ...d, cooldown: Number(e.target.value) || 5 }))} style={inputStyle}/>
            </div>
          </div>

          <div className="hh-section-h" style={{ padding: '12px 0 8px' }}>When</div>
          <div style={{ display: 'grid', gap: 10 }}>
            <select value={draft.conditionType} onChange={(e) => setDraft(d => ({ ...d, conditionType: e.target.value }))} style={selectStyle}>
              <option value="all_users_away">Nobody is home</option>
              <option value="any_user_home">Someone is home</option>
              <option value="user_in_zone">A person enters a zone</option>
              <option value="user_not_in_zone">A person leaves a zone</option>
              <option value="zone_empty">A zone becomes empty</option>
              <option value="zone_occupied">A zone is occupied</option>
              <option value="device_on">A device turns on</option>
              <option value="device_off">A device turns off</option>
              <option value="time_after">After a specific time</option>
              <option value="time_before">Before a specific time</option>
              <option value="battery_below">Battery drops below a threshold</option>
            </select>

            {['user_in_zone', 'user_not_in_zone', 'battery_below'].includes(draft.conditionType) && (
              <select value={draft.conditionUser} onChange={(e) => setDraft(d => ({ ...d, conditionUser: e.target.value }))} style={selectStyle}>
                {trackedFamily.map(f => <option key={f.id} value={f.tracker_id}>{f.name}</option>)}
              </select>
            )}

            {['user_in_zone', 'user_not_in_zone', 'zone_empty', 'zone_occupied'].includes(draft.conditionType) && (
              <select value={draft.conditionZone} onChange={(e) => setDraft(d => ({ ...d, conditionZone: e.target.value }))} style={selectStyle}>
                {geofences.map(g => <option key={g.id} value={g.id}>{g.name}</option>)}
              </select>
            )}

            {['device_on', 'device_off'].includes(draft.conditionType) && (
              <select value={draft.conditionDeviceId} onChange={(e) => setDraft(d => ({ ...d, conditionDeviceId: e.target.value }))} style={selectStyle}>
                {devices.map(device => <option key={device.id} value={device.id}>{device.name}</option>)}
              </select>
            )}

            {['time_after', 'time_before'].includes(draft.conditionType) && (
              <input type="time" value={draft.conditionTime} onChange={(e) => setDraft(d => ({ ...d, conditionTime: e.target.value }))} style={inputStyle}/>
            )}

            {draft.conditionType === 'battery_below' && (
              <input type="number" min="1" max="100" value={draft.conditionValue} onChange={(e) => setDraft(d => ({ ...d, conditionValue: Number(e.target.value) || 20 }))} style={inputStyle}/>
            )}
          </div>

          <div className="hh-section-h" style={{ padding: '12px 0 8px' }}>Optional time gate</div>
          <button onClick={() => setDraft(d => ({ ...d, includeTimeGate: !d.includeTimeGate }))} className="press" style={{ width: '100%', height: 40, borderRadius: 12, border: `1px solid ${draft.includeTimeGate ? 'var(--hh-accent-soft)' : 'var(--hh-line-soft)'}`, background: draft.includeTimeGate ? 'var(--hh-accent-tint)' : 'var(--hh-surface)', color: draft.includeTimeGate ? 'var(--hh-accent)' : 'var(--hh-ink-soft)', fontSize: 13, fontWeight: 600, marginBottom: draft.includeTimeGate ? 10 : 0 }}>
            {draft.includeTimeGate ? `Enabled after ${draft.gateTime}` : 'Add a time-after condition'}
          </button>
          {draft.includeTimeGate && <input type="time" value={draft.gateTime} onChange={(e) => setDraft(d => ({ ...d, gateTime: e.target.value }))} style={inputStyle}/>} 

          <div className="hh-section-h" style={{ padding: '12px 0 8px' }}>Then</div>
          <div style={{ display: 'grid', gap: 10 }}>
            <select value={draft.actionType} onChange={(e) => setDraft(d => ({ ...d, actionType: e.target.value }))} style={selectStyle}>
              <option value="room_control">Control a room</option>
              <option value="device_control">Control a device</option>
              <option value="notify">Send a notification</option>
            </select>

            {draft.actionType === 'room_control' && (
              <>
                <select value={draft.actionRoom} onChange={(e) => setDraft(d => ({ ...d, actionRoom: e.target.value }))} style={selectStyle}>
                  {roomOptions.map(room => <option key={room} value={room}>{room}</option>)}
                </select>
                <select value={draft.actionName} onChange={(e) => setDraft(d => ({ ...d, actionName: e.target.value }))} style={selectStyle}>
                  <option value="off">Turn off</option>
                  <option value="on">Turn on</option>
                  <option value="brightness">Set brightness</option>
                </select>
              </>
            )}

            {draft.actionType === 'device_control' && (
              <>
                <select value={draft.actionDeviceId} onChange={(e) => setDraft(d => ({ ...d, actionDeviceId: e.target.value }))} style={selectStyle}>
                  {devices.map(device => <option key={device.id} value={device.id}>{device.name}</option>)}
                </select>
                <select value={draft.actionName} onChange={(e) => setDraft(d => ({ ...d, actionName: e.target.value }))} style={selectStyle}>
                  <option value="off">Turn off</option>
                  <option value="on">Turn on</option>
                  <option value="toggle">Toggle</option>
                  <option value="brightness">Set brightness</option>
                  <option value="setpoint">Set temperature</option>
                </select>
              </>
            )}

            {((draft.actionType === 'room_control' && draft.actionName === 'brightness') || (draft.actionType === 'device_control' && ['brightness', 'setpoint', 'temperature'].includes(draft.actionName))) && (
              <input type="number" min="0" max="100" value={draft.actionValue} onChange={(e) => setDraft(d => ({ ...d, actionValue: Number(e.target.value) || 50 }))} style={inputStyle}/>
            )}

            {draft.actionType === 'notify' && (
              <>
                <input value={draft.notifyTitle} onChange={(e) => setDraft(d => ({ ...d, notifyTitle: e.target.value }))} placeholder="Notification title" style={inputStyle}/>
                <input value={draft.notifyMessage} onChange={(e) => setDraft(d => ({ ...d, notifyMessage: e.target.value }))} placeholder="Notification message" style={inputStyle}/>
              </>
            )}
          </div>

          <div style={{ marginTop: 16, padding: 14, background: 'var(--hh-accent-tint)', borderRadius: 14, border: '1px solid var(--hh-accent-soft)' }}>
            <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--hh-accent)', fontWeight: 600, marginBottom: 6 }}>Will create</div>
            <div style={{ fontSize: 13, color: 'var(--hh-ink)' }}>{rulePayload ? rulePayload.description : 'Choose a valid trigger and action.'}</div>
          </div>

          <button onClick={() => { if (rulePayload) { store.addRule(rulePayload); setComposing(false); } }}
            className="hh-btn accent press" style={{ width: '100%', marginTop: 16, height: 48 }}>Create rule</button>
        </div>
      </Sheet>
    </div>
  );
}

// ── Generic sub-header ────────────────────────────────────────
function SubHeader({ title, onBack, trailing }) {
  return (
    <div style={{ padding: '14px 16px 10px', display: 'flex', alignItems: 'center', gap: 8 }}>
      <button onClick={onBack} className="press" style={{ width: 38, height: 38, borderRadius: 999, background: 'var(--hh-surface)', border: '1px solid var(--hh-line-soft)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M15 18l-6-6 6-6"/></svg>
      </button>
      <div style={{ flex: 1 }}>
        <div className="hh-serif" style={{ fontSize: 22 }}>{title}</div>
      </div>
      {trailing}
    </div>
  );
}

// ── SCENES ───────────────────────────────────────────────────
const SCENE_ICONS_LIST = ['sparkles','lightbulb','home','moon','sun','coffee','tv','music','shield','flame','snowflake','wind','bell'];
const SCENE_COLORS = ['#8b5cf6','#3b82f6','#22c55e','#f97316','#ef4444','#ec4899','#14b8a6','#eab308','#6366f1','#a855f7'];
const SCENE_EMOJI_MAP = { sparkles:'✨', lightbulb:'💡', home:'🏠', moon:'🌙', sun:'☀️', coffee:'☕', tv:'📺', music:'🎵', shield:'🛡', flame:'🔥', snowflake:'❄️', wind:'💨', bell:'🔔' };
const DEVICE_ACTIONS_LIST = [{ v:'on', l:'Turn ON' },{ v:'off', l:'Turn OFF' },{ v:'toggle', l:'Toggle' },{ v:'setpoint', l:'Set temp' },{ v:'brightness', l:'Set brightness' }];

function ScenesScreen({ store, cfg, onBack }) {
  const { scenes, devices } = store;
  const [showForm, setShowForm] = React.useState(false);
  const [editId, setEditId] = React.useState(null);
  const [name, setName] = React.useState('');
  const [icon, setIcon] = React.useState('sparkles');
  const [color, setColor] = React.useState('#8b5cf6');
  const [actions, setActions] = React.useState([]);

  const resetForm = () => { setName(''); setIcon('sparkles'); setColor('#8b5cf6'); setActions([]); setEditId(null); setShowForm(false); };

  const openEdit = (s) => {
    setEditId(s.id); setName(s.name); setIcon(s._raw?.icon || 'sparkles'); setColor(s.color || '#8b5cf6');
    setActions(Array.isArray(s._raw?.actions) ? s._raw.actions : []); setShowForm(true);
  };

  const handleSave = () => {
    if (!name.trim()) return;
    const payload = { name: name.trim(), icon, color, actions };
    if (editId) store.updateScene(editId, payload);
    else store.createScene(payload);
    resetForm();
  };

  const addAction = () => setActions(a => [...a, { type: 'device_control', deviceId: '', action: 'toggle', value: null }]);
  const updateAction = (i, patch) => setActions(a => a.map((x, idx) => idx === i ? { ...x, ...patch } : x));
  const removeAction = (i) => setActions(a => a.filter((_, idx) => idx !== i));

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <SubHeader title="Scenes" onBack={onBack} trailing={
        <button onClick={() => { resetForm(); setShowForm(true); }} className="press hh-btn accent" style={{ height: 36, padding: '0 14px' }}><Icon name="plus" size={14} color="#fff"/>New</button>
      }/>
      <div className="hh-scroll" style={{ flex: 1, overflow: 'auto', padding: '0 16px 20px' }}>
        {showForm && (
          <div className="hh-card" style={{ padding: 14, marginBottom: 14 }}>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr auto', gap: 8, marginBottom: 8 }}>
              <input value={name} onChange={(e) => setName(e.target.value)} placeholder="Scene name"
                style={{ height: 40, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 12px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}/>
              <input type="color" value={color} onChange={(e) => setColor(e.target.value)}
                style={{ width: 42, height: 40, borderRadius: 10, border: '1px solid var(--hh-line-soft)', background: 'var(--hh-surface-2)', cursor: 'pointer' }}/>
            </div>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 10 }}>
              {SCENE_ICONS_LIST.map(ic => (
                <button key={ic} onClick={() => setIcon(ic)} className="press" style={{ width: 34, height: 34, borderRadius: 10, border: `2px solid ${icon === ic ? color : 'var(--hh-line-soft)'}`, background: icon === ic ? color + '22' : 'var(--hh-surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 16 }}>
                  {SCENE_EMOJI_MAP[ic] || '✨'}
                </button>
              ))}
            </div>
            <div className="hh-section-h" style={{ padding: '4px 0 8px' }}>Actions</div>
            {actions.map((a, i) => (
              <div key={i} style={{ display: 'flex', gap: 6, marginBottom: 6 }}>
                <select value={a.deviceId || ''} onChange={(e) => updateAction(i, { deviceId: Number(e.target.value) })}
                  style={{ flex: 2, height: 36, borderRadius: 8, border: '1px solid var(--hh-line-soft)', padding: '0 6px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', fontSize: 12, outline: 'none' }}>
                  <option value="">Device…</option>
                  {devices.map(d => <option key={d.id} value={d.id}>{d.name}</option>)}
                </select>
                <select value={a.action || 'toggle'} onChange={(e) => updateAction(i, { action: e.target.value })}
                  style={{ flex: 1, height: 36, borderRadius: 8, border: '1px solid var(--hh-line-soft)', padding: '0 4px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', fontSize: 12, outline: 'none' }}>
                  {DEVICE_ACTIONS_LIST.map(x => <option key={x.v} value={x.v}>{x.l}</option>)}
                </select>
                {(a.action === 'setpoint' || a.action === 'brightness') && (
                  <input type="number" value={a.value ?? ''} onChange={(e) => updateAction(i, { value: Number(e.target.value) })}
                    style={{ width: 52, height: 36, borderRadius: 8, border: '1px solid var(--hh-line-soft)', padding: '0 6px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', fontSize: 12, outline: 'none' }}/>
                )}
                <button onClick={() => removeAction(i)} className="press" style={{ width: 34, height: 36, borderRadius: 8, background: '#fee2e2', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <Icon name="trash2" size={12} color="#ef4444"/>
                </button>
              </div>
            ))}
            <button onClick={addAction} className="press" style={{ width: '100%', height: 34, borderRadius: 8, border: '1px dashed var(--hh-line)', background: 'transparent', fontSize: 12, color: 'var(--hh-ink-mute)', marginBottom: 10 }}>+ Add action</button>
            <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
              <button onClick={resetForm} className="press hh-btn ghost" style={{ height: 36 }}>Cancel</button>
              <button onClick={handleSave} className="press hh-btn accent" style={{ height: 36, padding: '0 18px' }}>{editId ? 'Update' : 'Create'}</button>
            </div>
          </div>
        )}

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
          {scenes.map(s => (
            <div key={s.id} style={{ position: 'relative' }}>
              <button onClick={() => store.activateScene(s.id)} className="press" style={{
                width: '100%', padding: 16, borderRadius: 20, textAlign: 'left', minHeight: 130,
                background: s.active ? `linear-gradient(135deg, ${s.color}, ${s.color}cc)` : 'var(--hh-surface)',
                border: `1px solid ${s.active ? s.color : 'var(--hh-line-soft)'}`,
                color: s.active ? '#fff' : 'var(--hh-ink)',
                display: 'flex', flexDirection: 'column', justifyContent: 'space-between',
                boxShadow: s.active ? 'var(--hh-shadow-lg)' : 'var(--hh-shadow-sm)',
              }}>
                <div>
                  <div style={{ fontSize: 36, marginBottom: 8 }}>{s.emoji}</div>
                  <div className="hh-serif" style={{ fontSize: 20 }}>{s.name}</div>
                  <div style={{ fontSize: 11, opacity: 0.8, marginTop: 2 }}>{s.note}</div>
                </div>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 12, fontSize: 11, opacity: 0.85 }}>
                  <span>{s.devices} devices</span>
                  {s.active ? <span style={{ fontWeight: 600 }}>● Active</span> : <Icon name="play" size={12}/>}
                </div>
              </button>
              <div style={{ position: 'absolute', top: 8, right: 8, display: 'flex', gap: 4 }}>
                <button onClick={(e) => { e.stopPropagation(); openEdit(s); }} className="press" style={{ width: 26, height: 26, borderRadius: 7, background: 'rgba(0,0,0,0.25)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <Icon name="edit" size={11} color="#fff"/>
                </button>
                <button onClick={(e) => { e.stopPropagation(); store.removeScene(s.id); }} className="press" style={{ width: 26, height: 26, borderRadius: 7, background: 'rgba(200,50,50,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <Icon name="trash2" size={11} color="#fff"/>
                </button>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ── ACTIVITY ─────────────────────────────────────────────────
function ActivityScreen({ store, cfg, onBack }) {
  const { activity } = store;
  const [filter, setFilter] = React.useState('all');
  const filtered = filter === 'all' ? activity : activity.filter(a => a.cat === filter);
  const iconFor = { device: 'plug', rule: 'sparkle', geo: 'pin', list: 'list', camera: 'camera', scene: 'bolt' };
  const colorFor = { device: 'var(--hh-sage)', rule: 'var(--hh-accent)', geo: 'var(--hh-mustard)', list: 'var(--hh-sky)', camera: 'var(--hh-plum)', scene: 'var(--hh-clay)' };
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <SubHeader title="Activity" onBack={onBack}/>
      <div className="hh-hscroll hh-scroll" style={{ padding: '0 16px 10px' }}>
        {[['all','All'],['device','Devices'],['rule','Rules'],['geo','Location'],['camera','Cameras'],['list','Lists'],['scene','Scenes']].map(([id,l]) => (
          <Chip key={id} active={filter === id} onClick={() => setFilter(id)}>{l}</Chip>
        ))}
      </div>
      <div className="hh-scroll" style={{ flex: 1, overflow: 'auto', padding: '0 20px 20px' }}>
        <div className="hh-card">
          {filtered.map((a, i) => (
            <div key={a.id} style={{ padding: '14px', display: 'flex', gap: 12, alignItems: 'center', borderBottom: i < filtered.length - 1 ? '1px solid var(--hh-line-soft)' : 'none' }}>
              <div style={{ width: 34, height: 34, borderRadius: 10, background: colorFor[a.cat] + '22', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <Icon name={iconFor[a.cat]} size={16} color={colorFor[a.cat]} variant={cfg.iconVariant}/>
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 13 }}><b>{a.who}</b> {a.action}</div>
                <div className="hh-mono" style={{ fontSize: 10, color: 'var(--hh-ink-mute)', marginTop: 2 }}>{a.time} · today</div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ── CAMERAS ──────────────────────────────────────────────────
function extractCameraStreamUrl(payload) {
  if (!payload || typeof payload !== 'object') return '';

  const candidates = [
    payload.url,
    payload.hls,
    payload.hls_url,
    payload.m3u8,
    payload.m3u8_url,
    payload.play_url,
    payload.stream?.url,
    payload.stream?.hls,
    payload.stream?.hls_url,
    payload.stream?.m3u8,
    payload.stream?.m3u8_url,
    payload.stream?.play_url,
    payload.stream?.result?.url,
    payload.stream?.result?.hls,
    payload.stream?.result?.hls_url,
    payload.stream?.result?.m3u8,
    payload.stream?.result?.m3u8_url,
  ];

  const nested = payload.stream?.urls;
  if (Array.isArray(nested)) {
    for (const entry of nested) {
      if (typeof entry === 'string') {
        candidates.push(entry);
      } else if (entry && typeof entry === 'object') {
        candidates.push(entry.url, entry.hls, entry.hls_url, entry.m3u8, entry.m3u8_url, entry.play_url);
      }
    }
  }

  const selected = candidates.find((value) => typeof value === 'string' && /^https?:\/\//i.test(value.trim()));
  return selected ? selected.trim() : '';
}

function CameraFeed({ device, store }) {
  const videoRef = React.useRef(null);
  const hlsRef = React.useRef(null);
  const retryTimerRef = React.useRef(null);
  const [state, setState] = React.useState('idle'); // idle | loading | playing | error
  const [retries, setRetries] = React.useState(0);

  const cleanup = () => {
    if (retryTimerRef.current) { clearTimeout(retryTimerRef.current); retryTimerRef.current = null; }
    if (hlsRef.current) { hlsRef.current.destroy(); hlsRef.current = null; }
    if (videoRef.current) {
      videoRef.current.pause();
      videoRef.current.removeAttribute('src');
      videoRef.current.load();
    }
  };

  const startStream = async () => {
    setState('loading');
    cleanup();
    try {
      const integration = device?._raw?.integration || '';
      const storedUrl = device?._raw?.stream_url || device?.stream_url || '';
      let url = storedUrl;

      if (!device?._raw && !storedUrl) {
        setState('error');
        return;
      }

      // Tuya HLS URLs are signed and short-lived; always ask for a fresh one.
      if (integration === 'tuya_cloud') {
        const res = await store.allocateStream(device.id);
        url = extractCameraStreamUrl(res) || url;
      }
      if (!url) { setState('error'); return; }
      if (url.startsWith('rtsp://')) { setState('rtsp'); return; }

      const video = videoRef.current;
      if (!video) return;

      video.muted = true;
      video.playsInline = true;
      video.autoplay = true;
      video.preload = 'auto';
      video.crossOrigin = 'anonymous';
      video.onloadeddata = () => setState('playing');
      video.onplaying = () => setState('playing');
      video.onstalled = () => setState('loading');
      video.onerror = () => setState('error');

      // Native HLS (Safari)
      if (video.canPlayType('application/vnd.apple.mpegurl')) {
        video.src = url;
        const playPromise = video.play();
        if (playPromise && typeof playPromise.catch === 'function') {
          playPromise.catch(() => setState('error'));
        }
        return;
      }

      // hls.js
      if (window.Hls && window.Hls.isSupported()) {
        const hls = new window.Hls({ enableWorker: true, lowLatencyMode: true });
        hlsRef.current = hls;
        hls.loadSource(url);
        hls.attachMedia(video);
        hls.on(window.Hls.Events.MANIFEST_PARSED, () => {
          video.play().catch(() => setState('error'));
        });
        hls.on(window.Hls.Events.LEVEL_LOADED, () => {
          setState('playing');
        });
        hls.on(window.Hls.Events.ERROR, (_, data) => {
          if (data.fatal && retries < 3) { setRetries(r => r + 1); retryTimerRef.current = setTimeout(startStream, 2500); }
          else if (data.fatal) setState('error');
        });
      } else {
        // Fallback
        video.src = url;
        video.play().catch(() => setState('error'));
      }
    } catch {
      if (retries < 3) { setRetries(r => r + 1); retryTimerRef.current = setTimeout(startStream, 2500); }
      else setState('error');
    }
  };

  React.useEffect(() => {
    setRetries(0);
    setState('idle');
    const timer = setTimeout(() => { startStream(); }, 120);
    return () => {
      clearTimeout(timer);
      cleanup();
    };
  }, [device && device.id]);

  return (
    <div style={{ borderRadius: 14, overflow: 'hidden', aspectRatio: '16/9', background: '#111', position: 'relative' }}>
      <video ref={videoRef} muted autoPlay playsInline style={{ width: '100%', height: '100%', objectFit: 'cover', display: state === 'playing' ? 'block' : 'none' }}/>
      {state === 'idle' && (
        <button onClick={startStream} className="press" style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 8, background: 'rgba(0,0,0,0.6)', color: '#fff', fontSize: 13 }}>
          <span style={{ fontSize: 32 }}>▶</span>
          <span>Tap to load stream</span>
        </button>
      )}
      {state === 'loading' && (
        <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: 13 }}>
          Allocating stream…
        </div>
      )}
      {state === 'error' && (
        <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 8, color: '#fff', fontSize: 13 }}>
          <span>Stream failed</span>
          <button onClick={() => { setRetries(0); startStream(); }} className="press hh-btn accent" style={{ height: 32, padding: '0 14px', fontSize: 12 }}>Retry</button>
        </div>
      )}
      {state === 'rtsp' && (
        <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 8, color: '#fff', fontSize: 13, textAlign: 'center', padding: 20 }}>
          <span>RTSP stream detected</span>
          <span style={{ opacity: 0.75 }}>Expose an HLS or browser-playable stream URL for this camera.</span>
        </div>
      )}
      <div style={{ position: 'absolute', top: 8, left: 8 }}>
        <span style={{ background: state === 'playing' ? '#C9562E' : '#555', color: '#fff', padding: '2px 8px', borderRadius: 4, fontSize: 10, fontWeight: 600 }}>
          {state === 'playing' ? '● LIVE' : device.name}
        </span>
      </div>
      {state === 'playing' && (
        <div style={{ position: 'absolute', top: 8, right: 8, background: 'rgba(0,0,0,0.5)', color: '#fff', padding: '2px 8px', borderRadius: 4, fontSize: 10 }}>{device.name}</div>
      )}
    </div>
  );
}

function CamerasScreen({ store, cfg, onBack }) {
  const cameraDevices = store.devices.filter(d => d.type === 'camera');
  const allCams = cameraDevices;
  const [focusIdx, setFocusIdx] = React.useState(0);
  const focusCam = allCams[focusIdx] || allCams[0] || null;

  React.useEffect(() => {
    if (focusIdx >= allCams.length) setFocusIdx(0);
  }, [allCams.length, focusIdx]);

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden', background: '#0f0a08' }}>
      <div style={{ padding: '14px 16px 10px', display: 'flex', alignItems: 'center', gap: 8, color: '#fff' }}>
        <button onClick={onBack} className="press" style={{ width: 38, height: 38, borderRadius: 999, background: 'rgba(255,255,255,0.12)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M15 18l-6-6 6-6"/></svg>
        </button>
        <div style={{ flex: 1 }}>
          <div className="hh-serif" style={{ fontSize: 22, color: '#fff' }}>Cameras</div>
        </div>
        <span className="hh-pill" style={{ background: 'rgba(230,50,50,0.25)', color: '#ffb4b4', border: '1px solid rgba(230,50,50,0.4)' }}>● LIVE</span>
      </div>

      {/* Focused camera */}
      {focusCam && (
        <div style={{ padding: '0 14px 10px' }}>
          <div style={{ borderRadius: 22, overflow: 'hidden', background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.08)' }}>
            <CameraFeed device={focusCam} store={store}/>
            <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10, padding: '12px 14px', color: '#fff' }}>
              <div>
                <div className="hh-serif" style={{ fontSize: 20, color: '#fff' }}>{focusCam.name}</div>
                <div style={{ fontSize: 12, color: 'rgba(255,255,255,0.65)', marginTop: 2 }}>{focusCam.room || focusCam.location || 'Camera feed'}</div>
              </div>
              <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', justifyContent: 'flex-end' }}>
                <span className="hh-pill" style={{ background: 'rgba(255,255,255,0.08)', color: '#fff', border: '1px solid rgba(255,255,255,0.12)' }}>{cameraDevices.length} configured</span>
                <span className="hh-pill" style={{ background: 'rgba(255,255,255,0.08)', color: '#fff', border: '1px solid rgba(255,255,255,0.12)' }}>{focusCam._raw?.integration || 'camera'}</span>
              </div>
            </div>
          </div>
        </div>
      )}

      <div style={{ padding: '0 14px 10px', fontSize: 12, color: 'rgba(255,255,255,0.6)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>All cameras · {allCams.length}</div>
      <div style={{ flex: 1, overflow: 'auto', padding: '0 14px 20px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
        {allCams.map((c, i) => (
          <button key={c.id} onClick={() => setFocusIdx(i)} className="press" style={{
            borderRadius: 14, overflow: 'hidden', position: 'relative', aspectRatio: '4/3',
            background: focusIdx === i ? 'linear-gradient(135deg, rgba(201,86,46,0.45), rgba(34,24,18,0.95))' : 'linear-gradient(135deg, rgba(255,255,255,0.08), rgba(17,17,17,0.95))', textAlign: 'left',
            border: focusIdx === i ? '2px solid var(--hh-accent)' : '1px solid rgba(255,255,255,0.08)',
          }}>
            <div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(circle at top right, rgba(255,255,255,0.14), transparent 45%)' }} />
            <div style={{ position: 'absolute', bottom: 8, left: 8, right: 8, color: '#fff' }}>
              <div style={{ fontSize: 12, fontWeight: 600 }}>{c.name}</div>
              <div style={{ fontSize: 10, opacity: 0.75 }}>{c.room || ''}</div>
            </div>
          </button>
        ))}
      </div>

      {allCams.length === 0 && (
        <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'rgba(255,255,255,0.5)', fontSize: 14 }}>
          No cameras configured. Add camera devices first.
        </div>
      )}
    </div>
  );
}

// ── DEVICES ──────────────────────────────────────────────────
const DEVICE_TYPES = [
  { value: 'light', label: 'Light (Tuya Local)' },
  { value: 'strip', label: 'LED Strip (Tuya Local)' },
  { value: 'plug', label: 'Power Plug (Tuya Local)' },
  { value: 'ac', label: 'AC (SmartThings)' },
  { value: 'washer', label: 'Washer (SmartThings)' },
  { value: 'camera', label: 'Camera' },
];
const ROOMS = ['Living Room','Bedroom','Kitchen','Bathroom','Office','Hallway','Garage','Garden'];
const INTEGRATIONS = { light: 'tuya', strip: 'tuya', plug: 'tuya', ac: 'smartthings', washer: 'smartthings', camera: 'camera_local' };

function DevicesScreen({ store, cfg, onBack, onOpenDevice }) {
  const { devices } = store;
  const [filter, setFilter] = React.useState('all');
  const [showForm, setShowForm] = React.useState(false);
  const [editId, setEditId] = React.useState(null);
  const [form, setForm] = React.useState({ name: '', type: 'light', room: 'Living Room', device_id: '', ip: '', local_key: '', version: '3.3', integration: '' });
  const [discovering, setDiscovering] = React.useState(false);
  const [discovered, setDiscovered] = React.useState([]);
  const [discoverErrors, setDiscoverErrors] = React.useState([]);
  const rooms = [...new Set(devices.map(d => d.room).filter(Boolean))];
  const filtered = filter === 'all' ? devices : filter === 'on' ? devices.filter(d => d.on) : devices.filter(d => d.room === filter);
  const onCount = devices.filter(d => d.on).length;
  const cameraCount = devices.filter(d => d.type === 'camera').length;
  const cloudCount = devices.filter(d => d._raw?.integration === 'tuya_cloud' || d._raw?.integration === 'smartthings').length;

  const resetForm = () => {
    setForm({ name: '', type: 'light', room: 'Living Room', device_id: '', ip: '', local_key: '', version: '3.3', integration: '' });
    setEditId(null);
  };

  const startEdit = (d) => {
    setEditId(d.id);
    setForm({
      name: d.name, type: d._raw?.type || d.type,
      room: d.room || 'Living Room',
      device_id: d._raw?.device_id || '',
      ip: d._raw?.ip || '',
      local_key: '', // never expose
      version: d._raw?.version || '3.3',
      integration: d._raw?.integration || '',
    });
    setShowForm(true);
  };

  const handleAdd = (e) => {
    e.preventDefault();
    if (!form.name.trim()) return;
    const payload = { name: form.name, type: form.type, room: form.room, integration: form.integration || INTEGRATIONS[form.type] || 'tuya', device_id: form.device_id, ip: form.ip, local_key: form.local_key, version: form.version };
    if (editId) {
      store.updateDeviceData(editId, payload);
    } else {
      store.createDevice(payload);
    }
    resetForm();
    setShowForm(false);
  };

  const handleDiscover = async () => {
    setDiscovering(true);
    setDiscovered([]);
    setDiscoverErrors([]);
    try {
      const res = await store.discoverDevices();
      setDiscovered(res.devices || []);
      setDiscoverErrors(res.errors || []);
    } catch {}
    setDiscovering(false);
  };

  const addDiscovered = (dev) => {
    store.createDevice({
      name: dev.label || dev.name,
      type: dev.type || 'light',
      integration: dev.integration || 'tuya_cloud',
      device_id: dev.device_id,
      room: 'Living Room',
    });
    setDiscovered(ds => ds.map(d => d.device_id === dev.device_id ? { ...d, alreadyLinked: true } : d));
  };

  // Room toggle — bulk on/off for a room
  const handleRoomToggle = (room) => {
    const roomDevices = devices.filter(d => d.room === room);
    const anyOn = roomDevices.some(d => d.on);
    store.controlRoom(room, anyOn ? 'off' : 'on').catch(() => {});
  };

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <SubHeader title={`${devices.length} Devices`} onBack={onBack} trailing={
        <div style={{ display: 'flex', gap: 6 }}>
          <button onClick={handleDiscover} disabled={discovering} className="press hh-btn ghost" style={{ height: 36, padding: '0 12px', fontSize: 12 }}>
            {discovering ? '…' : '🔍 Discover'}
          </button>
          <button onClick={() => { resetForm(); setShowForm(v => !v); }} className="press hh-btn accent" style={{ height: 36, padding: '0 14px' }}>
            <Icon name="plus" size={14} color="#fff"/>{showForm ? 'Cancel' : 'Add'}
          </button>
        </div>
      }/>
      <div style={{ padding: '0 16px 12px' }}>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
          {[
            { label: 'Online now', value: onCount },
            { label: 'Rooms', value: rooms.length || '—' },
            { label: 'Cloud', value: cloudCount + cameraCount },
          ].map(stat => (
            <div key={stat.label} className="hh-card" style={{ padding: 14, textAlign: 'center' }}>
              <div className="hh-serif" style={{ fontSize: 24 }}>{stat.value}</div>
              <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginTop: 4 }}>{stat.label}</div>
            </div>
          ))}
        </div>
      </div>
      <div className="hh-hscroll hh-scroll" style={{ padding: '0 16px 10px' }}>
        <Chip active={filter === 'all'} onClick={() => setFilter('all')}>All</Chip>
        <Chip active={filter === 'on'} onClick={() => setFilter('on')}>● On</Chip>
        {rooms.map(r => (
          <Chip key={r} active={filter === r} onClick={() => setFilter(r)}>
            {r}
            <button onClick={(e) => { e.stopPropagation(); handleRoomToggle(r); }} style={{ marginLeft: 4, fontSize: 10, opacity: 0.7 }}>⏻</button>
          </Chip>
        ))}
      </div>

      {/* Discovered devices */}
      {discovered.length > 0 && (
        <div style={{ padding: '0 16px 12px' }}>
          <div className="hh-section-h">Discovered · {discovered.length}</div>
          <div className="hh-card" style={{ padding: 0 }}>
            {discovered.map((dev, i) => (
              <div key={dev.device_id} style={{ padding: 12, display: 'flex', alignItems: 'center', gap: 10, borderBottom: i < discovered.length - 1 ? '1px solid var(--hh-line-soft)' : 'none' }}>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 600 }}>{dev.label || dev.name}</div>
                  <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)' }}>{dev.integration} · {dev.type} · {dev.manufacturer || ''}</div>
                </div>
                {dev.alreadyLinked ? (
                  <span className="hh-pill" style={{ fontSize: 10 }}>Linked</span>
                ) : (
                  <button onClick={() => addDiscovered(dev)} className="press hh-btn accent" style={{ height: 30, padding: '0 12px', fontSize: 11 }}>Add</button>
                )}
              </div>
            ))}
          </div>
          {discoverErrors.length > 0 && (
            <div style={{ padding: '8px 0', fontSize: 11, color: 'var(--hh-bad)' }}>
              {discoverErrors.map((e, i) => <div key={i}>{e.source}: {e.error}</div>)}
            </div>
          )}
        </div>
      )}

      {showForm && (
        <form onSubmit={handleAdd} style={{ padding: '0 16px 12px' }}>
          <div className="hh-card" style={{ padding: 12, display: 'flex', flexDirection: 'column', gap: 8 }}>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
              <input value={form.name} onChange={(e) => setForm(f => ({ ...f, name: e.target.value }))} placeholder="Device name" required
                style={{ height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 10px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}/>
              <select value={form.type} onChange={(e) => setForm(f => ({ ...f, type: e.target.value }))}
                style={{ height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 8px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}>
                {DEVICE_TYPES.map(t => <option key={t.value} value={t.value}>{t.label}</option>)}
              </select>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
              <select value={form.room} onChange={(e) => setForm(f => ({ ...f, room: e.target.value }))}
                style={{ height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 8px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}>
                {ROOMS.map(r => <option key={r} value={r}>{r}</option>)}
              </select>
              <input value={form.device_id} onChange={(e) => setForm(f => ({ ...f, device_id: e.target.value }))} placeholder="Device ID / ST device ID"
                style={{ height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 10px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}/>
            </div>
            <select value={form.integration} onChange={(e) => setForm(f => ({ ...f, integration: e.target.value }))}
              style={{ height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 8px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none', width: '100%' }}>
              <option value="">Auto (based on type)</option>
              <option value="tuya">Tuya Local</option>
              <option value="tuya_cloud">Tuya Cloud</option>
              <option value="smartthings">SmartThings</option>
              <option value="local_http">Local HTTP</option>
            </select>
            {['light','strip','plug'].includes(form.type) && (
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 80px', gap: 8 }}>
                <input value={form.ip} onChange={(e) => setForm(f => ({ ...f, ip: e.target.value }))} placeholder="IP address"
                  style={{ height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 10px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}/>
                <input value={form.local_key} onChange={(e) => setForm(f => ({ ...f, local_key: e.target.value }))} placeholder="Local key"
                  style={{ height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 10px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}/>
                <select value={form.version} onChange={(e) => setForm(f => ({ ...f, version: e.target.value }))}
                  style={{ height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 6px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}>
                  <option>3.1</option><option>3.3</option><option>3.4</option>
                </select>
              </div>
            )}
            <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
              <button type="submit" className="press hh-btn accent" style={{ height: 36, padding: '0 18px' }}>Save device</button>
            </div>
          </div>
        </form>
      )}

      <div className="hh-scroll" style={{ flex: 1, overflow: 'auto', padding: '0 20px 20px' }}>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))', gap: 10 }}>
          {filtered.map(d => (
            <div key={d.id} style={{ position: 'relative' }}>
              <DeviceTile d={d} iconVariant={cfg.iconVariant} onToggle={() => store.toggleDevice(d.id).catch(() => {})} onOpen={() => onOpenDevice(d)}/>
              <div style={{ position: 'absolute', top: 6, right: 6, display: 'flex', gap: 3, zIndex: 1 }}>
                <button onClick={(e) => { e.stopPropagation(); startEdit(d); }} className="press" style={{ width: 22, height: 22, borderRadius: 6, background: 'rgba(0,0,0,0.25)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <Icon name="edit" size={11} color="#fff"/>
                </button>
                <button onClick={(e) => { e.stopPropagation(); store.removeDevice(d.id); }} className="press" style={{ width: 22, height: 22, borderRadius: 6, background: 'rgba(200,50,50,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <Icon name="trash2" size={11} color="#fff"/>
                </button>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ── FAMILY ───────────────────────────────────────────────────
function FamilyMemberEditor({ f, geofences, onSave }) {
  const [trackerId, setTrackerId] = React.useState(f.tracker_id || '');
  const [role, setRole] = React.useState(f.role || 'Member');
  const [saving, setSaving] = React.useState(false);
  const [saved, setSaved] = React.useState(false);

  const isDirty = trackerId !== (f.tracker_id || '') || role !== (f.role || 'Member');

  const handleSave = () => {
    setSaving(true);
    onSave(f.id, { tracker_id: trackerId, role })
      .then(() => { setSaved(true); setTimeout(() => setSaved(false), 2000); })
      .catch(() => {})
      .finally(() => setSaving(false));
  };

  return (
    <div className="hh-card" style={{ padding: 16, marginBottom: 10 }}>
      <div style={{ display: 'flex', gap: 12, alignItems: 'center', marginBottom: 12 }}>
        <Avatar name={f.name} color={f.color} size={52}/>
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 18, fontWeight: 600 }}>{f.name}</div>
          <div style={{ fontSize: 12, color: 'var(--hh-ink-mute)' }}>
            {f.tracked
              ? <span style={{ color: 'var(--hh-sage)' }}>● Live tracking</span>
              : <span>No tracking</span>
            }
          </div>
        </div>
        <span className="hh-pill" style={{ background: f.battery > 30 ? 'var(--hh-sage-soft)' : '#F4CFC3', color: f.battery > 30 ? 'var(--hh-sage)' : 'var(--hh-bad)' }}>{f.battery}%</span>
      </div>

      {/* Editable fields */}
      <div style={{ display: 'grid', gap: 8, marginBottom: 10 }}>
        <div>
          <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginBottom: 4 }}>Tracker Alias <span style={{ opacity: 0.6 }}>(OwnTracks tst — e.g. RL)</span></div>
          <input
            value={trackerId}
            onChange={e => setTrackerId(e.target.value.toUpperCase())}
            placeholder="e.g. RL"
            maxLength={6}
            style={{ width: '100%', height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', background: 'var(--hh-surface-2)', padding: '0 10px', color: 'var(--hh-ink)', fontSize: 13, outline: 'none', boxSizing: 'border-box' }}
          />
        </div>
        <div>
          <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginBottom: 4 }}>Role</div>
          <select
            value={role}
            onChange={e => setRole(e.target.value)}
            style={{ width: '100%', height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', background: 'var(--hh-surface-2)', padding: '0 8px', color: 'var(--hh-ink)', fontSize: 13, outline: 'none', boxSizing: 'border-box' }}
          >
            <option value="Admin">Admin</option>
            <option value="Member">Member</option>
            <option value="Kid">Kid</option>
          </select>
        </div>
      </div>

      {(isDirty || saved) && (
        <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', marginBottom: 10 }}>
          {saved && <span style={{ fontSize: 12, color: 'var(--hh-sage)', display: 'flex', alignItems: 'center', gap: 4 }}>✓ Saved</span>}
          {isDirty && (
            <button onClick={handleSave} disabled={saving} className="press hh-btn accent" style={{ height: 34, padding: '0 14px', fontSize: 12 }}>
              {saving ? 'Saving…' : 'Save'}
            </button>
          )}
        </div>
      )}

      <div className="hh-section-h" style={{ padding: '4px 0 4px' }}>Geofences</div>
      <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
        {geofences.filter(g => g.members.includes(String(f.id))).map(g => (
          <span key={g.id} className="hh-pill" style={{ background: g.color + '22', color: g.color, borderColor: g.color + '55' }}>
            <Icon name="pin" size={10} color={g.color}/>{g.name}
          </span>
        ))}
        {geofences.filter(g => g.members.includes(String(f.id))).length === 0 && (
          <span style={{ fontSize: 12, color: 'var(--hh-ink-mute)' }}>No geofences linked</span>
        )}
      </div>
    </div>
  );
}

function FamilyScreen({ store, cfg, onBack }) {
  const { family, geofences } = store;

  const handleSave = (id, patch) => {
    return new Promise((resolve, reject) => {
      store.updateFamilyMember(id, patch);
      // Optimistically resolve; updateFamilyMember handles errors silently
      resolve();
    });
  };

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <SubHeader title="Family" onBack={onBack}/>
      <div style={{ padding: '0 20px 8px', fontSize: 12, color: 'var(--hh-ink-mute)' }}>
        Set the Tracker Alias to link each person to their OwnTracks device.
      </div>
      <div className="hh-scroll" style={{ flex: 1, overflow: 'auto', padding: '0 20px 20px' }}>
        {family.map(f => (
          <FamilyMemberEditor key={f.id} f={f} geofences={geofences} onSave={handleSave}/>
        ))}
      </div>
    </div>
  );
}

function SettingRow({ label, on }) {
  const [v, setV] = React.useState(on);
  return (
    <div style={{ padding: '8px 10px', background: 'var(--hh-surface-2)', borderRadius: 10, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 6 }}>
      <div style={{ fontSize: 11, color: 'var(--hh-ink-soft)' }}>{label}</div>
      <div className="hh-toggle" data-on={v} onClick={() => setV(!v)} style={{ transform: 'scale(0.75)', transformOrigin: 'right center' }}/>
    </div>
  );
}

// ── WASTE detail ────────────────────────────────────────────
function WasteScreen({ store, cfg, onBack }) {
  const { waste } = store;
  const [showForm, setShowForm] = React.useState(false);
  const [form, setForm] = React.useState({ type: '', next_date: '', color: '#6b7280', icon: 'trash-2', recurrence: 'biweekly', notes: '', reminder_enabled: true, reminder_days_before: 1, reminder_time: '19:00' });
  const ICONS = ['trash-2','leaf','package','newspaper'];
  const sorted = [...waste].sort((a, b) => String(a._raw?.next_date || '').localeCompare(String(b._raw?.next_date || '')));

  const handleAdd = (e) => {
    e.preventDefault();
    if (!form.type || !form.next_date) return;
    store.addWaste(form);
    setForm({ type: '', next_date: '', color: '#6b7280', icon: 'trash-2', recurrence: 'biweekly', notes: '', reminder_enabled: true, reminder_days_before: 1, reminder_time: '19:00' });
    setShowForm(false);
  };

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <SubHeader title="Waste collection" onBack={onBack} trailing={
        <button onClick={() => setShowForm(v => !v)} className="press hh-btn accent" style={{ height: 36, padding: '0 14px' }}>
          <Icon name="plus" size={14} color="#fff"/>Add
        </button>
      }/>
      <div className="hh-scroll" style={{ flex: 1, overflow: 'auto', padding: '0 20px 20px' }}>
        {sorted.length > 0 && (
          <div className="hh-card" style={{ padding: 18, background: `linear-gradient(135deg, ${sorted[0].color}, ${sorted[0].color}cc)`, color: '#fff', marginBottom: 14 }}>
            <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.1em', opacity: 0.85 }}>Put out next</div>
            <div className="hh-serif" style={{ fontSize: 30, marginTop: 4 }}>{sorted[0].type}</div>
            <div style={{ fontSize: 13, marginTop: 4, opacity: 0.9 }}>{sorted[0].next} · {sorted[0].day}</div>
          </div>
        )}

        {showForm && (
          <form onSubmit={handleAdd} className="hh-card" style={{ padding: 14, marginBottom: 14, display: 'flex', flexDirection: 'column', gap: 8 }}>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
              <input value={form.type} onChange={(e) => setForm(f => ({ ...f, type: e.target.value }))} placeholder="Type (e.g. PMD)" required
                style={{ height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 10px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}/>
              <input type="date" value={form.next_date} onChange={(e) => setForm(f => ({ ...f, next_date: e.target.value }))} required
                style={{ height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 8px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}/>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr auto', gap: 8 }}>
              <select value={form.recurrence} onChange={(e) => setForm(f => ({ ...f, recurrence: e.target.value }))}
                style={{ height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 8px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}>
                <option value="weekly">Weekly</option>
                <option value="biweekly">Biweekly</option>
                <option value="monthly">Monthly</option>
              </select>
              <select value={form.icon} onChange={(e) => setForm(f => ({ ...f, icon: e.target.value }))}
                style={{ height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 8px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}>
                {ICONS.map(ic => <option key={ic} value={ic}>{ic}</option>)}
              </select>
              <input type="color" value={form.color} onChange={(e) => setForm(f => ({ ...f, color: e.target.value }))}
                style={{ width: 42, height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', background: 'var(--hh-surface-2)', cursor: 'pointer' }}/>
            </div>
            <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
              <label style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 12, color: 'var(--hh-ink-soft)' }}>
                <input type="checkbox" checked={form.reminder_enabled} onChange={(e) => setForm(f => ({ ...f, reminder_enabled: e.target.checked }))} style={{ accentColor: 'var(--hh-accent)' }}/>
                Reminder
              </label>
              {form.reminder_enabled && (
                <select value={form.reminder_days_before} onChange={(e) => setForm(f => ({ ...f, reminder_days_before: Number(e.target.value) }))}
                  style={{ height: 34, borderRadius: 8, border: '1px solid var(--hh-line-soft)', padding: '0 6px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', fontSize: 12, outline: 'none' }}>
                  <option value={1}>1 day before</option>
                  <option value={2}>2 days before</option>
                  <option value={3}>3 days before</option>
                </select>
              )}
              {form.reminder_enabled && (
                <input type="time" value={form.reminder_time} onChange={(e) => setForm(f => ({ ...f, reminder_time: e.target.value }))}
                  style={{ height: 34, borderRadius: 8, border: '1px solid var(--hh-line-soft)', padding: '0 8px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', fontSize: 12, outline: 'none' }}/>
              )}
              <div style={{ flex: 1 }}/>
              <button type="submit" className="press hh-btn accent" style={{ height: 36, padding: '0 14px' }}>Add</button>
            </div>
          </form>
        )}

        {sorted.length === 0 && !showForm && (
          <p style={{ textAlign: 'center', color: 'var(--hh-ink-mute)', padding: '32px 20px', fontSize: 14 }}>No pickups yet. Tap Add to create one!</p>
        )}

        {sorted.map((w, i) => (
          <div key={w.id || w.type} className="hh-card" style={{ padding: 14, marginBottom: 8, display: 'flex', gap: 12, alignItems: 'center' }}>
            <div style={{ width: 42, height: 42, borderRadius: 12, background: w.color, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 22 }}>{w.icon}</div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 15, fontWeight: 600 }}>{w.type}</div>
              <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginTop: 2 }}>{w._raw?.recurrence || ''} · Remind evening before</div>
              <input type="date" value={w._raw?.next_date || ''} onChange={(e) => store.updateWaste(w.id, { next_date: e.target.value })}
                style={{ marginTop: 4, height: 30, borderRadius: 8, border: '1px solid var(--hh-line-soft)', padding: '0 6px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', fontSize: 11, outline: 'none' }}/>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 4, alignItems: 'flex-end' }}>
              <div className="hh-pill">{w.next}</div>
              <button onClick={() => store.markWasteCollected && store.markWasteCollected(w.id)} className="press" style={{ fontSize: 10, padding: '3px 8px', borderRadius: 6, background: 'var(--hh-sage-soft)', color: 'var(--hh-sage)' }}>Collected</button>
              <button onClick={() => store.removeWaste(w.id)} className="press" style={{ width: 26, height: 26, borderRadius: 6, background: '#fee2e2', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <Icon name="trash2" size={12} color="#ef4444"/>
              </button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ── SETTINGS ────────────────────────────────────────────────
function SettingsScreen({ store, cfg, onNav, user, onLogout }) {
  const displayName = user?.name || 'Guest';
  const linkedCameras = store.devices.filter(d => d.type === 'camera').length;
  const sections = [
    { h: 'Account', items: [
      { icon: 'users', label: 'Family & members', go: 'family', hint: `${store.family.length} people` },
      { icon: 'shield', label: 'Privacy & data', go: 'privacy' },
      { icon: 'bell', label: 'Push notifications', hint: store.pushBusy ? 'Updating…' : (store.pushEnabled ? 'Enabled' : store.pushStatus), action: () => store.togglePush() },
    ]},
    { h: 'Home', items: [
      { icon: 'plug', label: 'Devices', go: 'devices', hint: `${store.devices.length} total` },
      { icon: 'sparkle', label: 'Smart rules', go: 'rules', hint: `${store.rules.filter(r=>r.active).length} active` },
      { icon: 'bolt', label: 'Scenes', go: 'scenes', hint: `${store.scenes.length} scenes` },
      { icon: 'camera', label: 'Cameras', go: 'cameras', hint: `${linkedCameras} linked` },
      { icon: 'trash2', label: 'Waste collection', go: 'waste' },
      { icon: 'bolt', label: 'Activity log', go: 'activity' },
    ]},
    { h: 'Location', items: [
      { icon: 'pin', label: 'Geofences', go: 'map', hint: `${store.geofences.length} zones` },
      { icon: 'route', label: 'Location history', go: 'locHistory', hint: '90 days' },
    ]},
    { h: 'System', items: [
      { icon: 'wifi', label: 'Hubs & bridges', go: 'hubs' },
      { icon: 'droplet', label: 'Energy & utilities', go: 'energy' },
      { icon: 'settings', label: 'App settings', go: 'appSettings' },
    ]},
  ];
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <TopBar title="More" subtitle={`${displayName}'s casa · ${store.devices.length} devices · ${store.family.length} people`}/>
      <div className="hh-scroll" style={{ flex: 1, overflow: 'auto', padding: '0 0 20px' }}>
        <div style={{ padding: '0 20px 10px' }}>
          <div className="hh-card" style={{ padding: 14, display: 'flex', gap: 12, alignItems: 'center' }}>
            <Avatar name={displayName} color="var(--hh-accent)" size={48}/>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 16, fontWeight: 600 }}>{displayName}</div>
              <div style={{ fontSize: 12, color: 'var(--hh-ink-mute)' }}>{user?.role || 'Member'}</div>
            </div>
            {onLogout && (
              <button className="press hh-btn ghost" style={{ height: 34, fontSize: 12 }} onClick={onLogout}>Sign out</button>
            )}
          </div>
        </div>
        {sections.map(sec => (
          <div key={sec.h}>
            <div className="hh-section-h">{sec.h}</div>
            <div className="hh-card" style={{ margin: '0 20px' }}>
              {sec.items.map((it, i) => (
                <div key={it.label} onClick={() => it.go ? onNav(it.go) : it.action ? it.action() : null} className="press" style={{ padding: '14px', display: 'flex', gap: 12, alignItems: 'center', borderBottom: i < sec.items.length - 1 ? '1px solid var(--hh-line-soft)' : 'none', cursor: it.go || it.action ? 'pointer' : 'default' }}>
                  <div style={{ width: 32, height: 32, borderRadius: 9, background: 'var(--hh-accent-tint)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                    <Icon name={it.icon} size={16} color="var(--hh-accent)" variant={cfg.iconVariant}/>
                  </div>
                  <div style={{ flex: 1, fontSize: 14, fontWeight: 500 }}>{it.label}</div>
                  {it.hint && <div style={{ fontSize: 12, color: 'var(--hh-ink-mute)' }}>{it.hint}</div>}
                  <Icon name="chevronR" size={14} color="var(--hh-ink-mute)"/>
                </div>
              ))}
            </div>
          </div>
        ))}
        <div style={{ textAlign: 'center', padding: '24px 20px', color: 'var(--hh-ink-mute)', fontSize: 11 }}>
          <div className="hh-serif" style={{ fontSize: 14, color: 'var(--hh-accent)' }}>HomeHub</div>
          <div className="hh-mono" style={{ marginTop: 4 }}>v 2.4.1 · hub online · local</div>
        </div>
      </div>
    </div>
  );
}

// ── Privacy & Data ──
function PrivacyScreen({ store, cfg, onBack }) {
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <SubHeader title="Privacy & Data" onBack={onBack}/>
      <div className="hh-scroll" style={{ flex: 1, overflow: 'auto', padding: '0 0 20px' }}>
        <div style={{ padding: '0 20px' }}>
          <div className="hh-card" style={{ padding: 16, marginBottom: 12 }}>
            <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 8 }}>Data storage</div>
            <div style={{ fontSize: 13, color: 'var(--hh-ink-soft)', lineHeight: 1.5 }}>
              All data is stored locally on your home server. Nothing is sent to external clouds. Location data is kept for 90 days, then automatically purged.
            </div>
          </div>
          <div className="hh-card" style={{ padding: 16, marginBottom: 12 }}>
            <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 8 }}>Connected services</div>
            {[
              { name: 'SmartThings', desc: 'Device control via local API', status: 'Active' },
              { name: 'Tuya Cloud', desc: 'Device control & camera streams', status: 'Active' },
              { name: 'Open-Meteo', desc: 'Weather data (no API key)', status: 'Active' },
              { name: 'Mapbox', desc: 'Map tiles', status: 'Active' },
            ].map((s, i) => (
              <div key={s.name} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '10px 0', borderTop: i ? '1px solid var(--hh-line-soft)' : 'none' }}>
                <div>
                  <div style={{ fontSize: 13, fontWeight: 500 }}>{s.name}</div>
                  <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)' }}>{s.desc}</div>
                </div>
                <span style={{ fontSize: 11, color: 'var(--hh-good)', fontWeight: 500 }}>{s.status}</span>
              </div>
            ))}
          </div>
          <div className="hh-card" style={{ padding: 16 }}>
            <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 8 }}>Location tracking</div>
            <div style={{ fontSize: 13, color: 'var(--hh-ink-soft)', lineHeight: 1.5, marginBottom: 10 }}>
              Family members share location via the 480tracker app. Each person can disable tracking at any time from their own device.
            </div>
            <div style={{ fontSize: 12, color: 'var(--hh-ink-mute)' }}>
              {store.family.filter(f => f.tracked).length} of {store.family.length} members sharing location
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Location History ──
function LocationHistoryScreen({ store, cfg, onBack }) {
  const [days, setDays] = React.useState(7);
  const logs = store.activity.filter(a => a.cat === 'geo');
  const cutoff = Date.now() / 1000 - days * 86400;
  const filtered = logs.filter(l => {
    const ts = l.timestamp || (l.created_at ? new Date(l.created_at).getTime() / 1000 : 0);
    return ts > cutoff;
  });
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <SubHeader title="Location History" onBack={onBack}/>
      <div style={{ padding: '0 20px 10px', display: 'flex', gap: 6 }}>
        {[7, 30, 90].map(d => (
          <button key={d} onClick={() => setDays(d)} className="press" style={{
            padding: '6px 14px', borderRadius: 999, fontSize: 12, fontWeight: 500,
            background: days === d ? 'var(--hh-ink)' : 'var(--hh-surface-2)',
            color: days === d ? 'var(--hh-bg)' : 'var(--hh-ink-soft)',
          }}>{d}d</button>
        ))}
      </div>
      <div className="hh-scroll" style={{ flex: 1, overflow: 'auto', padding: '0 0 20px' }}>
        <div style={{ padding: '0 20px' }}>
          {filtered.length === 0 && <div style={{ textAlign: 'center', color: 'var(--hh-ink-mute)', padding: '40px 0', fontSize: 13 }}>No location events in this period.</div>}
          {filtered.slice(0, 100).map((l, i) => (
            <div key={l.id || i} style={{ display: 'flex', gap: 10, alignItems: 'flex-start', padding: '10px 0', borderBottom: '1px solid var(--hh-line-soft)' }}>
              <div style={{ width: 28, height: 28, borderRadius: 999, background: 'var(--hh-accent-tint)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, marginTop: 2 }}>
                <Icon name="pin" size={12} color="var(--hh-accent)"/>
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13, fontWeight: 500 }}>{l.description || l.title || 'Location event'}</div>
                <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginTop: 2 }}>{l.created_at ? new Date(l.created_at).toLocaleString() : ''}</div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ── Hubs & Bridges ──
function HubsScreen({ store, cfg, onBack }) {
  const tuyaDevices = store.devices.filter(d => d._raw?.integration === 'tuya_cloud');
  const stDevices = store.devices.filter(d => d._raw?.integration === 'smartthings');
  const localDevices = store.devices.filter(d => d._raw?.integration === 'local_http');
  const [token, setToken] = React.useState('');
  const [saving, setSaving] = React.useState(false);

  React.useEffect(() => {
    store.fetchSmartThingsStatus && store.fetchSmartThingsStatus();
  }, []);

  const smartThingsState = store.smartThingsStatus;
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <SubHeader title="Hubs & Bridges" onBack={onBack}/>
      <div className="hh-scroll" style={{ flex: 1, overflow: 'auto', padding: '0 0 20px' }}>
        <div style={{ padding: '0 20px' }}>
          {[
            { name: 'SmartThings Hub', icon: 'wifi', count: stDevices.length, status: smartThingsState?.valid ? 'Connected' : smartThingsState?.configured ? 'Token needs attention' : 'Not configured' },
            { name: 'Tuya Cloud', icon: 'cloud', count: tuyaDevices.length, status: tuyaDevices.length > 0 ? 'Connected' : 'Not configured' },
            { name: 'Local devices', icon: 'plug', count: localDevices.length, status: localDevices.length > 0 ? 'Active' : 'None' },
          ].map((hub, i) => (
            <div key={hub.name} className="hh-card" style={{ padding: 16, marginBottom: 10 }}>
              <div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
                <div style={{ width: 40, height: 40, borderRadius: 12, background: 'var(--hh-accent-tint)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <Icon name={hub.icon} size={18} color="var(--hh-accent)"/>
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 14, fontWeight: 600 }}>{hub.name}</div>
                  <div style={{ fontSize: 12, color: 'var(--hh-ink-mute)' }}>{hub.count} devices · {hub.status}</div>
                </div>
                <div style={{ width: 10, height: 10, borderRadius: 999, background: hub.count > 0 ? 'var(--hh-good)' : 'var(--hh-ink-mute)' }}/>
              </div>
            </div>
          ))}
          <div className="hh-card" style={{ padding: 16, marginBottom: 10 }}>
            <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 8 }}>SmartThings token</div>
            <div style={{ fontSize: 12, color: smartThingsState?.valid ? 'var(--hh-good)' : 'var(--hh-ink-mute)', marginBottom: 10 }}>
              {smartThingsState?.valid ? `Connected${smartThingsState.token ? ` · ${smartThingsState.token}` : ''}` : (smartThingsState?.error || 'Add or update the Personal Access Token to fix SmartThings device control.')}
            </div>
            <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
              <input value={token} onChange={(e) => setToken(e.target.value)} placeholder="Paste SmartThings Personal Access Token" style={{ flex: 1, height: 38, borderRadius: 10, border: '1px solid var(--hh-line-soft)', padding: '0 10px', background: 'var(--hh-surface-2)', color: 'var(--hh-ink)', outline: 'none' }}/>
              <button
                onClick={() => {
                  if (!token.trim() || !store.updateSmartThingsToken) return;
                  setSaving(true);
                  store.updateSmartThingsToken(token.trim()).catch(() => {}).finally(() => setSaving(false));
                }}
                className="press hh-btn accent"
                style={{ height: 38, padding: '0 14px', fontSize: 12 }}
              >
                {saving ? 'Saving…' : 'Update'}
              </button>
            </div>
          </div>
          <div className="hh-card" style={{ padding: 16 }}>
            <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 8 }}>Server info</div>
            <div style={{ fontSize: 12, color: 'var(--hh-ink-soft)', lineHeight: 1.8 }}>
              <div>Host: <span className="hh-mono">192.168.0.239</span></div>
              <div>API port: <span className="hh-mono">3390</span></div>
              <div>Tracker port: <span className="hh-mono">3380</span></div>
              <div>Total devices: <span className="hh-mono">{store.devices.length}</span></div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Energy & Utilities ──
function EnergyScreen({ store, cfg, onBack }) {
  const onDevices = store.devices.filter(d => d.on);
  const totalWatts = onDevices.reduce((s, d) => s + (d.power || 0), 0);
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <SubHeader title="Energy & Utilities" onBack={onBack}/>
      <div className="hh-scroll" style={{ flex: 1, overflow: 'auto', padding: '0 0 20px' }}>
        <div style={{ padding: '0 20px' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 16 }}>
            <div className="hh-card" style={{ padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 28, fontWeight: 600, color: 'var(--hh-accent)' }} className="hh-serif">{totalWatts || '—'}</div>
              <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginTop: 4 }}>Watts now</div>
            </div>
            <div className="hh-card" style={{ padding: 16, textAlign: 'center' }}>
              <div style={{ fontSize: 28, fontWeight: 600, color: 'var(--hh-accent)' }} className="hh-serif">{onDevices.length}</div>
              <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginTop: 4 }}>Active devices</div>
            </div>
          </div>
          <div className="hh-section-h">Active devices by power</div>
          <div className="hh-card" style={{ margin: '0' }}>
            {onDevices.length === 0 && <div style={{ padding: 16, textAlign: 'center', fontSize: 13, color: 'var(--hh-ink-mute)' }}>No devices currently on.</div>}
            {onDevices.sort((a, b) => (b.power || 0) - (a.power || 0)).map((d, i) => (
              <div key={d.id} style={{ display: 'flex', gap: 10, alignItems: 'center', padding: '12px 14px', borderBottom: i < onDevices.length - 1 ? '1px solid var(--hh-line-soft)' : 'none' }}>
                <div style={{ width: 32, height: 32, borderRadius: 9, background: 'var(--hh-accent-tint)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <Icon name="bolt" size={14} color="var(--hh-accent)"/>
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 500 }}>{d.name}</div>
                  <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)' }}>{d.room}</div>
                </div>
                <div className="hh-mono" style={{ fontSize: 13, color: 'var(--hh-ink-soft)' }}>{d.power || '—'}W</div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

// ── App Settings ──
function AppSettingsScreen({ store, cfg, onBack, updateCfg }) {
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <SubHeader title="App Settings" onBack={onBack}/>
      <div className="hh-scroll" style={{ flex: 1, overflow: 'auto', padding: '0 0 20px' }}>
        <div style={{ padding: '0 20px' }}>
          <div className="hh-section-h">Appearance</div>
          <div className="hh-card" style={{ padding: 16, marginBottom: 12 }}>
            <div style={{ marginBottom: 14 }}>
              <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 8 }}>Theme</div>
              <div style={{ display: 'flex', gap: 8 }}>
                {['light', 'dark'].map(v => (
                  <button key={v} onClick={() => updateCfg && updateCfg({ theme: v })} className="press" style={{
                    flex: 1, height: 38, borderRadius: 12, fontSize: 13, fontWeight: 500, textTransform: 'capitalize',
                    background: cfg.theme === v ? 'var(--hh-ink)' : 'var(--hh-surface-2)',
                    color: cfg.theme === v ? 'var(--hh-bg)' : 'var(--hh-ink-soft)',
                  }}>{v}</button>
                ))}
              </div>
            </div>
            <div style={{ marginBottom: 14 }}>
              <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 8 }}>Accent color</div>
              <div style={{ display: 'flex', gap: 8 }}>
                {[['terracotta','#C9562E'],['sage','#6E8662'],['mustard','#C99A2E'],['plum','#7A4F6B'],['sky','#5F7E91'],['clay','#B26749']].map(([k, c]) => (
                  <button key={k} onClick={() => updateCfg && updateCfg({ accent: k })} style={{
                    width: 32, height: 32, borderRadius: '50%', background: c, flexShrink: 0,
                    border: cfg.accent === k ? '3px solid var(--hh-ink)' : '2px solid transparent',
                    boxShadow: cfg.accent === k ? '0 0 0 2px var(--hh-bg)' : 'none',
                  }} title={k}/>
                ))}
              </div>
            </div>
            <div>
              <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 8 }}>Density</div>
              <div style={{ display: 'flex', gap: 8 }}>
                {['comfy', 'compact'].map(v => (
                  <button key={v} onClick={() => updateCfg && updateCfg({ density: v })} className="press" style={{
                    flex: 1, height: 38, borderRadius: 12, fontSize: 13, fontWeight: 500, textTransform: 'capitalize',
                    background: cfg.density === v ? 'var(--hh-ink)' : 'var(--hh-surface-2)',
                    color: cfg.density === v ? 'var(--hh-bg)' : 'var(--hh-ink-soft)',
                  }}>{v}</button>
                ))}
              </div>
            </div>
          </div>

          <div className="hh-section-h">About</div>
          <div className="hh-card" style={{ padding: 16 }}>
            <div style={{ fontSize: 12, color: 'var(--hh-ink-soft)', lineHeight: 1.8 }}>
              <div className="hh-serif" style={{ fontSize: 18, color: 'var(--hh-accent)', marginBottom: 8 }}>HomeHub</div>
              <div>Version: <span className="hh-mono">2.4.1</span></div>
              <div>Server: <span className="hh-mono">192.168.0.239:3390</span></div>
              <div>Database: <span className="hh-mono">PostgreSQL</span></div>
              <div>Devices: <span className="hh-mono">{store.devices.length}</span></div>
              <div>Family: <span className="hh-mono">{store.family.length}</span></div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { RulesScreen, ScenesScreen, ActivityScreen, CamerasScreen, DevicesScreen, FamilyScreen, WasteScreen, SettingsScreen, SubHeader, PrivacyScreen, LocationHistoryScreen, HubsScreen, EnergyScreen, AppSettingsScreen });
