function SpotifyDrawer() {
  const [tab,            setTab]            = React.useState('search'); // 'search' | 'playlists'
  const [query,          setQuery]          = React.useState('');
  const [results,        setResults]        = React.useState([]);
  const [playlists,      setPlaylists]      = React.useState([]);
  const [openPlaylist,   setOpenPlaylist]   = React.useState(null); // { id, name } or null
  const [playlistTracks, setPlaylistTracks] = React.useState([]);
  const [previewTrack,   setPreviewTrack]   = React.useState(null);
  const [previewPlaying, setPreviewPlaying] = React.useState(false);
  const [searchError,    setSearchError]    = React.useState('');
  const [searching,      setSearching]      = React.useState(false);
  const [loading,        setLoading]        = React.useState(false);
  const [playlistError,  setPlaylistError]  = React.useState('');
  const [isLoggedIn,     setIsLoggedIn]     = React.useState(
    () => !!(window.TaktSpotify && TaktSpotify.isLoggedIn())
  );
  const [previewMsg,     setPreviewMsg]     = React.useState('');
  const searchTimeout = React.useRef(null);

  // Keep login state in sync with localStorage
  React.useEffect(() => {
    const check = () => setIsLoggedIn(!!(window.TaktSpotify && TaktSpotify.isLoggedIn()));
    const id = setInterval(check, 2000);
    window.addEventListener('focus',   check);
    window.addEventListener('storage', check);
    return () => {
      clearInterval(id);
      window.removeEventListener('focus',   check);
      window.removeEventListener('storage', check);
    };
  }, []);

  // Debounced Spotify search
  React.useEffect(() => {
    clearTimeout(searchTimeout.current);
    setSearchError('');
    if (!query || tab !== 'search') { setResults([]); return; }

    setSearching(true);
    searchTimeout.current = setTimeout(async () => {
      if (!window.TaktSpotify) { setSearching(false); return; }
      const { ok, error, detail, items } = await TaktSpotify.searchTracks(query);
      setSearching(false);
      if (ok) {
        setResults(items);
      } else {
        setResults([]);
        if (error === 'no-token') {
          setIsLoggedIn(false);
          setSearchError('Ikke innlogget — logg inn med Spotify');
        } else if (error === 401) {
          setIsLoggedIn(false);
          setSearchError('Innlogging utløpt — logg inn på nytt');
        } else if (error === 'network') {
          setSearchError('Nettverksfeil');
        } else {
          setSearchError(`Søk feilet (${error})${detail ? ': ' + detail : ''}`);
        }
      }
    }, 400);
    return () => clearTimeout(searchTimeout.current);
  }, [query, isLoggedIn, tab]);

  // Load playlists when tab opens
  React.useEffect(() => {
    if (tab !== 'playlists' || !isLoggedIn || !window.TaktSpotify) return;
    if (openPlaylist) return; // viewing a specific playlist
    setLoading(true);
    TaktSpotify.getPlaylists().then(({ ok, items, error }) => {
      setLoading(false);
      if (ok) setPlaylists(items);
      else if (error === 401 || error === 'no-token') setIsLoggedIn(false);
    });
  }, [tab, isLoggedIn, openPlaylist]);

  // Load tracks when a playlist is opened
  React.useEffect(() => {
    if (!openPlaylist || !window.TaktSpotify) return;
    setLoading(true);
    setPlaylistError('');
    const promise = openPlaylist.id === '__liked__'
      ? TaktSpotify.getLikedTracks()
      : TaktSpotify.getPlaylistTracks(openPlaylist.id);
    promise.then(({ ok, items, error }) => {
      setLoading(false);
      if (ok) {
        setPlaylistTracks(items);
      } else {
        setPlaylistTracks([]);
        if (error === 401 || error === 'no-token') {
          setIsLoggedIn(false);
        } else if (error === 403) {
          setPlaylistError('Spotify har låst denne spillelisten for utvikler-apper. Bruk «❤ Likte sanger» eller søk i stedet.');
        } else {
          setPlaylistError(`Kunne ikke hente sanger (${error})`);
        }
      }
    });
  }, [openPlaylist]);

  const handlePreviewToggle = async () => {
    if (!previewTrack || !window.TaktSpotify) return;
    const st = TaktSpotify.getStatus();
    if (st !== 'ready') {
      setPreviewMsg(
        st === 'no-device'  ? 'Velg en Spotify-enhet over' :
        st === 'no-premium' ? 'Spotify Premium kreves' :
                              'Logg inn med Spotify'
      );
      return;
    }
    if (previewPlaying) {
      TaktSpotify.pause();
      setPreviewPlaying(false);
    } else {
      const r = await TaktSpotify.play([{ ...previewTrack, startSec: 0 }], 0);
      if (r && r.ok) { setPreviewPlaying(true); setPreviewMsg(''); }
      else setPreviewMsg('Fikk ikke kontakt med enheten');
    }
  };

  const renderTrack = (r, i) => (
    <div key={i} draggable="true"
      onClick={() => setPreviewTrack(r)}
      onDragStart={e => e.dataTransfer.setData('spotify', JSON.stringify({
        title: r.title, artist: r.artist, bpm: r.bpm,
        durationSec: r.durationSec, notes: '', spotifyUri: r.spotifyUri || '',
      }))}
      style={{ display:'flex', alignItems:'center', gap:10, padding:'10px 14px', borderBottom:`1px solid ${PC.line}`, cursor:'grab', background:previewTrack===r?`${PC.accent}0a`:'transparent' }}>
      {r.albumArt ? (
        <img src={r.albumArt} style={{ width:38, height:38, borderRadius:3, objectFit:'cover', flexShrink:0 }} alt="" />
      ) : (
        <div style={{ width:38, height:38, borderRadius:3, background:PC.bg, border:`1px solid ${PC.line}`, display:'flex', alignItems:'center', justifyContent:'center', fontSize:16, flexShrink:0, color:PC.dim }}>♪</div>
      )}
      <div style={{ minWidth:0, flex:1 }}>
        <div style={{ fontFamily:"'Archivo',sans-serif", fontSize:13, fontWeight:600, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', color:PC.ink }}>{r.title}</div>
        <div style={{ fontFamily:"'Archivo',sans-serif", fontSize:11, color:PC.muted, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{r.artist}</div>
      </div>
      <div style={{ textAlign:'right', flexShrink:0 }}>
        <div style={{ fontFamily:"'Space Mono',monospace", fontSize:10, color:PC.dim }}>{fmt(r.durationSec)}</div>
      </div>
    </div>
  );

  const tabBtn = (key, label) => (
    <button key={key} onClick={() => { setTab(key); setOpenPlaylist(null); }}
      style={{
        flex:1, padding:'7px 10px', borderRadius:4, fontSize:11, fontFamily:"'Archivo',sans-serif", fontWeight:700,
        textTransform:'uppercase', letterSpacing:'0.08em', cursor:'pointer',
        border:`1px solid ${tab===key?PC.accent:PC.line2}`,
        background:tab===key?`${PC.accent}10`:'transparent',
        color:tab===key?PC.accent:PC.ink2,
      }}>{label}</button>
  );

  return (
    <div style={{ width:256, minWidth:256, background:PC.paper, borderRight:`1px solid ${PC.line}`, display:'flex', flexDirection:'column', overflow:'hidden' }}>

      {/* Header */}
      <div style={{ padding:'12px 14px 10px', borderBottom:`1px solid ${PC.line}`, flexShrink:0 }}>
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:isLoggedIn ? 9 : 0 }}>
          <span style={{ fontFamily:"'Archivo',sans-serif", fontWeight:700, fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', color:PC.muted }}>Spotify</span>
          {isLoggedIn && (
            <span style={{ fontFamily:"'Archivo',sans-serif", fontSize:10, color:PC.dim, letterSpacing:'0.1em', textTransform:'uppercase' }}>Dra til tidslinje →</span>
          )}
        </div>

        {isLoggedIn ? (
          <>
            <SpotifyDevicePicker style={{ marginBottom:9 }} />
            <div style={{ display:'flex', gap:5, marginBottom:8 }}>
              {tabBtn('search',    'Søk')}
              {tabBtn('playlists', 'Mine lister')}
            </div>
            {tab === 'search' && (
              <input value={query} onChange={e => setQuery(e.target.value)}
                placeholder="Søk etter sanger og artister…"
                style={{ width:'100%', padding:'9px 11px', background:PC.bg, border:`1px solid ${PC.line}`, borderRadius:4, fontFamily:"'Archivo',sans-serif", fontSize:13, color:PC.ink, outline:'none', boxSizing:'border-box' }} />
            )}
            {tab === 'playlists' && openPlaylist && (
              <button onClick={() => { setOpenPlaylist(null); setPlaylistTracks([]); }}
                style={{ display:'flex', alignItems:'center', gap:5, padding:'6px 8px', borderRadius:4, border:'none', background:'transparent', color:PC.ink2, fontFamily:"'Archivo',sans-serif", fontWeight:700, fontSize:11, cursor:'pointer' }}>
                ← Tilbake til lister
              </button>
            )}
          </>
        ) : (
          <div style={{ marginTop:12, marginBottom:2 }}>
            <button onClick={() => window.TaktSpotify?.login()}
              style={{ width:'100%', padding:'10px', borderRadius:6, border:'none', background:PC.accent, color:'#fff', fontFamily:"'Archivo',sans-serif", fontWeight:700, fontSize:13, letterSpacing:'0.06em', cursor:'pointer' }}>
              Logg inn med Spotify
            </button>
            <div style={{ marginTop:8, fontFamily:"'Archivo',sans-serif", fontSize:11, color:PC.muted, lineHeight:1.5 }}>
              Krever Spotify Premium
            </div>
          </div>
        )}
      </div>

      {/* Content */}
      <div style={{ overflowY:'auto', flex:1 }}>
        {loading && (
          <div style={{ padding:'20px 14px', textAlign:'center', fontFamily:"'Archivo',sans-serif", fontSize:12, color:PC.muted }}>Laster…</div>
        )}

        {searching && (
          <div style={{ padding:'20px 14px', textAlign:'center', fontFamily:"'Archivo',sans-serif", fontSize:12, color:PC.muted }}>Søker…</div>
        )}

        {!searching && searchError && (
          <div style={{ margin:'12px 10px', padding:'10px 12px', borderRadius:4, background:`${PC.z5}12`, border:`1px solid ${PC.z5}40` }}>
            <div style={{ fontFamily:"'Archivo',sans-serif", fontSize:12, color:PC.z5, fontWeight:600 }}>{searchError}</div>
            {(searchError.includes('innlogget') || searchError.includes('utløpt')) && (
              <button onClick={() => window.TaktSpotify?.login()}
                style={{ marginTop:8, padding:'6px 12px', borderRadius:4, border:`1px solid ${PC.accent}`, background:'transparent', color:PC.accent, fontFamily:"'Archivo',sans-serif", fontWeight:700, fontSize:11, cursor:'pointer' }}>
                Logg inn på nytt
              </button>
            )}
          </div>
        )}

        {/* SEARCH TAB */}
        {tab === 'search' && !searching && !searchError && isLoggedIn && !query && (
          <div style={{ padding:'32px 14px', textAlign:'center', fontFamily:"'Archivo',sans-serif", fontSize:12, color:PC.muted, lineHeight:1.7 }}>
            Søk etter sanger eller artister
          </div>
        )}
        {tab === 'search' && !searching && results.map(renderTrack)}
        {tab === 'search' && !searching && !searchError && results.length === 0 && query && (
          <div style={{ padding:'24px 14px', textAlign:'center', fontFamily:"'Archivo',sans-serif", fontSize:12, color:PC.muted }}>Ingen treff</div>
        )}

        {/* PLAYLISTS TAB — list of playlists */}
        {tab === 'playlists' && !openPlaylist && !loading && (
          <>
            {/* Liked songs entry — always first */}
            <div onClick={() => setOpenPlaylist({ id: '__liked__', name: 'Likte sanger' })}
              style={{ display:'flex', alignItems:'center', gap:10, padding:'10px 14px', borderBottom:`1px solid ${PC.line}`, cursor:'pointer', background:`${PC.accent}06` }}>
              <div style={{ width:38, height:38, borderRadius:3, background:`linear-gradient(135deg, ${PC.accent}, #e63900)`, display:'flex', alignItems:'center', justifyContent:'center', fontSize:18, flexShrink:0, color:'#fff' }}>♥</div>
              <div style={{ minWidth:0, flex:1 }}>
                <div style={{ fontFamily:"'Archivo',sans-serif", fontSize:13, fontWeight:700, color:PC.ink }}>Likte sanger</div>
                <div style={{ fontFamily:"'Archivo',sans-serif", fontSize:11, color:PC.muted }}>Dine ❤-merkede sanger</div>
              </div>
              <span style={{ color:PC.dim, fontSize:14, flexShrink:0 }}>›</span>
            </div>

            {playlists.map(p => (
              <div key={p.id} onClick={() => setOpenPlaylist({ id: p.id, name: p.name })}
                style={{ display:'flex', alignItems:'center', gap:10, padding:'10px 14px', borderBottom:`1px solid ${PC.line}`, cursor:'pointer' }}>
                {p.image ? (
                  <img src={p.image} style={{ width:38, height:38, borderRadius:3, objectFit:'cover', flexShrink:0 }} alt="" />
                ) : (
                  <div style={{ width:38, height:38, borderRadius:3, background:PC.bg, border:`1px solid ${PC.line}`, display:'flex', alignItems:'center', justifyContent:'center', fontSize:16, flexShrink:0, color:PC.dim }}>♫</div>
                )}
                <div style={{ minWidth:0, flex:1 }}>
                  <div style={{ fontFamily:"'Archivo',sans-serif", fontSize:13, fontWeight:600, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', color:PC.ink }}>{p.name}</div>
                  <div style={{ fontFamily:"'Archivo',sans-serif", fontSize:11, color:PC.muted, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{p.owner || '—'}</div>
                </div>
                <span style={{ color:PC.dim, fontSize:14, flexShrink:0 }}>›</span>
              </div>
            ))}

            <div style={{ padding:'14px 14px 10px', fontFamily:"'Archivo',sans-serif", fontSize:11, color:PC.dim, lineHeight:1.6 }}>
              Spotify har låst spilleliste-innhold for utvikler-apper. Bruk «Likte sanger» eller søk for å finne musikk.
            </div>
          </>
        )}
        {tab === 'playlists' && !openPlaylist && !loading && playlists.length === 0 && isLoggedIn && (
          <div style={{ padding:'32px 14px', textAlign:'center', fontFamily:"'Archivo',sans-serif", fontSize:12, color:PC.muted }}>Ingen spillelister funnet</div>
        )}

        {/* PLAYLISTS TAB — tracks of opened playlist */}
        {tab === 'playlists' && openPlaylist && !loading && (
          <>
            <div style={{ padding:'10px 14px', fontFamily:"'Archivo',sans-serif", fontWeight:800, fontSize:13, color:PC.ink, borderBottom:`1px solid ${PC.line}` }}>{openPlaylist.name}</div>
            {playlistError && (
              <div style={{ margin:'12px 10px', padding:'10px 12px', borderRadius:4, background:`${PC.z5}12`, border:`1px solid ${PC.z5}40` }}>
                <div style={{ fontFamily:"'Archivo',sans-serif", fontSize:12, color:PC.z5, fontWeight:600, lineHeight:1.5 }}>{playlistError}</div>
              </div>
            )}
            {!playlistError && playlistTracks.map(renderTrack)}
            {!playlistError && playlistTracks.length === 0 && (
              <div style={{ padding:'24px 14px', textAlign:'center', fontFamily:"'Archivo',sans-serif", fontSize:12, color:PC.muted }}>Tom spilleliste</div>
            )}
          </>
        )}
      </div>

      {/* Preview bar */}
      <div style={{ padding:'10px 14px', borderTop:`1px solid ${PC.line}`, background:PC.bg, flexShrink:0 }}>
        <div style={{ fontFamily:"'Archivo',sans-serif", fontWeight:700, fontSize:9, letterSpacing:'0.14em', textTransform:'uppercase', color:PC.muted, marginBottom:6 }}>Forhåndsvisning</div>
        {previewTrack ? (
          <>
            <div style={{ fontFamily:"'Archivo',sans-serif", fontSize:12, fontWeight:600, color:PC.ink, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', marginBottom:5 }}>{previewTrack.title}</div>
            <div style={{ display:'flex', alignItems:'center', gap:10 }}>
              <button onClick={handlePreviewToggle}
                style={{ width:28, height:28, borderRadius:'50%', background:PC.accent, color:'#fff', border:'none', fontSize:11, cursor:'pointer', flexShrink:0 }}>
                {previewPlaying ? '❚❚' : '▶'}
              </button>
              <div style={{ flex:1, height:3, background:PC.line, borderRadius:2 }} />
              <span style={{ fontFamily:"'Space Mono',monospace", fontSize:10, color:PC.muted, flexShrink:0 }}>{fmt(previewTrack.durationSec)}</span>
            </div>
            {previewMsg && (
              <div style={{ marginTop:6, fontFamily:"'Archivo',sans-serif", fontSize:11, color:PC.z3, fontWeight:600 }}>{previewMsg}</div>
            )}
          </>
        ) : (
          <div style={{ display:'flex', alignItems:'center', gap:10 }}>
            <div style={{ width:28, height:28, borderRadius:'50%', background:'rgba(22,20,15,0.06)', display:'flex', alignItems:'center', justifyContent:'center', fontSize:11, color:PC.dim, flexShrink:0 }}>▶</div>
            <div style={{ flex:1, height:3, background:PC.line, borderRadius:2 }} />
          </div>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { SpotifyDrawer });
