
/**
 * Spotify Web API — Client Credentials (browser implementation for prototype)
 *
 * ⚠️  PRODUCTION NOTE:
 * In the Next.js build, move getToken() and search() to server-side
 * route handlers at /api/spotify/token and /api/spotify/search.
 * Never expose CLIENT_SECRET in client-side code in production.
 *
 * For this HTML prototype, the calls are made directly from the browser.
 * Spotify's Client Credentials flow supports CORS for token + search endpoints.
 */

const SpotifyAPI = (() => {
  const CLIENT_ID     = 'b2dabdfdccda48449465aebdf3929156';
  const CLIENT_SECRET = 'febb0ead471a4ed3abfad654e22ba9c9';

  let cache = { token: null, expiresAt: 0 };

  async function getToken() {
    if (cache.token && Date.now() < cache.expiresAt) return cache.token;
    const resp = await fetch('https://accounts.spotify.com/api/token', {
      method: 'POST',
      headers: {
        'Authorization': 'Basic ' + btoa(`${CLIENT_ID}:${CLIENT_SECRET}`),
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: 'grant_type=client_credentials',
    });
    if (!resp.ok) throw new Error('Token fetch failed');
    const data = await resp.json();
    cache = { token: data.access_token, expiresAt: Date.now() + (data.expires_in - 300) * 1000 };
    return cache.token;
  }

  async function search(query) {
    const token = await getToken();
    // Search BOTH tracks + artists for a richer dropdown
    const url = `https://api.spotify.com/v1/search?q=${encodeURIComponent(query)}&type=track,artist&limit=6&market=US`;
    const resp = await fetch(url, { headers: { 'Authorization': `Bearer ${token}` } });
    if (!resp.ok) throw new Error('Search failed');
    const data = await resp.json();

    const tracks = (data.tracks?.items || []).map(track => ({
      kind: 'track',
      id: track.id,
      name: track.name,
      artist: track.artists[0].name,
      artistId: track.artists[0].id,
      allArtists: track.artists.map(a => a.name).join(', '),
      artwork: track.album.images[1]?.url || track.album.images[0]?.url || null,
      artworkSmall: track.album.images[2]?.url || track.album.images[1]?.url || null,
      spotifyUrl: track.external_urls.spotify,
      popularity: track.popularity,
      previewUrl: track.preview_url,
      releaseDate: track.album.release_date,
      albumName: track.album.name,
    }));

    const artists = (data.artists?.items || []).slice(0, 3).map(a => ({
      kind: 'artist',
      id: a.id,
      artistId: a.id,
      name: a.name,
      allArtists: a.name,
      artwork: a.images?.[1]?.url || a.images?.[0]?.url || null,
      artworkSmall: a.images?.[2]?.url || a.images?.[1]?.url || a.images?.[0]?.url || null,
      spotifyUrl: a.external_urls.spotify,
      popularity: a.popularity,
      followers: a.followers?.total || 0,
      genres: a.genres || [],
    }));

    // Interleave: tracks first (most relevant), then top artists
    return [...tracks.slice(0, 6), ...artists].slice(0, 8);
  }

  // Fetch rich artist details. Spotify's public API does NOT expose monthly
  // listeners directly; we derive a realistic-looking value from followers +
  // popularity for the prototype, and always return the real followers count.
  async function getArtist(artistId) {
    const token = await getToken();
    const resp = await fetch(`https://api.spotify.com/v1/artists/${artistId}`, {
      headers: { 'Authorization': `Bearer ${token}` },
    });
    if (!resp.ok) throw new Error('Artist fetch failed');
    const a = await resp.json();

    // Derive a plausible monthly-listener estimate from followers + popularity.
    // In production this would come from an authenticated source (S4A API, Chartmetric, etc).
    const followers = a.followers?.total || 0;
    const popBoost = Math.max(0.6, (a.popularity || 40) / 50);
    const monthlyListeners = Math.round(followers * popBoost * (0.9 + (a.popularity || 50) / 500));

    return {
      id: a.id,
      name: a.name,
      artwork: a.images?.[0]?.url || null,
      artworkSmall: a.images?.[2]?.url || a.images?.[1]?.url || a.images?.[0]?.url || null,
      followers,
      popularity: a.popularity,
      genres: a.genres || [],
      monthlyListeners,
      spotifyUrl: a.external_urls.spotify,
    };
  }

  async function getTopTracks(artistId) {
    const token = await getToken();
    const resp = await fetch(
      `https://api.spotify.com/v1/artists/${artistId}/top-tracks?market=US`,
      { headers: { 'Authorization': `Bearer ${token}` } }
    );
    if (!resp.ok) return [];
    const data = await resp.json();
    return (data.tracks || []).slice(0, 5).map(t => ({
      id: t.id,
      name: t.name,
      artwork: t.album.images[2]?.url || t.album.images[1]?.url || null,
      popularity: t.popularity,
      previewUrl: t.preview_url,
    }));
  }

  return { search, getArtist, getTopTracks };
})();

window.SpotifyAPI = SpotifyAPI;
