// screens-extras.jsx — Rental flow, swipe browse, portfolio, notifications, profile, admin

// ─── MIETEN DASHBOARD ──────────────────────────────────────────────────
function MietenDashboardScreen({ ctx }) {
  const { listings, searches, navigate } = ctx;
  const rentalSearches = searches.filter(s => s.category === 'miete');
  const newRentals = listings.filter(l => l.type === 'miete').slice(0, 3);

  return (
    <div className="phone-scroll fade-in" style={{ paddingBottom: 100, background: 'var(--bg)' }}>
      <div style={{ padding: '60px 20px 0' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
          <div>
            <div style={{ fontSize: 13, color: 'var(--ink-muted)', fontWeight: 500 }}>Maxim · Mieten</div>
            <h1 style={{ margin: '6px 0 0', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 38, lineHeight: 1.0, letterSpacing: -0.025 }}>
              Mietwohnungen
            </h1>
          </div>
          <IconBtn onClick={() => navigate('searchBuilderMiete')}><I.plus style={{ width: 22, height: 22, strokeWidth: 2.4 }} /></IconBtn>
        </div>
      </div>

      <div style={{ padding: '20px 16px 0', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
        <StatTile value={rentalSearches.filter(s => s.active).length} label="Aktive Suchen" />
        <StatTile value={rentalSearches.reduce((s,x) => s+x.matches, 0)} label="Treffer" />
        <StatTile value={`+${rentalSearches.reduce((s,x) => s+x.newToday, 0)}`} label="Neu heute" accent />
        <StatTile value="Ø 17 Tg." label="Time-to-rent" delta="lokaler Schnitt" />
      </div>

      <Section title="Ihre Mietsuchen" trailing="+ Neue">
        {rentalSearches.length === 0 ? (
          <EmptyState
            icon={<I.key />}
            title="Noch keine Mietsuche"
            subtitle="Legen Sie Ihre erste Suche an und wir benachrichtigen Sie bei neuen Inseraten."
            cta={<button onClick={() => navigate('searchBuilderMiete')} className="btn btn-accent">Mietsuche erstellen</button>}
          />
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
            {rentalSearches.map(s => (
              <SearchCard key={s.id} search={s} onTap={() => navigate('mietenResults', { searchId: s.id })} />
            ))}
          </div>
        )}
      </Section>

      <Section title="Neue Inserate" trailing="Alle ansehen" onTrailing={() => navigate('mietenResults', { searchId: rentalSearches[0]?.id })}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {newRentals.map(l => (
            <ListingRow key={l.id} listing={l} onTap={() => navigate('listing', { id: l.id })} />
          ))}
        </div>
      </Section>

      <Section title="Info">
        <div className="card" style={{ padding: 14, display: 'flex', gap: 12, alignItems: 'center' }}>
          <div style={{ width: 36, height: 36, borderRadius: 10, background: 'var(--info-soft)', color: 'var(--info)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
            <I.shield />
          </div>
          <div style={{ flex: 1, fontSize: 12, color: 'var(--ink-2)', lineHeight: 1.5 }}>
            Mietangebote werden <strong>nicht KI-bewertet</strong>. Sortierung nach Neuheit und Stichwortmatch.
          </div>
        </div>
      </Section>
    </div>
  );
}

function SearchCard({ search, onTap }) {
  return (
    <div className="card" onClick={onTap} style={{ padding: '14px 16px', cursor: 'pointer' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <div style={{ flex: 1 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
            <span style={{
              width: 8, height: 8, borderRadius: 999,
              background: search.active ? 'var(--success)' : 'var(--ink-faint)',
              boxShadow: search.active ? '0 0 0 3px rgba(47,143,90,.18)' : 'none',
            }} />
            <div style={{ fontSize: 15, fontWeight: 700, color: 'var(--ink)', letterSpacing: -0.01 }}>{search.name}</div>
          </div>
          <div style={{ fontSize: 12, color: 'var(--ink-muted)' }}>
            {search.city} +{search.radius}km · {fmtPriceShort(search.priceMin)}–{fmtPriceShort(search.priceMax)} · {search.roomsMin}–{search.roomsMax} Zi.
          </div>
        </div>
        <I.chevR style={{ color: 'var(--ink-faint)' }} />
      </div>
      <div style={{ display: 'flex', gap: 6, marginTop: 12, alignItems: 'center', flexWrap: 'wrap' }}>
        <span className="chip" style={{ fontSize: 11 }}>
          <strong style={{ color: 'var(--ink)' }}>{search.matches}</strong>&nbsp;Treffer
        </span>
        {search.newToday > 0 && <span className="chip chip-accent" style={{ fontSize: 11 }}>+{search.newToday} neu</span>}
        {search.aiEnabled && <span className="chip chip-info" style={{ fontSize: 11 }}>KI</span>}
        <span style={{ fontSize: 11, color: 'var(--ink-faint)', marginLeft: 'auto' }}>
          {fmtRelative(search.lastRun)}
        </span>
      </div>
    </div>
  );
}

// ─── SWIPE BROWSE (Tinder-style) ───────────────────────────────────────
function SwipeScreen({ ctx }) {
  const { listings, back, navigate, favs, toggleFav, archiveListing, archived } = ctx;
  const queue = listings.filter(l => l.type === 'kauf' && !archived.has(l.id)).slice(0, 8);
  const [idx, setIdx] = React.useState(0);
  const [dragX, setDragX] = React.useState(0);
  const [dragging, setDragging] = React.useState(false);
  const startX = React.useRef(0);
  const currentY = React.useRef(0);

  const onStart = (e) => {
    startX.current = (e.touches ? e.touches[0].clientX : e.clientX);
    currentY.current = (e.touches ? e.touches[0].clientY : e.clientY);
    setDragging(true);
  };
  const onMove = (e) => {
    if (!dragging) return;
    const x = (e.touches ? e.touches[0].clientX : e.clientX);
    setDragX(x - startX.current);
  };
  const onEnd = () => {
    if (!dragging) return;
    setDragging(false);
    if (Math.abs(dragX) > 100) {
      const decision = dragX > 0 ? 'like' : 'pass';
      const item = queue[idx];
      if (decision === 'like') toggleFav(item.id, true);
      else archiveListing(item.id);
      setDragX(dragX > 0 ? 400 : -400);
      setTimeout(() => {
        setDragX(0);
        setIdx(i => i + 1);
      }, 180);
    } else {
      setDragX(0);
    }
  };

  const decide = (decision) => {
    const item = queue[idx];
    if (!item) return;
    if (decision === 'like') toggleFav(item.id, true);
    else archiveListing(item.id);
    setDragX(decision === 'like' ? 400 : -400);
    setTimeout(() => {
      setDragX(0);
      setIdx(i => i + 1);
    }, 180);
  };

  const current = queue[idx];
  const next = queue[idx + 1];
  const angle = dragX * 0.06;
  const likeOpacity = Math.max(0, Math.min(1, dragX / 80));
  const passOpacity = Math.max(0, Math.min(1, -dragX / 80));

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: '#1F1A14', color: '#fff' }}>
      <div style={{ padding: '60px 20px 12px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <button onClick={back} style={{ background: 'rgba(255,255,255,.1)', border: 0, color: '#fff', width: 40, height: 40, borderRadius: 999, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
          <I.chevL />
        </button>
        <div style={{ textAlign: 'center' }}>
          <div style={{ fontFamily: 'var(--font-display)', fontSize: 22, letterSpacing: -0.01 }}>Entdecken</div>
          <div style={{ fontSize: 11, color: 'rgba(255,255,255,.55)', marginTop: 2 }}>{Math.min(idx+1, queue.length)} / {queue.length}</div>
        </div>
        <div style={{ width: 40 }} />
      </div>

      <div style={{ flex: 1, position: 'relative', padding: '20px 20px 0' }}>
        {current ? (
          <>
            {/* Next card (peek behind) */}
            {next && (
              <SwipeCard
                listing={next}
                style={{
                  transform: 'scale(.94) translateY(20px)', opacity: .6, pointerEvents: 'none',
                }}
              />
            )}
            {/* Current card */}
            <SwipeCard
              listing={current}
              onStart={onStart} onMove={onMove} onEnd={onEnd}
              onTap={() => Math.abs(dragX) < 6 && navigate('listing', { id: current.id })}
              style={{
                transform: `translateX(${dragX}px) rotate(${angle}deg)`,
                transition: dragging ? 'none' : 'transform .25s ease',
                cursor: 'grab', touchAction: 'pan-y',
              }}
              likeOpacity={likeOpacity}
              passOpacity={passOpacity}
            />
          </>
        ) : (
          <div style={{ position: 'absolute', inset: 20, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', color: '#fff' }}>
            <div style={{ width: 80, height: 80, borderRadius: 999, background: 'rgba(255,255,255,.1)', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 20, color: 'var(--primary)' }}>
              <I.check style={{ width: 40, height: 40 }} />
            </div>
            <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 32, margin: 0 }}>Alles durch!</h2>
            <p style={{ color: 'rgba(255,255,255,.6)', marginTop: 8, fontSize: 14 }}>
              Sie haben alle Inserate gesehen. Neue Treffer erhalten Sie als Mitteilung.
            </p>
            <button onClick={() => setIdx(0)} className="btn btn-accent" style={{ marginTop: 20 }}>Von vorn beginnen</button>
          </div>
        )}
      </div>

      {/* Action buttons */}
      {current && (
        <div style={{ padding: '20px 40px 40px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 20 }}>
          <ActionBtn onClick={() => decide('pass')} color="#fff" bg="rgba(255,255,255,.12)" size={56}>
            <I.x style={{ width: 26, height: 26, strokeWidth: 2.5 }} />
          </ActionBtn>
          <ActionBtn onClick={() => navigate('listing', { id: current.id })} color="#1F1A14" bg="#fff" size={48}>
            <I.search style={{ width: 22, height: 22 }} />
          </ActionBtn>
          <ActionBtn onClick={() => decide('like')} color="#fff" bg="var(--primary)" size={56}>
            <I.heartFill style={{ width: 26, height: 26 }} />
          </ActionBtn>
        </div>
      )}
    </div>
  );
}

function ActionBtn({ children, onClick, color, bg, size = 56 }) {
  return (
    <button onClick={onClick} style={{
      width: size, height: size, borderRadius: 999, border: 0, cursor: 'pointer',
      background: bg, color, display: 'flex', alignItems: 'center', justifyContent: 'center',
      boxShadow: '0 6px 16px rgba(0,0,0,.25)',
    }}>{children}</button>
  );
}

function SwipeCard({ listing, onStart, onMove, onEnd, onTap, style, likeOpacity = 0, passOpacity = 0 }) {
  return (
    <div
      onMouseDown={onStart} onMouseMove={onMove} onMouseUp={onEnd} onMouseLeave={onEnd}
      onTouchStart={onStart} onTouchMove={onMove} onTouchEnd={onEnd}
      onClick={onTap}
      style={{
        position: 'absolute', inset: 0, borderRadius: 24, overflow: 'hidden',
        background: '#fff', boxShadow: '0 20px 40px rgba(0,0,0,.3)',
        ...style,
      }}
    >
      <div className="photo" style={{
        position: 'absolute', inset: 0,
        backgroundImage: `url(${listing.photos[0]})`,
      }} />
      <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(0deg, rgba(0,0,0,.85) 0%, transparent 55%)' }} />

      {/* Like/Pass overlays */}
      <div style={{
        position: 'absolute', top: 30, left: 22, padding: '8px 18px',
        border: '3px solid var(--primary)', color: 'var(--primary)',
        fontWeight: 800, fontSize: 22, borderRadius: 10, transform: 'rotate(-10deg)',
        opacity: likeOpacity, background: 'rgba(255,255,255,.85)',
      }}>MERKEN</div>
      <div style={{
        position: 'absolute', top: 30, right: 22, padding: '8px 18px',
        border: '3px solid #fff', color: '#fff',
        fontWeight: 800, fontSize: 22, borderRadius: 10, transform: 'rotate(10deg)',
        opacity: passOpacity, background: 'rgba(0,0,0,.4)',
      }}>WEITER</div>

      {/* Badge top */}
      <div style={{ position: 'absolute', top: 16, left: 16, display: 'flex', gap: 6 }}>
        <PlatformBadge platform={listing.platform} />
        {listing.provisionsfrei && <span style={{ background: 'rgba(255,255,255,.92)', color: 'var(--ink)', padding: '3px 8px', borderRadius: 999, fontSize: 10, fontWeight: 700 }}>PROVISIONSFREI</span>}
      </div>
      {listing.aiScore && (
        <div style={{
          position: 'absolute', top: 14, right: 14,
          width: 52, height: 52, borderRadius: 999,
          background: listing.aiScore >= 80 ? '#2F8F5A' : listing.aiScore >= 60 ? '#C28428' : '#C8331C',
          color: '#fff', fontSize: 17, fontWeight: 800,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          boxShadow: '0 4px 12px rgba(0,0,0,.3)', flexDirection: 'column', lineHeight: 1,
        }}>
          {listing.aiScore}
          <div style={{ fontSize: 7, fontWeight: 600, opacity: .9, marginTop: 2, letterSpacing: 0.05 }}>KI-SCORE</div>
        </div>
      )}

      {/* Body */}
      <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, padding: '20px 22px 26px', color: '#fff' }}>
        <div style={{ fontFamily: 'var(--font-display)', fontSize: 30, fontWeight: 400, letterSpacing: -0.02, lineHeight: 1.0 }}>
          {fmtPriceShort(listing.price)}
        </div>
        <div style={{ fontSize: 16, fontWeight: 600, marginTop: 6 }}>{listing.title}</div>
        <div style={{ fontSize: 13, color: 'rgba(255,255,255,.8)', marginTop: 4, display: 'flex', alignItems: 'center', gap: 4 }}>
          <I.pin style={{ width: 13, height: 13 }} /> {listing.district}, {listing.city}
        </div>
        <div style={{ display: 'flex', gap: 14, marginTop: 12, fontSize: 13, fontWeight: 500 }}>
          <span style={{ display: 'flex', alignItems: 'center', gap: 4 }}><I.ruler style={{ width: 14, height: 14 }} /> {fmtArea(listing.area)}</span>
          <span style={{ display: 'flex', alignItems: 'center', gap: 4 }}><I.bed style={{ width: 14, height: 14 }} /> {listing.rooms} Zi.</span>
          <span style={{ display: 'flex', alignItems: 'center', gap: 4 }}><I.calendar style={{ width: 14, height: 14 }} /> {listing.baujahr}</span>
        </div>
      </div>
    </div>
  );
}

// ─── PORTFOLIO (favorites + archive) ───────────────────────────────────
function PortfolioScreen({ ctx }) {
  const { listings, favs, archived, navigate, toggleFav } = ctx;
  const [tab, setTab] = React.useState('favs');
  const favList = listings.filter(l => favs.has(l.id));
  const archiveList = listings.filter(l => archived.has(l.id));
  const totalValue = favList.filter(l => l.type === 'kauf').reduce((s, l) => s + l.price, 0);
  const avgScore = (() => {
    const xs = favList.filter(l => l.aiScore);
    return xs.length ? Math.round(xs.reduce((s,l) => s+l.aiScore, 0) / xs.length) : null;
  })();

  return (
    <div className="phone-scroll fade-in" style={{ paddingBottom: 100, background: 'var(--bg)' }}>
      <div style={{ padding: '60px 20px 0' }}>
        <div style={{ fontSize: 13, color: 'var(--ink-muted)', fontWeight: 500 }}>Meine Auswahl</div>
        <h1 style={{ margin: '6px 0 0', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 38, lineHeight: 1.0, letterSpacing: -0.025 }}>
          Merkliste
        </h1>
      </div>

      {/* Analytics */}
      <div style={{ padding: '20px 16px 0', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
        <StatTile value={favList.length} label="Gemerkt" delta={`${favList.filter(l=>l.type==='kauf').length} Kauf · ${favList.filter(l=>l.type==='miete').length} Miete`} />
        <StatTile value={fmtPriceShort(totalValue)} label="Gesamtvolumen" delta="nur Kaufobjekte" accent />
        <StatTile value={avgScore ? `Ø ${avgScore}` : '—'} label="KI-Score Mittelw." />
        <StatTile value={archiveList.length} label="Archiviert" />
      </div>

      {/* Tabs */}
      <div style={{ padding: '24px 16px 0', display: 'flex', gap: 8, alignItems: 'center' }}>
        <TabBtn active={tab==='favs'} onClick={() => setTab('favs')}>
          <I.heartFill style={{ width: 14, height: 14 }} /> Gemerkt ({favList.length})
        </TabBtn>
        <TabBtn active={tab==='archive'} onClick={() => setTab('archive')}>
          <I.archive style={{ width: 14, height: 14 }} /> Archiv ({archiveList.length})
        </TabBtn>
      </div>

      <div style={{ padding: '16px 16px 0' }}>
        {(tab==='favs' ? favList : archiveList).length === 0 ? (
          <EmptyState
            icon={tab==='favs' ? <I.heart /> : <I.archive />}
            title={tab==='favs' ? 'Noch nichts gemerkt' : 'Archiv ist leer'}
            subtitle={tab==='favs' ? 'Tippen Sie auf das Herz, um Inserate hier zu sammeln.' : 'Verschobene Inserate landen hier.'}
          />
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            {(tab==='favs' ? favList : archiveList).map(l => (
              <ListingCard key={l.id} listing={l} onTap={() => navigate('listing', { id: l.id })} isFav={favs.has(l.id)} onFav={toggleFav} compact />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function TabBtn({ active, onClick, children }) {
  return (
    <button onClick={onClick} className="chip" style={{
      padding: '8px 14px', fontSize: 13,
      background: active ? 'var(--ink)' : 'var(--surface)',
      color: active ? '#fff' : 'var(--ink-2)',
      border: active ? 'none' : '1px solid var(--border)',
    }}>{children}</button>
  );
}

// ─── NOTIFICATIONS ─────────────────────────────────────────────────────
function NotificationsScreen({ ctx }) {
  const { notifications, navigate, setNotifications, searches } = ctx;
  const [pushEnabled, setPushEnabled] = React.useState(true);
  const [pref, setPref] = React.useState({ ai: true, matches: true, system: true });

  const markAll = () => setNotifications(notifications.map(n => ({ ...n, read: true })));
  const click = (n) => {
    setNotifications(notifications.map(x => x.id === n.id ? { ...x, read: true } : x));
    if (n.listingId) navigate('listing', { id: n.listingId });
    else if (n.searchId) {
      const s = searches.find(x => x.id === n.searchId);
      if (s) {
        if (s.category === 'kauf') navigate('results', { searchId: n.searchId });
        else navigate('mietenResults', { searchId: n.searchId });
      }
    }
  };

  return (
    <div className="phone-scroll fade-in" style={{ paddingBottom: 100, background: 'var(--bg)' }}>
      <div style={{ padding: '60px 20px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <div>
          <div style={{ fontSize: 13, color: 'var(--ink-muted)', fontWeight: 500 }}>Aktivitäten</div>
          <h1 style={{ margin: '6px 0 0', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 38, lineHeight: 1.0, letterSpacing: -0.025 }}>
            Mitteilungen
          </h1>
        </div>
        <button onClick={markAll} style={{ background: 'transparent', border: 0, color: 'var(--primary)', fontSize: 13, fontWeight: 600, cursor: 'pointer', padding: 0 }}>
          Alle gelesen
        </button>
      </div>

      {/* Push subscription card */}
      <div style={{ padding: '20px 16px 0' }}>
        <div className="card" style={{ padding: 14 }}>
          <div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
            <div style={{
              width: 40, height: 40, borderRadius: 12,
              background: pushEnabled ? 'var(--primary)' : 'var(--surface-2)',
              color: pushEnabled ? '#fff' : 'var(--ink-muted)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}><I.bell /></div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--ink)' }}>Browser-Push aktiv</div>
              <div style={{ fontSize: 12, color: 'var(--ink-muted)', marginTop: 2 }}>
                {pushEnabled ? 'Sie erhalten Sofortbenachrichtigungen.' : 'Push deaktiviert.'}
              </div>
            </div>
            <Toggle on={pushEnabled} />
            <div onClick={() => setPushEnabled(!pushEnabled)} style={{ position: 'absolute', inset: 0, cursor: 'pointer' }} />
          </div>
          {pushEnabled && (
            <div style={{ marginTop: 12, paddingTop: 12, borderTop: '0.5px solid var(--border)', display: 'flex', flexDirection: 'column', gap: 10 }}>
              <PrefRow label="Hohe KI-Scores (≥ 80)" on={pref.ai} onClick={() => setPref(p => ({ ...p, ai: !p.ai }))} />
              <PrefRow label="Neue Treffer in Suchen" on={pref.matches} onClick={() => setPref(p => ({ ...p, matches: !p.matches }))} />
              <PrefRow label="System-Hinweise" on={pref.system} onClick={() => setPref(p => ({ ...p, system: !p.system }))} />
            </div>
          )}
        </div>
      </div>

      {/* Stream */}
      <div style={{ padding: '24px 16px 0' }}>
        <h3 className="section-title" style={{ marginBottom: 10 }}>Letzte Aktivität</h3>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {notifications.map(n => (
            <NotifRow key={n.id} n={n} onClick={() => click(n)} />
          ))}
        </div>
      </div>
    </div>
  );
}
function PrefRow({ label, on, onClick }) {
  return (
    <div onClick={onClick} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', cursor: 'pointer' }}>
      <span style={{ fontSize: 13, color: 'var(--ink-2)' }}>{label}</span>
      <Toggle on={on} />
    </div>
  );
}
function NotifRow({ n, onClick }) {
  const icons = {
    'ai-high':   { i: <I.spark />,   bg: 'var(--primary-soft)', c: 'var(--primary-ink)' },
    'new-match': { i: <I.search />,  bg: 'var(--info-soft)',    c: 'var(--info)' },
    'system':    { i: <I.shield />,  bg: 'var(--surface-2)',    c: 'var(--ink-muted)' },
  };
  const cfg = icons[n.kind] || icons.system;
  return (
    <div onClick={onClick} className="card" style={{
      padding: 14, display: 'flex', gap: 12, alignItems: 'flex-start', cursor: 'pointer',
      background: n.read ? 'var(--surface)' : 'var(--surface)',
      borderLeft: n.read ? '0' : '3px solid var(--primary)',
      paddingLeft: n.read ? 14 : 11,
    }}>
      <div style={{ width: 36, height: 36, borderRadius: 10, background: cfg.bg, color: cfg.c, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{cfg.i}</div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
          <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--ink)' }}>{n.title}</div>
          {!n.read && <span style={{ width: 6, height: 6, borderRadius: 999, background: 'var(--primary)' }} />}
        </div>
        <div style={{ fontSize: 12, color: 'var(--ink-muted)', marginTop: 4, lineHeight: 1.5 }}>{n.body}</div>
        <div style={{ fontSize: 11, color: 'var(--ink-faint)', marginTop: 6 }}>{fmtRelative(n.at)}</div>
      </div>
    </div>
  );
}

// ─── PROFILE ───────────────────────────────────────────────────────────
function ProfileScreen({ ctx }) {
  const { navigate, signOut, favs } = ctx;
  return (
    <div className="phone-scroll fade-in" style={{ paddingBottom: 100, background: 'var(--bg)' }}>
      <div style={{ padding: '60px 20px 0' }}>
        <h1 style={{ margin: 0, fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 38, lineHeight: 1.0, letterSpacing: -0.025 }}>
          Profil
        </h1>
      </div>

      {/* User card */}
      <div style={{ padding: '20px 16px 0' }}>
        <div className="card" style={{ padding: 16, display: 'flex', gap: 14, alignItems: 'center' }}>
          <div style={{
            width: 58, height: 58, borderRadius: 999,
            background: 'linear-gradient(135deg, var(--primary), var(--primary-deep))',
            color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: 'var(--font-display)', fontSize: 28, fontWeight: 400,
          }}>MB</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 17, fontWeight: 700, color: 'var(--ink)', letterSpacing: -0.01 }}>Maxim Berger</div>
            <div style={{ fontSize: 13, color: 'var(--ink-muted)' }}>maxim.berger@example.de</div>
            <div style={{ marginTop: 6, display: 'inline-flex', alignItems: 'center', gap: 5 }}>
              <span className="chip chip-accent" style={{ fontSize: 11 }}><I.flame style={{ width: 12, height: 12 }} /> Pro · 12 Tg.</span>
            </div>
          </div>
        </div>
      </div>

      {/* Plan card */}
      <div style={{ padding: '20px 16px 0' }}>
        <div className="card" style={{ padding: 16, background: 'linear-gradient(135deg, var(--ink) 0%, var(--ink-2) 100%)', color: '#fff' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
            <div>
              <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--primary)', textTransform: 'uppercase', letterSpacing: 0.05 }}>Aktiv</div>
              <div style={{ fontFamily: 'var(--font-display)', fontSize: 28, fontWeight: 400, letterSpacing: -0.01, marginTop: 4 }}>ImmoBot Pro</div>
            </div>
            <div style={{ textAlign: 'right' }}>
              <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: -0.01 }}>19 €</div>
              <div style={{ fontSize: 11, color: 'rgba(255,255,255,.55)' }}>/ Monat</div>
            </div>
          </div>
          <div style={{ display: 'flex', gap: 14, marginTop: 14, fontSize: 12, color: 'rgba(255,255,255,.7)' }}>
            <span>✓ Unbegr. Suchen</span>
            <span>✓ 100 KI/Tag</span>
            <span>✓ CSV-Export</span>
          </div>
          <div style={{ display: 'flex', gap: 8, marginTop: 14 }}>
            <button className="btn btn-soft" style={{ flex: 1, background: 'rgba(255,255,255,.12)', color: '#fff', fontSize: 13, padding: '10px' }}>Plan verwalten</button>
            <button className="btn btn-accent" style={{ flex: 1, fontSize: 13, padding: '10px' }}>Upgrade Premium</button>
          </div>
        </div>
      </div>

      {/* Menu */}
      <div style={{ padding: '24px 16px 0' }}>
        <h3 className="section-title" style={{ marginBottom: 8 }}>Konto</h3>
        <div className="card" style={{ overflow: 'hidden' }}>
          <ProfileRow icon={<I.user />} title="Persönliche Daten" />
          <ProfileRow icon={<I.bell />} title="Benachrichtigungen" onTap={() => navigate('notifications', null, true)} />
          <ProfileRow icon={<I.settings />} title="Job-Monitor (Admin)" onTap={() => navigate('admin')} />
          <ProfileRow icon={<I.shield />} title="Datenschutz" isLast />
        </div>
      </div>
      <div style={{ padding: '16px 16px 0' }}>
        <h3 className="section-title" style={{ marginBottom: 8 }}>Such-Voreinstellungen</h3>
        <div className="card" style={{ overflow: 'hidden' }}>
          <ProfileRow icon={<I.home />} title="Standard-Standort" detail="Berlin" />
          <ProfileRow icon={<I.spark />} title="KI-Modell" detail="gpt-4o" />
          <ProfileRow icon={<I.globe />} title="Sprache" detail="Deutsch" isLast />
        </div>
      </div>
      <div style={{ padding: '16px 16px 0' }}>
        <div className="card" style={{ overflow: 'hidden' }}>
          <ProfileRow icon={<I.logout />} title="Abmelden" danger onTap={signOut} isLast />
        </div>
      </div>
      <div style={{ textAlign: 'center', padding: '24px 0 0', fontSize: 11, color: 'var(--ink-faint)' }}>
        ImmoBot v3.4.1 · Build 2026.05.13
      </div>
    </div>
  );
}
function ProfileRow({ icon, title, detail, isLast, danger, onTap }) {
  return (
    <div onClick={onTap} style={{
      display: 'flex', alignItems: 'center', gap: 12, padding: '14px 16px',
      borderBottom: isLast ? 'none' : '0.5px solid var(--border)',
      cursor: onTap ? 'pointer' : 'default',
      color: danger ? 'var(--danger)' : 'var(--ink)',
    }}>
      <div style={{ color: danger ? 'var(--danger)' : 'var(--ink-muted)', display: 'flex' }}>{icon}</div>
      <div style={{ flex: 1, fontSize: 14, fontWeight: 500 }}>{title}</div>
      {detail && <div style={{ fontSize: 13, color: 'var(--ink-muted)' }}>{detail}</div>}
      <I.chevR style={{ color: 'var(--ink-faint)', width: 18, height: 18 }} />
    </div>
  );
}

// ─── ADMIN JOB MONITOR ────────────────────────────────────────────────
function AdminScreen({ ctx }) {
  const { back } = ctx;
  const [jobs, setJobs] = React.useState(window.JOBS);
  const [debug, setDebug] = React.useState(true);

  // Animate running jobs
  React.useEffect(() => {
    const t = setInterval(() => {
      setJobs(js => js.map(j => {
        if (j.status === 'running' && j.progress < 100) {
          const newP = Math.min(100, j.progress + Math.random() * 3);
          return { ...j, progress: newP };
        }
        return j;
      }));
    }, 800);
    return () => clearInterval(t);
  }, []);

  const counts = {
    running: jobs.filter(j => j.status === 'running').length,
    queued: jobs.filter(j => j.status === 'queued').length,
    completed: jobs.filter(j => j.status === 'completed').length,
    failed: jobs.filter(j => j.status === 'failed' || j.status === 'skipped').length,
  };

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--bg)' }}>
      <TopBar title="Job-Monitor" onBack={back} trailing={
        <span className="chip" style={{
          background: debug ? 'var(--ink)' : 'var(--surface-2)',
          color: debug ? '#fff' : 'var(--ink-muted)',
          fontSize: 11, padding: '5px 10px', cursor: 'pointer',
        }} onClick={() => setDebug(!debug)}>DEBUG {debug ? 'ON' : 'OFF'}</span>
      } />
      <div className="phone-scroll" style={{ flex: 1, padding: '12px 16px 100px' }}>
        {/* Stat strip */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 8, marginBottom: 16 }}>
          <MiniStat label="Laufend" value={counts.running} color="#2A6FDB" />
          <MiniStat label="Warten" value={counts.queued} color="#C28428" />
          <MiniStat label="Fertig" value={counts.completed} color="#2F8F5A" />
          <MiniStat label="Fehler" value={counts.failed} color="#C8331C" />
        </div>

        {/* Job list */}
        <h3 className="section-title" style={{ marginBottom: 10 }}>Aktive & geplante Jobs</h3>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {jobs.map(j => <JobRow key={j.id} job={j} />)}
        </div>

        {/* Debug panel */}
        {debug && (
          <div style={{ marginTop: 24 }}>
            <h3 className="section-title" style={{ marginBottom: 10 }}>Debug-Konsole</h3>
            <div style={{
              background: '#15110C', color: '#A9D2B5', padding: 14, borderRadius: 12,
              fontFamily: 'var(--font-mono)', fontSize: 11, lineHeight: 1.6,
              maxHeight: 220, overflowY: 'auto',
            }}>
              <div style={{ color: '#5B7B66' }}>[2026-05-13 09:00:12]</div>
              <div>cron: scrape-immo-altbau-berlin → triggered</div>
              <div style={{ color: '#5B7B66', marginTop: 8 }}>[2026-05-13 09:00:14]</div>
              <div>fetched 47/70 listings (immoscout24.de)</div>
              <div style={{ color: '#5B7B66', marginTop: 8 }}>[2026-05-13 09:00:21]</div>
              <div style={{ color: '#F4B04D' }}>warn: rate-limit warning, sleeping 4s</div>
              <div style={{ color: '#5B7B66', marginTop: 8 }}>[2026-05-13 09:00:29]</div>
              <div>ai-eval (gpt-4o) → listing l1 → score=87, latency=2.4s</div>
              <div style={{ color: '#5B7B66', marginTop: 8 }}>[2026-05-13 09:00:34]</div>
              <div>push → user_42 → "Neue Top-Bewertung 92/100"</div>
              <div style={{ color: '#5B7B66', marginTop: 8 }}>[2026-05-13 09:00:38]</div>
              <div style={{ color: '#E07C74' }}>error: scrape-kleinanzeigen-premium-muc → 429 rate-limit, retry in 600s</div>
              <div style={{ color: '#5B7B66', marginTop: 8 }}>[2026-05-13 09:00:42]</div>
              <div>queue depth: 12 (3 scrape, 9 ai-eval)</div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
function MiniStat({ label, value, color }) {
  return (
    <div className="card" style={{ padding: '10px 8px', textAlign: 'center' }}>
      <div style={{ fontSize: 22, fontWeight: 700, color, letterSpacing: -0.02, fontVariantNumeric: 'tabular-nums' }}>{value}</div>
      <div style={{ fontSize: 10, fontWeight: 600, color: 'var(--ink-muted)', textTransform: 'uppercase', letterSpacing: 0.04, marginTop: 2 }}>{label}</div>
    </div>
  );
}
function JobRow({ job }) {
  const statusCfg = {
    running:   { c: '#2A6FDB', bg: 'var(--info-soft)',    label: 'läuft' },
    queued:    { c: '#C28428', bg: 'var(--warn-soft)',    label: 'wartet' },
    completed: { c: '#2F8F5A', bg: 'var(--success-soft)', label: 'fertig' },
    failed:    { c: '#C8331C', bg: 'var(--danger-soft)',  label: 'fehler' },
    skipped:   { c: '#6B6259', bg: 'var(--surface-2)',    label: 'übersprungen' },
  };
  const cfg = statusCfg[job.status];
  const kindIcon = job.kind === 'ai-eval' ? <I.spark /> : <I.refresh />;
  return (
    <div className="card" style={{ padding: 12 }}>
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>
        <div style={{ width: 32, height: 32, borderRadius: 9, background: cfg.bg, color: cfg.c, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
          {kindIcon}
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
            <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)' }}>
              {job.kind === 'ai-eval' ? 'KI-Eval' : 'Scrape'} · {job.target}
            </div>
            <span className="chip" style={{ background: cfg.bg, color: cfg.c, fontSize: 10, padding: '2px 8px' }}>{cfg.label}</span>
          </div>
          <div style={{ fontSize: 11, color: 'var(--ink-muted)', marginTop: 2 }}>
            {job.search} · {job.items}
          </div>
          {job.status === 'running' && (
            <div style={{ marginTop: 8, height: 4, background: 'var(--surface-2)', borderRadius: 999, overflow: 'hidden' }}>
              <div style={{ width: `${job.progress}%`, height: '100%', background: cfg.c, borderRadius: 999, transition: 'width .8s ease' }} />
            </div>
          )}
          {job.error && (
            <div style={{ fontSize: 11, color: 'var(--danger)', marginTop: 6, fontFamily: 'var(--font-mono)' }}>
              {job.error}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  MietenDashboardScreen, SwipeScreen, PortfolioScreen, NotificationsScreen, ProfileScreen, AdminScreen,
});
