// Sidebar — channel list, primary nav, theme toggle
const { useMemo: useMemoSB } = React;

function Sidebar({ state, dispatch }) {
  const { channels, videos, watched, hidden, route, theme, sidebarCollapsed, userTags } = state;
  const activeChannel = route.type === 'channel' ? route.id : null;
  const activeView = route.type === 'feed' ? route.feed :
                     route.type === 'stats' ? 'stats' :
                     (route.type === 'channel' ? 'channel' : null);
  const activeTag = route.type === 'tag' ? route.tag : null;
  const [confirming, setConfirming] = React.useState(null); // {kind:'tag'|'channel', id}
  const [searchQ, setSearchQ] = React.useState('');

  const showRail = state.sidebarRail || state.focusMode;

  const totals = useMemoSB(() => {
    const t = {};
    for (const c of channels) t[c.id] = { total: 0, unwatched: 0 };
    for (const v of videos) {
      if (hidden.has(v.channelId)) continue;
      if (!t[v.channelId]) continue;
      t[v.channelId].total++;
      if (!watched.has(v.id)) t[v.channelId].unwatched++;
    }
    return t;
  }, [channels, videos, watched, hidden]);

  // Tags + counts (union of channel tags + user-created empties)
  const tags = useMemoSB(() => {
    const map = new Map();
    for (const tag of userTags) {
      map.set(tag, { tag, channels: 0, unwatched: 0 });
    }
    for (const c of channels) {
      if (hidden.has(c.id)) continue;
      for (const tag of (c.tags || [])) {
        if (!map.has(tag)) map.set(tag, { tag, channels: 0, unwatched: 0 });
        const row = map.get(tag);
        row.channels++;
        row.unwatched += (totals[c.id]?.unwatched || 0);
      }
    }
    return [...map.values()].sort((a, b) => a.tag.localeCompare(b.tag));
  }, [channels, hidden, totals, userTags]);

  const totalUnwatched = Object.values(totals).reduce((a, b) => a + b.unwatched, 0);
  const visibleChannels = channels.filter(c => !hidden.has(c.id));

  // sidebar-local tag creator state
  const [adding, setAdding] = React.useState(false);
  const [addVal, setAddVal] = React.useState('');
  const submitAdd = () => {
    const t = addVal.trim().toLowerCase().replace(/^#/, '').replace(/\s+/g, '-');
    if (!t) { setAdding(false); return; }
    dispatch({ type: 'create-tag', tag: t });
    setAddVal('');
    setAdding(false);
  };

  return (
    <aside className="sidebar">
      <div className="sb-brand">
        <div className="sb-mark">
          <img src="/assets/solotube.png" width={showRail ? 26 : 24} height={showRail ? 26 : 24} alt="SoloTube" style={{display:'inline-block',flexShrink:0}} />
          <span className="sb-mark-text">SOLOTUBE</span>
        </div>
        <button
          className="sb-rail-toggle"
          onClick={() => dispatch({ type: 'toggle-rail' })}
          title={state.sidebarRail ? 'Expand sidebar' : 'Collapse sidebar'}
        >
          {state.sidebarRail ? '›' : '‹'}
        </button>
      </div>

      {/* RAIL MODE (compact navigation) */}
      {showRail && (
        <div className="sb-rail">
          {(state.settings.railChannels || state.focusMode) && (
            <>
              <div className="sb-rail-section">
                {['all','new','watched'].map((f, i) => (
                  <button
                    key={f}
                    className={`sb-rail-item ${activeView === f ? 'active' : ''}`}
                    onClick={() => dispatch({ type: 'route', route: { type: 'feed', feed: f } })}
                    title={f === 'all' ? 'All channels' : f === 'new' ? 'Unwatched only' : 'Watched'}
                  >
                    <span className="sb-rail-num">{String(i+1).padStart(2, '0')}</span>
                  </button>
                ))}
              </div>
              <div className="sb-rail-divider"></div>
              <div className="sb-rail-section sb-rail-channels">
                {visibleChannels.map((c) => {
                  const t = totals[c.id] || { total: 0, unwatched: 0 };
                  return (
                    <button
                      key={c.id}
                      className={`sb-rail-ch ${activeChannel === c.id ? 'active' : ''}`}
                      onClick={() => dispatch({ type: 'route', route: { type: 'channel', id: c.id } })}
                      title={`${c.name} · ${t.unwatched} unwatched`}
                      style={{ background: c.accent }}
                    >
                      {c.mark}
                      {state.settings.railUnwatchedDots && t.unwatched > 0 && <span className="sb-rail-dot"></span>}
                    </button>
                  );
                })}
              </div>
            </>
          )}
          <div className="sb-rail-bottom">
            <button className="sb-rail-add" onClick={() => dispatch({ type: 'open-settings' })} title="Settings">
              <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.3">
                <circle cx="8" cy="8" r="2.2"/>
                <path d="M8 1 V3 M8 13 V15 M1 8 H3 M13 8 H15 M3 3 L4.5 4.5 M11.5 11.5 L13 13 M3 13 L4.5 11.5 M11.5 4.5 L13 3"/>
              </svg>
            </button>
            <button className="sb-rail-add" onClick={() => dispatch({ type: 'open-add' })} title="Add channel">+</button>
          </div>
        </div>
      )}

      {/* EXPANDED MODE */}
      {!showRail && (
      <>
      <div className="sb-body">

      {/* Search */}
      <div className="sb-search-wrap">
        <span className="sb-search-icon">⌕</span>
        <input
          className="sb-search-input"
          placeholder="search videos & channels…"
          value={searchQ}
          onChange={e => setSearchQ(e.target.value)}
          onKeyDown={e => { if (e.key === 'Escape') setSearchQ(''); }}
        />
        {searchQ && (
          <button className="sb-search-clear" onClick={() => setSearchQ('')}>×</button>
        )}
      </div>

      {/* Search results overlay */}
      {searchQ.trim() && (() => {
        const q = searchQ.trim().toLowerCase();
        const chHits = channels.filter(c =>
          c.name.toLowerCase().includes(q) || (c.handle || '').toLowerCase().includes(q)
        );
        const vidHits = videos.filter(v =>
          v.title.toLowerCase().includes(q)
        ).slice(0, 12);
        const nothing = chHits.length === 0 && vidHits.length === 0;
        return (
          <div className="sb-search-results">
            {nothing && (
              <div className="sb-search-empty">No results for "{searchQ}"</div>
            )}
            {chHits.length > 0 && (
              <>
                <div className="sb-search-group">CHANNELS</div>
                {chHits.map(c => (
                  <button
                    key={c.id}
                    className="sb-search-row"
                    onClick={() => { dispatch({ type: 'route', route: { type: 'channel', id: c.id } }); setSearchQ(''); }}
                  >
                    <span className="sb-search-mark" style={{ background: c.accent }}>{c.mark}</span>
                    <span className="sb-search-label">{c.name}</span>
                  </button>
                ))}
              </>
            )}
            {vidHits.length > 0 && (
              <>
                <div className="sb-search-group">VIDEOS</div>
                {vidHits.map(v => {
                  const ch = channels.find(c => c.id === v.channelId);
                  return (
                    <button
                      key={v.id}
                      className="sb-search-row"
                      onClick={() => { dispatch({ type: 'route', route: { type: 'watch', id: v.id } }); setSearchQ(''); }}
                    >
                      <span className="sb-search-mark" style={{ background: ch?.accent || '#888' }}>{ch?.mark || '▶'}</span>
                      <span className="sb-search-label">{v.title}</span>
                    </button>
                  );
                })}
              </>
            )}
          </div>
        );
      })()}

      <button
        className="sb-section-label sb-section-toggle"
        onClick={() => dispatch({ type: 'toggle-section', section: 'views' })}
      >
        <span className="chev">{sidebarCollapsed.views ? '▸' : '▾'}</span>
        <span style={{flex: 1, textAlign: 'left'}}>Views</span>
        <span className="count">05</span>
      </button>
      {!sidebarCollapsed.views && (
      <nav className="sb-nav">
        <button
          className={`sb-nav-item ${activeView === 'all' ? 'active' : ''}`}
          onClick={() => dispatch({ type: 'route', route: { type: 'feed', feed: 'all' } })}
        >
          <span className="num">01</span>
          <span className="label">All channels</span>
          {totalUnwatched > 0 && <span className="badge">{totalUnwatched}</span>}
        </button>
        <button
          className={`sb-nav-item ${activeView === 'new' ? 'active' : ''}`}
          onClick={() => dispatch({ type: 'route', route: { type: 'feed', feed: 'new' } })}
        >
          <span className="num">02</span>
          <span className="label">Unwatched only</span>
        </button>
        <button
          className={`sb-nav-item ${activeView === 'watched' ? 'active' : ''}`}
          onClick={() => dispatch({ type: 'route', route: { type: 'feed', feed: 'watched' } })}
        >
          <span className="num">03</span>
          <span className="label">Watched</span>
        </button>
        <button
          className={`sb-nav-item ${activeView === 'favorites' ? 'active' : ''}`}
          onClick={() => dispatch({ type: 'route', route: { type: 'feed', feed: 'favorites' } })}
        >
          <span className="num">04</span>
          <span className="label">Favorites</span>
          {state.favorites.size > 0 && <span className="badge badge-quiet">{state.favorites.size}</span>}
        </button>
        <button
          className={`sb-nav-item ${activeView === 'stats' ? 'active' : ''}`}
          onClick={() => dispatch({ type: 'route', route: { type: 'stats' } })}
        >
          <span className="num">05</span>
          <span className="label">Your time</span>
        </button>
      </nav>
      )}

      <button
        className="sb-section-label sb-section-toggle"
        onClick={() => dispatch({ type: 'toggle-section', section: 'tags' })}
      >
        <span className="chev">{sidebarCollapsed.tags ? '▸' : '▾'}</span>
        <span style={{flex: 1, textAlign: 'left'}}>Tags</span>
        <span className="count">{tags.length.toString().padStart(2, '0')}</span>
        <span
          className="sb-section-add"
          role="button"
          onClick={(e) => { e.stopPropagation(); if (sidebarCollapsed.tags) dispatch({type:'toggle-section', section:'tags'}); setAdding(true); }}
          title="New tag"
        >+</span>
      </button>
      {!sidebarCollapsed.tags && (
      <nav className="sb-nav sb-tags">
        {adding && (
          <div className="sb-tag-add-row">
            <span className="sb-tag-hash">#</span>
            <input
              className="sb-tag-add-input"
              autoFocus
              value={addVal}
              onChange={(e) => setAddVal(e.target.value)}
              onBlur={submitAdd}
              onKeyDown={(e) => {
                if (e.key === 'Enter') submitAdd();
                if (e.key === 'Escape') { setAdding(false); setAddVal(''); }
              }}
              placeholder="new tag…"
            />
          </div>
        )}
        {tags.length === 0 && !adding && (
          <div style={{padding: '6px 22px 8px', fontFamily:'var(--ff-mono)', fontSize: 10.5, color: 'var(--ink-3)', letterSpacing:'0.06em'}}>
            no tags yet — add one with +
          </div>
        )}
        {tags.map((row) => (
          <div key={row.tag} className={`sb-tag-item-wrap ${activeTag === row.tag ? 'active' : ''}`}>
            <button
              className={`sb-tag-item ${activeTag === row.tag ? 'active' : ''}`}
              onClick={() => dispatch({ type: 'route', route: { type: 'tag', tag: row.tag } })}
            >
              <span className="sb-tag-hash">#</span>
              <span className="sb-tag-name">{row.tag}</span>
              <span className="sb-tag-count">{row.channels}<span className="sb-tag-sep">/</span>{row.unwatched}</span>
            </button>
            {confirming?.kind === 'tag' && confirming.id === row.tag ? (
              <div className="sb-confirm">
                <button className="yes" onClick={() => { dispatch({type:'delete-tag', tag: row.tag}); setConfirming(null); }}>delete</button>
                <button className="no" onClick={() => setConfirming(null)}>cancel</button>
              </div>
            ) : (
              <button
                className="sb-row-trash"
                title="Delete tag"
                onClick={(e) => { e.stopPropagation(); setConfirming({kind:'tag', id: row.tag}); }}
              >×</button>
            )}
          </div>
        ))}
      </nav>
      )}

      <button
        className="sb-section-label sb-section-toggle"
        onClick={() => dispatch({ type: 'toggle-section', section: 'channels' })}
      >
        <span className="chev">{sidebarCollapsed.channels ? '▸' : '▾'}</span>
        <span style={{flex: 1, textAlign: 'left'}}>Channels</span>
        <span className="count">{visibleChannels.length.toString().padStart(2, '0')}</span>
      </button>
      {!sidebarCollapsed.channels && (
      <div className="sb-channels">
        {visibleChannels.map((c, i) => {
          const t = totals[c.id] || { total: 0, unwatched: 0 };
          const isConfirm = confirming?.kind === 'channel' && confirming.id === c.id;
          return (
            <div key={c.id} className={`sb-ch-item-wrap ${activeChannel === c.id ? 'active' : ''}`}>
              <button
                className={`sb-ch-item ${activeChannel === c.id ? 'active' : ''}`}
                onClick={() => dispatch({ type: 'route', route: { type: 'channel', id: c.id } })}
              >
                <span className="sb-ch-mark" style={{ background: c.accent }}>{c.mark}</span>
                <span>
                  <div className="sb-ch-name">{c.name}</div>
                  <div className="sb-ch-handle">{c.handle}</div>
                </span>
                <span className={`sb-ch-badge ${t.unwatched === 0 ? 'zero' : ''}`}>
                  {t.unwatched > 0 ? t.unwatched : '—'}
                </span>
              </button>
              {isConfirm ? (
                <div className="sb-confirm sb-confirm-ch">
                  <span className="q">Remove “{c.name}” and all its videos?</span>
                  <div className="row">
                    <button className="yes" onClick={() => { dispatch({type:'remove-channel', channelId: c.id}); setConfirming(null); }}>remove</button>
                    <button className="no" onClick={() => setConfirming(null)}>cancel</button>
                  </div>
                </div>
              ) : (
                <button
                  className="sb-row-trash sb-row-trash-ch"
                  title="Remove channel"
                  onClick={(e) => { e.stopPropagation(); setConfirming({kind:'channel', id: c.id}); }}
                >×</button>
              )}
            </div>
          );
        })}
      </div>
      )}

      <div className="sb-actions">
        <button className="sb-action" onClick={() => dispatch({ type: 'open-add' })}>+ add</button>
        <span className="sb-action-sep">·</span>
        <button className="sb-action" onClick={() => dispatch({ type: 'open-import' })} title="Import a playlist or your Takeout subscriptions">import</button>
        <span className="sb-action-sep">·</span>
        <button className="sb-action" onClick={() => dispatch({ type: 'open-scout' })} title="Ask for recommendations — only when you want them">◢ scout</button>
      </div>
      </div>{/* end sb-body */}

      <div className="sb-footer">
        <button
          className="sb-footer-gear"
          onClick={() => dispatch({ type: 'open-settings' })}
          title="Settings"
        >
          <svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.3">
            <circle cx="8" cy="8" r="2.2"/>
            <path d="M8 1 V3 M8 13 V15 M1 8 H3 M13 8 H15 M3 3 L4.5 4.5 M11.5 11.5 L13 13 M3 13 L4.5 11.5 M11.5 4.5 L13 3"/>
          </svg>
          <span>settings</span>
        </button>
      </div>
      </>
      )}
    </aside>
  );
}

window.Sidebar = Sidebar;
