import type { TrackRef } from '$lib/api/types';

// Global multi-select state for track lists (album, library/liked,
// search results, etc.). Reset on route change by the layout effect.
//
// The store keeps both a Set of ids (for O(1) isSelected) and a Map of
// id->TrackRef (so the bulk-action bar can act on the full TrackRef
// payload without re-querying the source list). Shift-range uses the
// most recent toggle as the anchor.

let _selectedIds      = $state(new Set<string>());
let _selectedTrackMap = $state(new Map<string, TrackRef>());
let _anchorIndex      = $state<number | null>(null);

export const selection = {
  get count(): number     { return _selectedIds.size; },
  get active(): boolean   { return _selectedIds.size > 0; },
  get tracks(): TrackRef[] {
    return Array.from(_selectedTrackMap.values());
  },
  get ids(): string[]     { return Array.from(_selectedIds); },
  isSelected(id: string): boolean { return _selectedIds.has(id); }
};

export function toggleOne(track: TrackRef, index: number): void {
  const ids = new Set(_selectedIds);
  const map = new Map(_selectedTrackMap);
  if (ids.has(track.id)) {
    ids.delete(track.id);
    map.delete(track.id);
  } else {
    ids.add(track.id);
    map.set(track.id, track);
  }
  _selectedIds = ids;
  _selectedTrackMap = map;
  _anchorIndex = index;
}

// Shift-click range: select every track from the anchor to `toIndex`
// inclusive. If no anchor is set (first click ever in this list), the
// range collapses to a single toggle.
export function selectRange(toIndex: number, tracks: TrackRef[]): void {
  if (_anchorIndex === null) {
    toggleOne(tracks[toIndex], toIndex);
    return;
  }
  const from = _anchorIndex;
  const [a, b] = from <= toIndex ? [from, toIndex] : [toIndex, from];
  const ids = new Set(_selectedIds);
  const map = new Map(_selectedTrackMap);
  for (let i = a; i <= b; i++) {
    const t = tracks[i];
    if (!t) continue;
    ids.add(t.id);
    map.set(t.id, t);
  }
  _selectedIds = ids;
  _selectedTrackMap = map;
  _anchorIndex = toIndex;
}

export function clearSelection(): void {
  if (_selectedIds.size === 0 && _anchorIndex === null) return;
  _selectedIds = new Set();
  _selectedTrackMap = new Map();
  _anchorIndex = null;
}
