import { useState, useEffect, useCallback, useRef } from 'react';
import { createPortal } from 'react-dom';
import { S, api } from '../lib.js';

const POSTER   = 'https://image.tmdb.org/t/p/w342';
const BACKDROP = 'https://image.tmdb.org/t/p/w780';

const TOOL_DEFS = [
  { id: 'kino',      label: '🎬 Kino',      desc: 'Aktuell im Kino (DE) – alle laufenden Filme', ready: true },
  { id: 'demnächst', label: '🗓 Demnächst',  desc: 'Neustarts wochenweise – nächste Wochen',      ready: true },
  { id: 'favoriten', label: '❤ Favoriten',  desc: 'Deine gespeicherten Lieblingsfilme',           ready: true },
  { id: 'suchen',    label: '🔍 Suchen',     desc: 'Filme suchen und Infos abrufen',               ready: true },
];

const getIcon = lbl => [...lbl][0] ?? '🎬';
const getText = lbl => { const c = [...lbl]; return c.slice(1).join('').trim() || lbl; };

const fmtDE = d => d ? new Date(d).toLocaleDateString('de-DE',
  { day:'2-digit', month:'2-digit', year:'numeric' }) : '';

const fmtWeek = dateStr => {
  const d = new Date(dateStr);
  // KW berechnen
  const jan4 = new Date(d.getFullYear(), 0, 4);
  const kw = Math.ceil(((d - jan4) / 86400000 + jan4.getDay() + 1) / 7);
  const end = new Date(d); end.setDate(d.getDate() + 6);
  return `KW ${kw} · ${d.toLocaleDateString('de-DE',{day:'2-digit',month:'2-digit'})} – ${end.toLocaleDateString('de-DE',{day:'2-digit',month:'2-digit',year:'numeric'})}`;
};

const FSK_COLOR = fsk => {
  if (!fsk) return null;
  const n = parseInt(fsk);
  if (n === 0)  return { bg:'#fff',    color:'#000' };
  if (n === 6)  return { bg:'#f9e200', color:'#000' };
  if (n === 12) return { bg:'#00a859', color:'#fff' };
  if (n === 16) return { bg:'#0070bb', color:'#fff' };
  if (n === 18) return { bg:'#e2001a', color:'#fff' };
  return { bg:'#444', color:'#fff' };
};

export default function Media({ toast, mobile, initTab, onInitTabConsumed }) {
  const [activeTool, setActiveTool] = useState('kino');
  const [favIds, toggleFav] = useFavIds();

  // Wenn von außen ein Tab vorgegeben wird (z.B. Dashboard-Badge)
  useEffect(() => {
    if (initTab) {
      setActiveTool(initTab);
      onInitTabConsumed?.();
    }
  }, [initTab]);
  const [modal,      setModal]      = useState(null); // { id, media_type }
  const [xrelIds,    setXrelIds]    = useState(new Set()); // tmdb_ids mit bekannten Releases

  const chipScrollRef = useRef(null);
  const [chipScroll, setChipScroll] = useState({ left: false, right: true });

  const onChipScroll = () => {
    const el = chipScrollRef.current;
    if (!el) return;
    setChipScroll({ left: el.scrollLeft > 4, right: el.scrollLeft < el.scrollWidth - el.clientWidth - 4 });
  };

  const active = TOOL_DEFS.find(t => t.id === activeTool);

  return (
    <div style={{ padding: mobile ? '14px 14px 90px' : '36px 44px', maxWidth: 900 }}>
      <div style={{ display:'flex', alignItems:'center', gap:12, marginBottom:16, flexWrap:'wrap' }}>
        <h1 style={{ color:'#fff', fontFamily:"'Space Mono',monospace", fontSize: mobile?17:22, margin:0 }}>Media</h1>
        <span style={{ color:'rgba(255,255,255,0.5)', fontFamily:'monospace', fontSize:10 }}>Kino · Vorschau · Favoriten</span>
      </div>

      {mobile ? (
        <div style={{ marginBottom:16 }}>
          <div style={{ display:'flex', alignItems:'center', gap:4 }}>
            {chipScroll.left && (
              <button onClick={() => chipScrollRef.current?.scrollBy({ left:-160, behavior:'smooth' })}
                style={{ flexShrink:0, background:'rgba(255,255,255,0.06)', border:'1px solid rgba(255,255,255,0.12)',
                  borderRadius:20, color:'rgba(255,255,255,0.6)', cursor:'pointer', padding:'6px 8px', fontSize:14 }}>‹</button>
            )}
            <div ref={chipScrollRef} onScroll={onChipScroll}
              style={{ display:'flex', gap:6, overflowX:'auto', flex:1,
                padding:'3px 2px 6px', scrollbarWidth:'none', WebkitOverflowScrolling:'touch' }}>
              {TOOL_DEFS.map(t => (
                <button key={t.id} onClick={() => setActiveTool(t.id)} style={{
                  display:'flex', alignItems:'center', gap:6, flexShrink:0,
                  padding:'7px 12px', borderRadius:20, fontFamily:'monospace', fontSize:11,
                  cursor:'pointer', whiteSpace:'nowrap',
                  background: activeTool===t.id ? 'rgba(78,205,196,0.15)' : 'rgba(255,255,255,0.05)',
                  border:     activeTool===t.id ? '1px solid #4ecdc4' : '1px solid rgba(255,255,255,0.1)',
                  color:      activeTool===t.id ? '#4ecdc4' : 'rgba(255,255,255,0.75)',
                  fontWeight: activeTool===t.id ? 700 : 400,
                }}>
                  <span style={{ fontSize:15 }}>{getIcon(t.label)}</span>
                  <span>{getText(t.label)}</span>
                </button>
              ))}
            </div>
            {chipScroll.right && (
              <button onClick={() => chipScrollRef.current?.scrollBy({ left:160, behavior:'smooth' })}
                style={{ flexShrink:0, background:'rgba(255,255,255,0.06)', border:'1px solid rgba(255,255,255,0.12)',
                  borderRadius:20, color:'rgba(255,255,255,0.6)', cursor:'pointer', padding:'6px 8px', fontSize:14 }}>›</button>
            )}
          </div>
        </div>
      ) : (
        <div style={{ display:'grid', gridTemplateColumns:'repeat(2,1fr)', gap:5, marginBottom:16 }}>
          {TOOL_DEFS.map(t => (
            <button key={t.id} title={t.desc} onClick={() => setActiveTool(t.id)} style={{
              display:'flex', alignItems:'center', gap:9,
              padding:'8px 11px', borderRadius:9, fontFamily:'monospace',
              cursor:'pointer', textAlign:'left', border:'none',
              background: activeTool===t.id ? 'rgba(78,205,196,0.15)' : 'rgba(255,255,255,0.04)',
              outline:    activeTool===t.id ? '1px solid #4ecdc4' : 'none',
            }}>
              <span style={{ fontSize:17, flexShrink:0, lineHeight:1, minWidth:22, textAlign:'center' }}>{getIcon(t.label)}</span>
              <div style={{ minWidth:0, flex:1 }}>
                <div style={{ color: activeTool===t.id ? '#4ecdc4' : 'rgba(255,255,255,0.85)', fontSize:12,
                  fontWeight: activeTool===t.id?700:500, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
                  {getText(t.label)}
                </div>
                <div style={{ color:'rgba(255,255,255,0.28)', fontSize:9, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', marginTop:1 }}>
                  {t.desc}
                </div>
              </div>
            </button>
          ))}
        </div>
      )}


      <div style={{ ...S.card }}>
        <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:18, flexWrap:'wrap' }}>
          <div style={{ ...S.head, marginBottom:0 }}>{active?.label}</div>
          <span style={{ color:'rgba(255,255,255,0.5)', fontFamily:'monospace', fontSize:10 }}>{active?.desc}</span>
        </div>

        {activeTool === 'kino'      && <KinoGrid onOpenModal={setModal} xrelIds={xrelIds} onXrelLoaded={ids => setXrelIds(prev => new Set([...prev, ...ids]))} favIds={favIds} onToggleFav={toggleFav}/>}
        {activeTool === 'demnächst' && <DemnächstGrid onOpenModal={setModal} xrelIds={xrelIds} onXrelLoaded={ids => setXrelIds(prev => new Set([...prev, ...ids]))} favIds={favIds} onToggleFav={toggleFav}/>}
        {activeTool === 'favoriten' && <FavoritenKalender onOpenModal={setModal} />}
        {activeTool === 'suchen'    && <SucheGrid onOpenModal={setModal} xrelIds={xrelIds} onXrelLoaded={ids => setXrelIds(prev => new Set([...prev, ...ids]))} favIds={favIds} onToggleFav={toggleFav}/>}
      </div>

      {modal && createPortal(
        <MovieModal
          tmdbId={modal?.id || modal}
          mediaType={modal?.media_type || 'movie'}
          onClose={() => setModal(null)}
          mobile={mobile}
          onHasXrel={id => setXrelIds(prev => new Set([...prev, id]))}
          noYearFilter={activeTool === 'suchen'}
          isFav={favIds.has(modal?.id || modal)}
          onToggleFav={movie => toggleFav(movie, favIds.has(modal?.id || modal))}
        />,
        document.body
      )}
    </div>
  );
}

// ── Film-Karte ────────────────────────────────────────────────────────────────
function MovieCard({ movie, favIds, hasXrel, onToggleFav, onOpenModal }) {
  const isFav    = favIds.has(movie.id);
  const isTop    = movie.rank != null && movie.rank <= 10;
  const fskStyle = FSK_COLOR(movie.fsk);

  return (
    <div style={{
      background:'rgba(255,255,255,0.03)', border: isTop ? '1px solid rgba(255,215,0,0.25)' : '1px solid rgba(255,255,255,0.08)',
      borderRadius:10, overflow:'hidden', display:'flex', flexDirection:'column', cursor:'pointer',
    }}>
      <div style={{ position:'relative', aspectRatio:'2/3', background:'#111', overflow:'hidden' }}
           onClick={() => onOpenModal({ id: movie.id, media_type: movie.media_type || 'movie' })}>
        {movie.poster_path
          ? <img src={POSTER + movie.poster_path} alt={movie.title}
              style={{ width:'100%', height:'100%', objectFit:'cover', display:'block' }} />
          : <div style={{ width:'100%', height:'100%', display:'flex', alignItems:'center',
              justifyContent:'center', fontSize:36, color:'rgba(255,255,255,0.1)' }}>🎬</div>
        }
        {/* TV-Badge */}
        {movie.media_type === 'tv' && (
          <div style={{ position:'absolute', top:6, left:6, background:'rgba(96,165,250,0.85)',
            borderRadius:5, padding:'2px 7px', fontSize:9, fontWeight:700,
            fontFamily:'monospace', color:'#fff', letterSpacing:1 }}>
            SERIE
          </div>
        )}
        {/* Top-Badge */}
        {isTop && (
          <div style={{ position:'absolute', bottom:6, left:6, background:'rgba(0,0,0,0.85)',
            borderRadius:5, padding:'2px 8px', fontSize:13, fontWeight:900,
            fontFamily:"'Space Mono',monospace",
            color: movie.rank === 1 ? '#ffd700' : movie.rank <= 3 ? '#c0c0c0' : '#fff' }}>
            #{movie.rank}
          </div>
        )}
        {/* Rating */}
        {movie.vote_average > 0 && (
          <div style={{ position:'absolute', top:6, left:6, background:'rgba(0,0,0,0.8)',
            borderRadius:5, padding:'2px 6px', fontSize:10, color:'#ffe66d', fontWeight:700,
            fontFamily:"'Space Mono',monospace" }}>★ {movie.vote_average.toFixed(1)}</div>
        )}
        {/* FSK */}
        {fskStyle && (
          <div style={{ position:'absolute', top:6, right:36, background:fskStyle.bg,
            borderRadius:4, padding:'1px 5px', fontSize:9, color:fskStyle.color,
            fontWeight:900, fontFamily:"'Space Mono',monospace", lineHeight:1.5 }}>
            {movie.fsk}
          </div>
        )}
        {/* xREL-Badge */}
        {hasXrel && (
          <div style={{ position:'absolute', bottom:6, right:6, background:'rgba(78,205,196,0.9)',
            borderRadius:4, padding:'1px 5px', fontSize:9, color:'#000',
            fontWeight:900, fontFamily:"'Space Mono',monospace", lineHeight:1.5 }}>
            xREL
          </div>
        )}
        {/* Fav */}
        <button onClick={e => { e.stopPropagation(); onToggleFav(movie, isFav); }} style={{
          position:'absolute', top:5, right:5, background:'rgba(0,0,0,0.65)',
          border:'none', borderRadius:'50%', width:30, height:30, cursor:'pointer',
          fontSize:14, display:'flex', alignItems:'center', justifyContent:'center',
        }}>{isFav ? '❤' : '🤍'}</button>
      </div>
      <div style={{ padding:'8px 10px', flex:1, display:'flex', flexDirection:'column', gap:3 }}
           onClick={() => onOpenModal({ id: movie.id, media_type: movie.media_type || 'movie' })}>
        {isTop && (
          <div style={{ fontSize:9, color:'#ffd700', fontFamily:'monospace', fontWeight:700, letterSpacing:1 }}>
            ★ TOP {movie.rank <= 10 ? '10' : ''}
          </div>
        )}
        <div style={{ fontSize:12, fontWeight:700, color:'#fff', lineHeight:1.3,
          fontFamily:"'Space Mono',monospace", overflow:'hidden',
          display:'-webkit-box', WebkitLineClamp:2, WebkitBoxOrient:'vertical' }}>
          {movie.title}
        </div>
        {movie.original_title && movie.original_title !== movie.title && (
          <div style={{ fontSize:9, color:'rgba(255,255,255,0.35)', fontFamily:'monospace',
            overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', fontStyle:'italic' }}>
            ({movie.original_title})
          </div>
        )}
        {movie.genres?.length > 0 && (
          <div style={{ fontSize:9, color:'#4ecdc4', fontFamily:'monospace', overflow:'hidden',
            textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
            {movie.genres.slice(0,2).join(' · ')}
          </div>
        )}
        {movie.release_date && (
          <div style={{ fontSize:9, color:'rgba(255,255,255,0.3)', fontFamily:'monospace' }}>
            {fmtDE(movie.release_date)}
          </div>
        )}
      </div>
    </div>
  );
}

// ── Favoriten-Hook ────────────────────────────────────────────────────────────
function useFavIds() {
  const [favIds, setFavIds] = useState(new Set());
  const load = useCallback(async () => {
    try { const d = await api('/tools/media/favorites'); setFavIds(new Set(d.map(f => f.tmdb_id))); }
    catch (_) {}
  }, []);
  useEffect(() => { load(); }, []);

  const toggle = async (movie, isFav) => {
    if (isFav) {
      await api(`/tools/media/favorites/${movie.id}`, { method:'DELETE' });
      setFavIds(prev => { const s = new Set(prev); s.delete(movie.id); return s; });
    } else {
      await api('/tools/media/favorites', { body: {
        tmdb_id: movie.id, title: movie.title,
        poster_path: movie.poster_path || '',
        release_date: movie.release_date || '',
        release_date_de: fmtDE(movie.release_date),
        genres: movie.genres || [], fsk: movie.fsk || '',
        media_type: movie.media_type || 'movie',
      }});
      setFavIds(prev => new Set([...prev, movie.id]));
    }
  };
  return [favIds, toggle];
}

// ── Kino Grid – alle laufenden Filme ─────────────────────────────────────────
function KinoGrid({ onOpenModal, xrelIds, onXrelLoaded }) {
  const [movies,   setMovies]   = useState([]);
  const [loading,  setLoading]  = useState(true);
  const [error,    setError]    = useState('');
  const [favIds, toggleFav]     = useFavIds();

  // Filme laden + Cache-Status für Badges
  useEffect(() => {
    setLoading(true); setError('');
    api('/tools/media/now-playing')
      .then(list => {
        setMovies(list);
        // Badges aus Cache laden (kein xREL-Call, nur DB)
        const ids = list.map(m => m.id).join(',');
        if (ids) api(`/tools/media/xrel-cached?ids=${ids}`)
          .then(result => {
            const hits = Object.entries(result).filter(([,v])=>v).map(([k])=>Number(k));
            if (hits.length) onXrelLoaded?.(hits);
          }).catch(()=>{});
      })
      .catch(e => setError(e.message))
      .finally(() => setLoading(false));
  }, []);

  // xREL-Badges: startet einmalig wenn Filme geladen, ID-String als stable dependency

  const onToggle = async (movie, isFav) => {
    try { await toggleFav(movie, isFav); } catch (e) { alert(e.message); }
  };

  if (loading) return <StatusBox>⏳ Lädt Kinocharts…</StatusBox>;
  if (error)   return <ErrorBox msg={error} />;
  if (!movies.length) return <StatusBox>Keine Filme gefunden</StatusBox>;

  const top10 = movies.filter(m => m.rank != null);
  const rest  = movies.filter(m => m.rank == null);

  return (
    <div>
      {top10.length > 0 && (
        <>
          <div style={{ ...S.head, marginBottom:12 }}>★ TOP 10 – MEISTGESEHEN</div>
          <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(130px,1fr))', gap:12, marginBottom:24 }}>
            {top10.map(m => <MovieCard key={m.id} movie={m} favIds={favIds} hasXrel={xrelIds?.has(m.id)} onToggleFav={onToggle} onOpenModal={onOpenModal} />)}
          </div>
        </>
      )}
      {rest.length > 0 && (
        <>
          <div style={{ ...S.head, marginBottom:12 }}>WEITERE FILME IM KINO</div>
          <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(130px,1fr))', gap:12 }}>
            {rest.map(m => <MovieCard key={m.id} movie={m} favIds={favIds} hasXrel={xrelIds?.has(m.id)} onToggleFav={onToggle} onOpenModal={onOpenModal} />)}
          </div>
        </>
      )}
    </div>
  );
}

// ── Demnächst – wochenweise Neustarts ────────────────────────────────────────
function DemnächstGrid({ onOpenModal, xrelIds, onXrelLoaded }) {
  const [groups,  setGroups]  = useState({});
  const [loading, setLoading] = useState(true);
  const [error,   setError]   = useState('');
  const [favIds, toggleFav]   = useFavIds();

  useEffect(() => {
    setLoading(true); setError('');
    api('/tools/media/upcoming')
      .then(grps => {
        setGroups(grps);
        const ids = Object.values(grps).flat().map(m => m.id).join(',');
        if (ids) api(`/tools/media/xrel-cached?ids=${ids}`)
          .then(result => {
            const hits = Object.entries(result).filter(([,v])=>v).map(([k])=>Number(k));
            if (hits.length) onXrelLoaded?.(hits);
          }).catch(()=>{});
      })
      .catch(e => setError(e.message))
      .finally(() => setLoading(false));
  }, []);


  const onToggle = async (movie, isFav) => {
    try { await toggleFav(movie, isFav); } catch (e) { alert(e.message); }
  };

  if (loading) return <StatusBox>⏳ Lädt Neustarts…</StatusBox>;
  if (error)   return <ErrorBox msg={error} />;

  const entries = Object.entries(groups).sort(([a],[b]) => a.localeCompare(b));
  if (!entries.length) return <StatusBox>Keine kommenden Filme gefunden</StatusBox>;

  return (
    <div style={{ display:'flex', flexDirection:'column', gap:28 }}>
      {entries.map(([weekStart, movies]) => (
        <div key={weekStart}>
          <div style={{ ...S.head, marginBottom:12, display:'flex', alignItems:'center', gap:8 }}>
            <span>NEUSTART {fmtWeek(weekStart)}</span>
            <div style={{ flex:1, height:1, background:'rgba(255,255,255,0.07)' }}/>
            <span style={{ fontSize:9 }}>{movies.length} Film{movies.length!==1?'e':''}</span>
          </div>
          <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(130px,1fr))', gap:12 }}>
            {movies.map(m => <MovieCard key={m.id} movie={m} favIds={favIds} hasXrel={xrelIds?.has(m.id)} onToggleFav={onToggle} onOpenModal={onOpenModal} />)}
          </div>
        </div>
      ))}
    </div>
  );
}

// ── Suche ────────────────────────────────────────────────────────────────────
// ── Aufklappbare Film/Serien-Sektion ─────────────────────────────────────────
function CollapsibleSection({ label, count, children, defaultOpen=true }) {
  const [open, setOpen] = useState(defaultOpen);
  return (
    <div style={{marginBottom:16}}>
      <button onClick={()=>setOpen(v=>!v)} style={{
        display:'flex',alignItems:'center',gap:8,background:'none',border:'none',cursor:'pointer',
        width:'100%',padding:'6px 0',marginBottom: open?10:0,
      }}>
        <span style={{color:'rgba(255,255,255,0.5)',fontFamily:'monospace',fontSize:11,letterSpacing:1}}>
          {label} ({count})
        </span>
        <div style={{flex:1,height:1,background:'rgba(255,255,255,0.07)'}}/>
        <span style={{color:'rgba(255,255,255,0.3)',fontSize:11,transform:open?'rotate(90deg)':'none',transition:'transform 0.2s'}}>▶</span>
      </button>
      {open && children}
    </div>
  );
}

function SectionedGrid({ films, serien, favIds, xrelIds, onToggle, onOpenModal }) {
  return (
    <div>
      {films.length > 0 && (
        <CollapsibleSection label="🎬 FILME" count={films.length}>
          <div style={{display:'grid',gridTemplateColumns:'repeat(auto-fill,minmax(130px,1fr))',gap:12}}>
            {films.map(m => <MovieCard key={'m'+m.id} movie={m} favIds={favIds} hasXrel={xrelIds?.has(m.id)} onToggleFav={onToggle} onOpenModal={onOpenModal}/>)}
          </div>
        </CollapsibleSection>
      )}
      {serien.length > 0 && (
        <CollapsibleSection label="📺 SERIEN" count={serien.length}>
          <div style={{display:'grid',gridTemplateColumns:'repeat(auto-fill,minmax(130px,1fr))',gap:12}}>
            {serien.map(m => <MovieCard key={'t'+m.id} movie={m} favIds={favIds} hasXrel={xrelIds?.has(m.id)} onToggleFav={onToggle} onOpenModal={onOpenModal}/>)}
          </div>
        </CollapsibleSection>
      )}
    </div>
  );
}

function SucheGrid({ onOpenModal, xrelIds, onXrelLoaded }) {
  const [query,   setQuery]   = useState('');
  const [results, setResults] = useState(null); // null=noch nicht gesucht
  const [loading, setLoading] = useState(false);
  const [error,   setError]   = useState('');
  const [favIds, toggleFav]   = useFavIds();
  const inputRef = useRef(null);

  const doSearch = async (q = query) => {
    const trimmed = q.trim();
    if (!trimmed || trimmed.length < 2) return;
    setLoading(true); setError(''); setResults(null);
    try {
      const list = await api(`/tools/media/search?q=${encodeURIComponent(trimmed)}`);
      // Neueste zuerst
      list.sort((a,b) => (b.release_date||'').localeCompare(a.release_date||''));
      setResults(list);
      // xREL-Badges aus Cache
      if (list.length) {
        const ids = list.map(m => m.id).join(',');
        api(`/tools/media/xrel-cached?ids=${ids}`)
          .then(r => {
            const hits = Object.entries(r).filter(([,v])=>v).map(([k])=>Number(k));
            if (hits.length) onXrelLoaded?.(hits);
          }).catch(()=>{});
      }
    } catch(e) { setError(e.message); }
    finally { setLoading(false); }
  };

  const onToggle = async (movie, isFav) => {
    try { await toggleFav(movie, isFav); } catch(e) { alert(e.message); }
  };

  const onKey = e => { if (e.key === 'Enter') doSearch(); };

  return (
    <div>
      {/* Suchfeld */}
      <div style={{ display:'flex', gap:8, marginBottom:20 }}>
        <input
          ref={inputRef}
          value={query}
          onChange={e => setQuery(e.target.value)}
          onKeyDown={onKey}
          placeholder="Film- oder Serientitel eingeben…"
          style={{
            flex:1, background:'rgba(255,255,255,0.06)', border:'1px solid rgba(255,255,255,0.15)',
            borderRadius:8, padding:'9px 14px', color:'#fff', fontFamily:"'Space Mono',monospace",
            fontSize:13, outline:'none',
          }}
        />
        <button
          onClick={() => doSearch()}
          disabled={loading || query.trim().length < 2}
          style={{
            background:'rgba(78,205,196,0.15)', border:'1px solid rgba(78,205,196,0.3)',
            color:'#4ecdc4', borderRadius:8, padding:'9px 18px', cursor:'pointer',
            fontFamily:"'Space Mono',monospace", fontSize:12, fontWeight:700,
            opacity: loading || query.trim().length < 2 ? 0.5 : 1,
          }}
        >
          {loading ? '⏳' : '🔍 Suchen'}
        </button>
      </div>

      {error && <ErrorBox msg={error} />}

      {results === null && !loading && (
        <StatusBox>Filmtitel eingeben und Suchen drücken</StatusBox>
      )}

      {results !== null && results.length === 0 && (
        <StatusBox>Keine Ergebnisse für „{query}"</StatusBox>
      )}
      {results !== null && results.length > 0 && (() => {
        const films  = results.filter(m => m.media_type !== 'tv');
        const serien = results.filter(m => m.media_type === 'tv');
        return <SectionedGrid films={films} serien={serien} favIds={favIds} xrelIds={xrelIds} onToggle={onToggle} onOpenModal={onOpenModal}/>;
      })()}
    </div>
  );
}

// ── FavCard – einzelner Favoriten-Eintrag ─────────────────────────────────────
function FavCard({ f, onOpenModal, onRemove }) {
  const genres   = (() => { try { return JSON.parse(f.genres||'[]'); } catch { return []; } })();
  const fskStyle = FSK_COLOR(f.fsk);
  return (
    <div onClick={() => onOpenModal({ id: f.tmdb_id, media_type: f.media_type || 'movie' })} style={{
      display:'flex', gap:12, alignItems:'flex-start',
      background:'rgba(255,255,255,0.03)', border:'1px solid rgba(255,255,255,0.06)',
      borderRadius:8, padding:'10px 12px', cursor:'pointer', position:'relative',
    }}>
      <div style={{ width:44, height:66, flexShrink:0, borderRadius:5, overflow:'hidden', background:'#111' }}>
        {f.poster_path
          ? <img src={POSTER + f.poster_path} alt={f.title} style={{ width:'100%', height:'100%', objectFit:'cover', display:'block' }} />
          : <div style={{ width:'100%', height:'100%', display:'flex', alignItems:'center', justifyContent:'center', fontSize:18 }}>
              {f.media_type==='tv'?'📺':'🎬'}
            </div>
        }
      </div>
      <div style={{ flex:1, minWidth:0 }}>
        <div style={{ fontSize:13, fontWeight:700, color:'#fff', fontFamily:"'Space Mono',monospace",
          overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{f.title}</div>
        <div style={{ fontSize:10, color:'rgba(255,255,255,0.4)', marginTop:3, fontFamily:'monospace' }}>
          🇩🇪 {f.release_date_de || '–'}
        </div>
        {genres.length > 0 && (
          <div style={{ fontSize:10, color:'#4ecdc4', marginTop:2, fontFamily:'monospace' }}>
            {genres.slice(0,3).join(' · ')}
          </div>
        )}
        {f.fsk && (
          <span style={{ ...fskStyle, fontSize:9, padding:'1px 5px', borderRadius:3, marginTop:4, display:'inline-block' }}>
            FSK {f.fsk}
          </span>
        )}
      </div>
      <button onClick={e=>{ e.stopPropagation(); onRemove(f.tmdb_id); }} style={{
        background:'rgba(248,113,113,0.1)', border:'1px solid rgba(248,113,113,0.25)',
        borderRadius:5, padding:'3px 8px', color:'#f87171', fontFamily:'monospace',
        fontSize:10, cursor:'pointer', flexShrink:0,
      }}>✕</button>
    </div>
  );
}

// ── Favoriten Kalender ────────────────────────────────────────────────────────
function FavoritenKalender({ onOpenModal }) {
  const [favs,      setFavs]    = useState([]);
  const [allFavs,   setAllFavs] = useState([]);
  const [loading,   setLoading] = useState(true);
  const [error,     setError]   = useState('');
  const [adminTab,  setAdminTab]= useState(false);
  const [isAdmin,   setIsAdmin] = useState(false);

  useEffect(() => {
    setLoading(true); setError('');
    Promise.all([
      api('/tools/media/favorites'),
      api('/tools/media/favorites/all').catch(() => null),
    ]).then(([mine, all]) => {
      setFavs(mine);
      if (all) { setAllFavs(all); setIsAdmin(true); }
    }).catch(e => setError(e.message)).finally(() => setLoading(false));
  }, []);

  const ackAll = async () => {
    await api('/tools/media/favorites/acknowledge-all', { method:'POST', body:{} });
    setAllFavs(prev => prev.map(f => ({ ...f, acknowledged: 1 })));
  };

  const removeFav = async (tmdbId) => {
    try {
      await api(`/tools/media/favorites/${tmdbId}`, { method:'DELETE' });
      setFavs(prev => prev.filter(f => f.tmdb_id !== tmdbId));
    } catch (e) { alert(e.message); }
  };

  if (loading) return <StatusBox>⏳ Lädt…</StatusBox>;
  if (error)   return <ErrorBox msg={error} />;

  // Admin-Ansicht: alle Favoriten nach User gruppiert
  if (isAdmin && adminTab) {
    const unacked = allFavs.filter(f => !f.acknowledged).length;
    const userGroups = {};
    allFavs.forEach(f => {
      if (!userGroups[f.username]) userGroups[f.username] = [];
      userGroups[f.username].push(f);
    });
    return (
      <div>
        <div style={{display:'flex',gap:8,marginBottom:16,alignItems:'center',flexWrap:'wrap'}}>
          <button onClick={()=>setAdminTab(false)}
            style={{background:'rgba(255,255,255,0.06)',border:'1px solid rgba(255,255,255,0.12)',
              borderRadius:7,padding:'5px 12px',color:'rgba(255,255,255,0.6)',fontFamily:'monospace',fontSize:11,cursor:'pointer'}}>
            ← Meine Favoriten
          </button>
          {unacked > 0 && (
            <button onClick={ackAll}
              style={{background:'rgba(245,158,11,0.12)',border:'1px solid rgba(245,158,11,0.35)',
                borderRadius:7,padding:'5px 12px',color:'#f59e0b',fontFamily:'monospace',fontSize:11,cursor:'pointer'}}>
              ✓ Alle {unacked} quittieren
            </button>
          )}
        </div>
        {!allFavs.length
          ? <StatusBox>Noch keine Favoriten von irgendjemandem.</StatusBox>
          : Object.entries(userGroups).map(([username, items]) => (
            <div key={username} style={{marginBottom:20}}>
              <div style={{display:'flex',alignItems:'center',gap:8,marginBottom:8,
                padding:'6px 10px',background:'rgba(255,255,255,0.04)',borderRadius:8}}>
                <span style={{color:'rgba(255,255,255,0.6)',fontFamily:'monospace',fontSize:12,fontWeight:700}}>
                  👤 {username}
                </span>
                <span style={{color:'rgba(255,255,255,0.3)',fontFamily:'monospace',fontSize:10}}>
                  {items.length} Favorit{items.length!==1?'en':''}
                </span>
                {items.filter(f=>!f.acknowledged).length > 0 && (
                  <span style={{background:'rgba(245,158,11,0.2)',border:'1px solid rgba(245,158,11,0.4)',
                    borderRadius:10,padding:'1px 7px',color:'#f59e0b',fontFamily:'monospace',fontSize:9}}>
                    {items.filter(f=>!f.acknowledged).length} neu
                  </span>
                )}
              </div>
              <div style={{display:'flex',flexDirection:'column',gap:4}}>
                {items.map(f => (
                  <div key={f.id} style={{display:'flex',alignItems:'center',gap:10,padding:'8px 12px',
                    background:!f.acknowledged?'rgba(245,158,11,0.05)':'rgba(255,255,255,0.02)',
                    border:`1px solid ${!f.acknowledged?'rgba(245,158,11,0.2)':'rgba(255,255,255,0.05)'}`,
                    borderRadius:8}}>
                    {f.poster_path
                      ? <img src={POSTER+f.poster_path} alt={f.title} style={{width:32,height:48,objectFit:'cover',borderRadius:4,flexShrink:0}}/>
                      : <div style={{width:32,height:48,background:'#111',borderRadius:4,flexShrink:0,display:'flex',alignItems:'center',justifyContent:'center',fontSize:14}}>
                          {f.media_type==='tv'?'📺':'🎬'}
                        </div>
                    }
                    <div style={{flex:1,minWidth:0}}>
                      <div style={{color:'rgba(255,255,255,0.85)',fontFamily:'monospace',fontSize:12,
                        overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
                        {f.title}
                        {f.media_type==='tv' && <span style={{marginLeft:6,color:'#60a5fa',fontSize:9}}>SERIE</span>}
                      </div>
                      <div style={{color:'rgba(255,255,255,0.3)',fontFamily:'monospace',fontSize:10,marginTop:2}}>
                        ⭐ {f.added_at ? new Date(f.added_at).toLocaleDateString('de-DE') : '—'}
                        {!!f.acknowledged && <span style={{marginLeft:6}}>✓</span>}
                      </div>
                    </div>
                    {!f.acknowledged && (
                      <button onClick={async e=>{e.stopPropagation();
                        await api(`/tools/media/favorites/${f.id}/acknowledge`,{method:'POST',body:{}});
                        setAllFavs(prev=>prev.map(x=>x.id===f.id?{...x,acknowledged:1}:x));
                      }} style={{background:'rgba(245,158,11,0.1)',border:'1px solid rgba(245,158,11,0.3)',
                        borderRadius:6,padding:'3px 10px',color:'#f59e0b',fontFamily:'monospace',fontSize:9,cursor:'pointer',flexShrink:0}}>
                        ✓
                      </button>
                    )}
                  </div>
                ))}
              </div>
            </div>
          ))
        }
      </div>
    );
  }
  if (!favs.length) return (
    <div>
      {isAdmin && (
        <button onClick={()=>setAdminTab(true)}
          style={{marginBottom:12,background:'rgba(255,255,255,0.05)',border:'1px solid rgba(255,255,255,0.1)',
            borderRadius:7,padding:'5px 12px',color:'rgba(255,255,255,0.5)',fontFamily:'monospace',fontSize:11,cursor:'pointer'}}>
          👥 Alle Favoriten ({allFavs.length})
        </button>
      )}
      <StatusBox>Noch keine Favoriten – markiere Filme mit ❤</StatusBox>
    </div>
  );

  // Aufteilen in Filme und Serien, dann nach Datum gruppieren
  const filmeFavs  = favs.filter(f => f.media_type !== 'tv');
  const serienFavs = favs.filter(f => f.media_type === 'tv');

  function buildGroups(list) {
    const g = {};
    for (const f of list) {
      const d     = f.release_date ? new Date(f.release_date) : null;
      const key   = d ? `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}` : 'unbekannt';
      const label = d ? d.toLocaleDateString('de-DE', { month:'long', year:'numeric' }) : 'Unbekannt';
      if (!g[key]) g[key] = { label, items:[] };
      g[key].items.push(f);
    }
    return g;
  }
  const filmGroups  = buildGroups(filmeFavs);
  const serienGroups = buildGroups(serienFavs);

  return (
    <div style={{ display:'flex', flexDirection:'column', gap:24 }}>
      {isAdmin && (
        <button onClick={()=>setAdminTab(true)}
          style={{marginBottom:4,background:'rgba(255,255,255,0.05)',border:'1px solid rgba(255,255,255,0.1)',
            borderRadius:7,padding:'5px 12px',color:'rgba(255,255,255,0.5)',fontFamily:'monospace',fontSize:11,cursor:'pointer',
            display:'flex',alignItems:'center',gap:6,width:'fit-content'}}>
          👥 Alle Favoriten ({allFavs.length})
          {allFavs.filter(f=>!f.acknowledged).length > 0 && (
            <span style={{background:'rgba(245,158,11,0.2)',border:'1px solid rgba(245,158,11,0.4)',
              borderRadius:10,padding:'1px 7px',color:'#f59e0b',fontSize:9}}>
              {allFavs.filter(f=>!f.acknowledged).length} neu
            </span>
          )}
        </button>
      )}
      {filmeFavs.length > 0 && (
        <CollapsibleSection label="🎬 FILME" count={filmeFavs.length}>
          {Object.entries(filmGroups).sort(([a],[b]) => a.localeCompare(b)).map(([key, group]) => (
            <div key={'film-'+key} style={{marginBottom:12}}>
              <div style={{...S.head,marginBottom:6,display:'flex',alignItems:'center',gap:6}}>
                <span>{group.label.toUpperCase()}</span>
                <div style={{flex:1,height:1,background:'rgba(255,255,255,0.07)'}}/>
                <span style={{fontSize:9}}>{group.items.length}×</span>
              </div>
              <div style={{display:'flex',flexDirection:'column',gap:6}}>
                {group.items.map(f => <FavCard key={f.tmdb_id} f={f} onOpenModal={onOpenModal} onRemove={removeFav}/>)}
              </div>
            </div>
          ))}
        </CollapsibleSection>
      )}
      {serienFavs.length > 0 && (
        <CollapsibleSection label="📺 SERIEN" count={serienFavs.length}>
          {Object.entries(serienGroups).sort(([a],[b]) => a.localeCompare(b)).map(([key, group]) => (
            <div key={'serie-'+key} style={{marginBottom:12}}>
              <div style={{...S.head,marginBottom:6,display:'flex',alignItems:'center',gap:6}}>
                <span>{group.label.toUpperCase()}</span>
                <div style={{flex:1,height:1,background:'rgba(255,255,255,0.07)'}}/>
                <span style={{fontSize:9}}>{group.items.length}×</span>
              </div>
              <div style={{display:'flex',flexDirection:'column',gap:6}}>
                {group.items.map(f => <FavCard key={f.tmdb_id} f={f} onOpenModal={onOpenModal} onRemove={removeFav}/>)}
              </div>
            </div>
          ))}
        </CollapsibleSection>
      )}
      {false && Object.entries({}).map(([key, group]) => (
        <div key={key}>
          <div style={{ ...S.head, marginBottom:10, display:'flex', alignItems:'center', gap:8 }}>
            <span>{group.label.toUpperCase()}</span>
            <div style={{ flex:1, height:1, background:'rgba(255,255,255,0.07)' }}/>
            <span style={{ fontSize:9 }}>{group.items.length} Film{group.items.length!==1?'e':''}</span>
          </div>
          <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
            {group.items.map(f => {
              const genres   = (() => { try { return JSON.parse(f.genres||'[]'); } catch { return []; } })();
              const fskStyle = FSK_COLOR(f.fsk);
              return (
                <div key={f.tmdb_id} onClick={() => onOpenModal({ id: f.tmdb_id, media_type: f.media_type || 'movie' })} style={{
                  display:'flex', gap:12, alignItems:'flex-start',
                  background:'rgba(255,255,255,0.03)', border:'1px solid rgba(255,255,255,0.06)',
                  borderRadius:8, padding:'10px 12px', cursor:'pointer',
                }}>
                  <div style={{ width:44, height:66, flexShrink:0, borderRadius:5, overflow:'hidden', background:'#111' }}>
                    {f.poster_path
                      ? <img src={POSTER + f.poster_path} alt={f.title} style={{ width:'100%', height:'100%', objectFit:'cover', display:'block' }} />
                      : <div style={{ width:'100%', height:'100%', display:'flex', alignItems:'center', justifyContent:'center', fontSize:18 }}>🎬</div>
                    }
                  </div>
                  <div style={{ flex:1, minWidth:0 }}>
                    <div style={{ fontSize:13, fontWeight:700, color:'#fff', fontFamily:"'Space Mono',monospace",
                      overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{f.title}</div>
                    <div style={{ fontSize:10, color:'rgba(255,255,255,0.4)', marginTop:3, fontFamily:'monospace' }}>
                      🇩🇪 {f.release_date_de || '–'}
                    </div>
                    {genres.length > 0 && (
                      <div style={{ fontSize:10, color:'#4ecdc4', marginTop:2, fontFamily:'monospace' }}>
                        {genres.slice(0,3).join(' · ')}
                      </div>
                    )}
                    {fskStyle && (
                      <div style={{ display:'inline-block', marginTop:4, background:fskStyle.bg,
                        borderRadius:3, padding:'1px 5px', fontSize:9, color:fskStyle.color,
                        fontWeight:900, fontFamily:'monospace' }}>FSK {f.fsk}</div>
                    )}
                  </div>
                  <button onClick={e => { e.stopPropagation(); removeFav(f.tmdb_id); }} style={{
                    background:'none', border:'none', color:'rgba(255,107,157,0.6)',
                    cursor:'pointer', fontSize:16, flexShrink:0, padding:'0 2px', alignSelf:'center',
                  }}>✕</button>
                </div>
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );
}

// ── Film-Detail-Modal (via Portal) ────────────────────────────────────────────
function MovieModal({ tmdbId, mediaType='movie', onClose, mobile, onHasXrel, noYearFilter, isFav=false, onToggleFav }) {
  const [detail,      setDetail]      = useState(null);
  const [xrel,        setXrel]        = useState(null);   // null=nicht gesucht, []=gesucht
  const [xrelDates,   setXrelDates]   = useState([]);
  const [xrelLoading, setXrelLoading] = useState(false);
  const [loading,     setLoading]     = useState(true);
  const [error,       setError]       = useState('');

  // detail als Ref damit searchXrel immer den aktuellen Wert hat
  const detailRef = useRef(null);

  useEffect(() => {
    setLoading(true); setDetail(null); setXrel(null); setXrelDates([]); setError('');
    detailRef.current = null;
    api(`/tools/media/${mediaType === 'tv' ? 'tv' : 'movie'}/${tmdbId}`)
      .then(d => {
        setDetail(d);
        detailRef.current = d;
        setLoading(false);
        // Gecachte Releases laden (nur für Filme)
        const xrelParams = new URLSearchParams({
          title:      d.title || '',
          orig:       d.original_title || '',
          imdb_id:    d.imdb_id || '',
          year:       noYearFilter ? '0' : (d.release_date ? d.release_date.slice(0,4) : ''),
          media_type: mediaType || 'movie',
        });
        api(`/tools/media/movie/${tmdbId}/xrel?${xrelParams}`)
          .then(r => {
            if (r.xrel_dates?.length > 0) setXrelDates(r.xrel_dates);
            if (r.xrel?.length > 0) { setXrel(r.xrel); onHasXrel?.(tmdbId); }
          })
          .catch(() => {});
      })
      .catch(e => { setError(e.message); setLoading(false); });
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = prev; };
  }, [tmdbId, mediaType]);

  const searchXrel = async (forceRefresh = false) => {
    const d = detailRef.current;
    if (!d) return;
    setXrelLoading(true);
    try {
      const params = new URLSearchParams({
        title:      d.title || '',
        orig:       d.original_title || '',
        imdb_id:    d.imdb_id || '',
        year:       noYearFilter ? '0' : (d.release_date ? d.release_date.slice(0,4) : ''),
        media_type: mediaType || 'movie',
      });
      if (forceRefresh || noYearFilter) params.set('refresh', '1');
      const r = await api(`/tools/media/movie/${tmdbId}/xrel?${params}`);
      // Nur überschreiben wenn neue Daten gefunden – sonst alte behalten
      if ((r.xrel || []).length > 0) {
        setXrel(r.xrel);
        onHasXrel?.(tmdbId);
      } else if (!forceRefresh) {
        // Erster Load ohne Ergebnis → explizit leer setzen
        setXrel([]);
      }
      // Sonst: forceRefresh ohne Ergebnis → alte Liste bleibt stehen
      if (r.xrel_dates?.length > 0) setXrelDates(r.xrel_dates);
    } catch(_) { setXrel([]); }
    finally { setXrelLoading(false); }
  };

  // ESC schließt
  useEffect(() => {
    const h = e => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', h);
    return () => document.removeEventListener('keydown', h);
  }, [onClose]);

  const fskStyle = detail ? FSK_COLOR(detail.fsk) : null;

  return (
    <div onClick={onClose} style={{
      position:'fixed', inset:0, background:'rgba(0,0,0,0.8)', zIndex:9000,
      display:'flex', alignItems: mobile ? 'flex-end' : 'center', justifyContent:'center',
      backdropFilter:'blur(4px)',
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        background:'#1a1a1f', border:'1px solid rgba(255,255,255,0.12)',
        borderRadius: mobile ? '16px 16px 0 0' : 16,
        width: mobile ? '100%' : 560,
        maxHeight: mobile ? '88vh' : '85vh',
        display:'flex', flexDirection:'column',
        position:'relative',
      }}>
        {/* Backdrop + fixer Schließen-Button – NICHT im scrollenden Bereich */}
        <div style={{ position:'relative', flexShrink:0,
          borderRadius: mobile ? '16px 16px 0 0' : '16px 16px 0 0',
          overflow:'hidden',
          height: detail?.backdrop_path ? 160 : 0,
          background:'#111',
        }}>
          {detail?.backdrop_path && (
            <img src={BACKDROP + detail.backdrop_path} alt=""
              style={{ width:'100%', height:'100%', objectFit:'cover', display:'block', opacity:0.45 }} />
          )}
          {detail?.backdrop_path && (
            <div style={{ position:'absolute', inset:0,
              background:'linear-gradient(to bottom, transparent 30%, #1a1a1f)' }} />
          )}
        </div>

        {/* Schließen + Favorit – sticky außerhalb des Scroll-Containers */}
        <button onClick={onClose} style={{
          position:'absolute', top:12, right:12,
          background:'rgba(0,0,0,0.75)', border:'none', borderRadius:'50%',
          width:34, height:34, cursor:'pointer', zIndex:10,
          color:'#fff', fontSize:18, display:'flex', alignItems:'center', justifyContent:'center',
        }}>✕</button>
        {onToggleFav && detail && (
          <button onClick={() => onToggleFav(detail)} style={{
            position:'absolute', top:12, right:54,
            background:'rgba(0,0,0,0.75)', border:'none', borderRadius:'50%',
            width:34, height:34, cursor:'pointer', zIndex:10,
            color: isFav ? '#f87171' : 'rgba(255,255,255,0.6)',
            fontSize:18, display:'flex', alignItems:'center', justifyContent:'center',
          }}>{isFav ? '❤' : '🤍'}</button>
        )}

        {/* Scrollbarer Inhalt */}
        <div style={{ overflowY:'auto', WebkitOverflowScrolling:'touch', flex:1 }}>
        <div style={{ padding:'16px 20px 28px' }}>
          {loading && <StatusBox>⏳ Lädt…</StatusBox>}
          {error   && <ErrorBox msg={error} />}
          {detail  && (<>
            <div style={{ display:'flex', gap:16, alignItems:'flex-start' }}>
              {/* Poster */}
              <div style={{ width:88, flexShrink:0, borderRadius:8, overflow:'hidden', background:'#111' }}>
                {detail.poster_path
                  ? <img src={POSTER + detail.poster_path} alt={detail.title} style={{ width:'100%', display:'block' }} />
                  : <div style={{ height:132, display:'flex', alignItems:'center', justifyContent:'center', fontSize:28 }}>🎬</div>
                }
              </div>
              {/* Info */}
              <div style={{ flex:1, minWidth:0 }}>
                <div style={{ fontSize:15, fontWeight:900, color:'#fff', lineHeight:1.3,
                  fontFamily:"'Space Mono',monospace", marginBottom:4 }}>{detail.title}</div>
                {detail.tagline && (
                  <div style={{ fontSize:11, color:'rgba(255,255,255,0.4)', fontStyle:'italic', marginBottom:8 }}>{detail.tagline}</div>
                )}
                <div style={{ display:'flex', gap:5, flexWrap:'wrap', marginBottom:8 }}>
                  {detail.vote_average > 0 && <Badge bg="rgba(255,230,109,0.15)" color="#ffe66d">★ {detail.vote_average.toFixed(1)}</Badge>}
                  {detail.media_type !== 'tv' && detail.runtime > 0 && <Badge bg="rgba(255,255,255,0.07)" color="rgba(255,255,255,0.7)">⏱ {detail.runtime} Min</Badge>}
                  {detail.media_type === 'tv' && detail.number_of_seasons > 0 && <Badge bg="rgba(96,165,250,0.15)" color="#60a5fa">📺 {detail.number_of_seasons} Staffel{detail.number_of_seasons!==1?'n':''}</Badge>}
                  {detail.media_type === 'tv' && detail.number_of_episodes > 0 && <Badge bg="rgba(255,255,255,0.07)" color="rgba(255,255,255,0.7)">{detail.number_of_episodes} Ep.</Badge>}
                  {fskStyle && <Badge bg={fskStyle.bg} color={fskStyle.color}>FSK {detail.fsk}</Badge>}
                  {detail.release_date && <Badge bg="rgba(255,255,255,0.07)" color="rgba(255,255,255,0.55)">🇩🇪 {fmtDE(detail.release_date)}</Badge>}
                  {detail.countries?.length > 0 && <Badge bg="rgba(255,255,255,0.07)" color="rgba(255,255,255,0.4)">🌍 {detail.countries.slice(0,2).join(' · ')}</Badge>}
                </div>
                {detail.genres?.length > 0 && (
                  <div style={{ display:'flex', gap:4, flexWrap:'wrap' }}>
                    {detail.genres.map(g => (
                      <span key={g} style={{ fontSize:10, color:'#4ecdc4', background:'rgba(78,205,196,0.1)',
                        borderRadius:4, padding:'2px 7px', fontFamily:'monospace' }}>{g}</span>
                    ))}
                  </div>
                )}
              </div>
            </div>

            {xrelDates.length > 0 && (
              <div style={{ marginTop:16 }}>
                <div style={{ ...S.head, marginBottom:8 }}>ERSCHEINUNGSDATEN</div>
                <div style={{ display:'flex', flexDirection:'column', gap:4 }}>
                  {xrelDates.map((r, i) => (
                    <div key={i} style={{ display:'flex', justifyContent:'space-between', alignItems:'center',
                      fontSize:11, fontFamily:'monospace', padding:'3px 0',
                      borderBottom:'1px solid rgba(255,255,255,0.05)' }}>
                      <span style={{ color:'rgba(255,255,255,0.5)' }}>{r.label}</span>
                      <span style={{ color:'rgba(255,255,255,0.8)', fontWeight:600 }}>{fmtDE(r.date)}</span>
                    </div>
                  ))}
                </div>
              </div>
            )}

            {detail.overview && (
              <div style={{ marginTop:18 }}>
                <div style={{ ...S.head, marginBottom:6 }}>HANDLUNG</div>
                <div style={{ fontSize:13, color:'rgba(255,255,255,0.75)', lineHeight:1.75 }}>{detail.overview}</div>
              </div>
            )}
            {detail.director && (
              <div style={{ marginTop:14 }}>
                <div style={{ ...S.head, marginBottom:4 }}>REGIE</div>
                <div style={{ fontSize:13, color:'rgba(255,255,255,0.8)' }}>{detail.director}</div>
              </div>
            )}
            {detail.cast?.length > 0 && (
              <div style={{ marginTop:14 }}>
                <div style={{ ...S.head, marginBottom:6 }}>BESETZUNG</div>
                <div style={{ display:'flex', flexWrap:'wrap', gap:6 }}>
                  {detail.cast.map(name => (
                    <span key={name} style={{ fontSize:11, color:'rgba(255,255,255,0.65)',
                      background:'rgba(255,255,255,0.06)', borderRadius:4, padding:'3px 8px', fontFamily:'monospace' }}>
                      {name}
                    </span>
                  ))}
                </div>
              </div>
            )}

            {/* Links */}
            <div style={{ marginTop:18, display:'flex', gap:8, flexWrap:'wrap' }}>
              {detail.tmdb_url && (
                <a href={detail.tmdb_url} target="_blank" rel="noopener noreferrer" style={{
                  display:'inline-flex', alignItems:'center', gap:5,
                  fontSize:11, color:'#01d277', background:'rgba(1,210,119,0.1)',
                  border:'1px solid rgba(1,210,119,0.25)', borderRadius:6,
                  padding:'5px 11px', fontFamily:'monospace', textDecoration:'none',
                }}>🎬 TMDb</a>
              )}
              {detail.imdb_url && (
                <a href={detail.imdb_url} target="_blank" rel="noopener noreferrer" style={{
                  display:'inline-flex', alignItems:'center', gap:5,
                  fontSize:11, color:'#f5c518', background:'rgba(245,197,24,0.1)',
                  border:'1px solid rgba(245,197,24,0.25)', borderRadius:6,
                  padding:'5px 11px', fontFamily:'monospace', textDecoration:'none',
                }}>⭐ IMDb</a>
              )}
            </div>

            {/* xREL Releases */}
            <div style={{ marginTop:18 }}>
              {/* Web-Release aus frühestem WEB-Release ableiten */}
              {xrel?.length > 0 && (() => {
                const webRelease = xrel
                  .filter(r => /web/i.test(r.dirname||''))
                  .sort((a,b) => (a.date||'').localeCompare(b.date||''))[0];
                return webRelease?.date ? (
                  <div style={{ fontSize:11, color:'rgba(255,255,255,0.4)', fontFamily:'monospace', marginBottom:8 }}>
                    🌐 Erster Web-Release: <span style={{ color:'#4ecdc4' }}>{fmtDE(webRelease.date)}</span>
                    <span style={{ marginLeft:6, color:'rgba(255,255,255,0.25)', fontSize:10 }}>{webRelease.p2p ? 'P2P' : 'SCN'}</span>
                  </div>
                ) : null;
              })()}
              <div>
                  <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom: xrel?.length ? 8 : 0 }}>
                    <div style={{ ...S.head, marginBottom:0, flex:1 }}>RELEASES (XREL.TO)</div>
                    <button
                      onClick={() => searchXrel(xrel !== null && xrel.length > 0)}
                      disabled={xrelLoading}
                      style={{
                        fontSize:10, fontFamily:'monospace', cursor: xrelLoading ? 'default' : 'pointer',
                        background:'rgba(78,205,196,0.1)', border:'1px solid rgba(78,205,196,0.25)',
                        color: xrelLoading ? 'rgba(255,255,255,0.3)' : '#4ecdc4',
                        borderRadius:6, padding:'3px 10px', flexShrink:0,
                      }}
                    >
                      {xrelLoading ? '⏳ Suche…' : xrel === null ? '🔍 Nach Releases suchen' : '🔄 Erneut suchen'}
                    </button>
                  </div>
                  {xrel !== null && xrel.length === 0 && (
                    <div style={{ fontSize:11, color:'rgba(255,255,255,0.3)', fontFamily:'monospace', fontStyle:'italic' }}>
                      Keine deutschen Releases gefunden
                    </div>
                  )}
                </div>
            </div>
            {xrel !== null && xrel.length > 0 && (
              <div style={{ marginTop:4 }}>
                <div style={{ display:'flex', flexDirection:'column', gap:4 }}>
                  {xrel.map((r, i) => (
                    <a key={i} href={r.url} target="_blank" rel="noopener noreferrer" style={{
                      display:'flex', alignItems:'flex-start', gap:8,
                      background:'rgba(255,255,255,0.03)', border:'1px solid rgba(255,255,255,0.07)',
                      borderRadius:6, padding:'6px 10px', textDecoration:'none',
                    }}>
                      <span style={{ fontSize:9, fontWeight:700, fontFamily:'monospace',
                        color: r.p2p ? '#4ecdc4' : '#ff6b9d',
                        background: r.p2p ? 'rgba(78,205,196,0.12)' : 'rgba(255,107,157,0.12)',
                        borderRadius:3, padding:'1px 5px', flexShrink:0, marginTop:1 }}>
                        {r.p2p ? 'P2P' : 'SCN'}
                      </span>
                      <div style={{ flex:1, minWidth:0 }}>
                        <DirnameWrapped dirname={r.dirname} />
                        <div style={{ display:'flex', gap:8, marginTop:2 }}>
                          {r.size && <span style={{ fontSize:9, color:'rgba(255,255,255,0.35)', fontFamily:'monospace' }}>{r.size}</span>}
                          {r.date && <span style={{ fontSize:9, color:'rgba(255,255,255,0.25)', fontFamily:'monospace' }}>{r.date}</span>}
                        </div>
                      </div>
                    </a>
                  ))}
                </div>
              </div>
            )}
          </>)}
        </div>
        </div>{/* Ende scroll-wrapper */}
      </div>
    </div>
  );
}

function Badge({ children, bg, color }) {
  return (
    <span style={{ fontSize:10, background:bg, color, borderRadius:4,
      padding:'2px 7px', fontFamily:"'Space Mono',monospace", fontWeight:700 }}>
      {children}
    </span>
  );
}

// Dirname zweizeilig: vor "German." trennen
function DirnameWrapped({ dirname }) {
  if (!dirname) return null;
  const lower = dirname.toLowerCase();
  const idx = lower.indexOf('german.');
  if (idx < 0) {
    // Kein "German." – einfach umbrechen nach 40 Zeichen Worttrennung
    return <span style={{ fontSize:10, color:'rgba(255,255,255,0.75)', fontFamily:'monospace',
      wordBreak:'break-all', lineHeight:1.4 }}>{dirname}</span>;
  }
  const before = dirname.slice(0, idx + 7); // inkl. "German."
  const after  = dirname.slice(idx + 7);
  return (
    <span style={{ fontSize:10, color:'rgba(255,255,255,0.75)', fontFamily:'monospace', lineHeight:1.4 }}>
      {before}
      {after && <><br/><span style={{ color:'rgba(255,255,255,0.5)' }}>{after}</span></>}
    </span>
  );
}

function StatusBox({ children }) {
  return (
    <div style={{ padding:'28px 20px', textAlign:'center',
      color:'rgba(255,255,255,0.35)', fontFamily:"'Space Mono',monospace", fontSize:13 }}>
      {children}
    </div>
  );
}

function ErrorBox({ msg }) {
  return (
    <div style={{ padding:'20px', textAlign:'center', color:'#ff6b9d',
      fontFamily:"'Space Mono',monospace", fontSize:13 }}>
      <div>⚠ {msg}</div>
      {msg?.includes('Token') && (
        <div style={{ marginTop:8, fontSize:11, color:'rgba(255,255,255,0.4)' }}>
          Token eintragen: Einstellungen → Benutzer → <span style={{ color:'#4ecdc4' }}>TMDB API</span>
        </div>
      )}
    </div>
  );
}
