import SpotifyWebApi from 'spotify-web-api-js';
import { SpotifyTrack, SpotifyUser, RecentlyPlayedItem, SpotifyPlaylist } from '../types';

const SPOTIFY_CLIENT_ID = (import.meta as any).env.VITE_SPOTIFY_CLIENT_ID;
// Use same-origin callback for prod proxy server; env can override
const REDIRECT_URI = (import.meta as any).env.VITE_REDIRECT_URI || (typeof window !== 'undefined' ? `${window.location.origin}/callback.html` : 'http://localhost:3000/callback.html');

// Debug: Check what redirect URI is being used
console.log('🔍 Debug - Current redirect URI:', REDIRECT_URI);
console.log('🔍 Debug - Environment VITE_REDIRECT_URI:', (import.meta as any).env.VITE_REDIRECT_URI);


export const spotifyApi = new SpotifyWebApi();

export const getSpotifyAuthUrl = (): string => {
  const scopes = [
    'user-read-private',
    'user-read-email',
    'user-read-recently-played',
    'user-top-read',
    'playlist-read-private',
    'playlist-read-collaborative',
    'playlist-modify-public',
    'playlist-modify-private',
    'user-read-playback-state',
    'user-modify-playback-state',
    'user-read-currently-playing',
  ].join(' ');

  const params = new URLSearchParams({
    client_id: SPOTIFY_CLIENT_ID,
    response_type: 'code',
    redirect_uri: REDIRECT_URI,
    scope: scopes,
    show_dialog: 'true',
  });

  const authUrl = `https://accounts.spotify.com/authorize?${params.toString()}`;
  console.log('🔍 Debug - Generated Spotify Auth URL:', authUrl);
  return authUrl;
};

export const exchangeCodeForToken = async (code: string): Promise<{
  access_token: string;
  refresh_token: string;
  expires_in: number;
}> => {
  const body = new URLSearchParams({
    grant_type: 'authorization_code',
    code,
    redirect_uri: REDIRECT_URI,
  });

  console.log('🔍 Spotify - Token exchange request:', {
    code: code.substring(0, 20) + '...',
    redirect_uri: REDIRECT_URI,
    client_id: SPOTIFY_CLIENT_ID
  });

  const response = await fetch('https://accounts.spotify.com/api/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Authorization': `Basic ${btoa(`${SPOTIFY_CLIENT_ID}:${(import.meta as any).env.VITE_SPOTIFY_CLIENT_SECRET}`)}`,
    },
    body: body,
  });

  console.log('🔍 Spotify - Token exchange response:', {
    status: response.status,
    statusText: response.statusText,
    ok: response.ok
  });

  if (!response.ok) {
    const errorText = await response.text();
    console.error('🔍 Spotify - Token exchange error:', errorText);
    throw new Error(`Failed to exchange code for token: ${response.status} ${response.statusText}`);
  }

  const tokenData = await response.json();
  console.log('🔍 Spotify - Token exchange success:', !!tokenData.access_token);
  return tokenData;
};

export const refreshAccessToken = async (refreshToken: string): Promise<{
  access_token: string;
  expires_in: number;
}> => {
  const response = await fetch('https://accounts.spotify.com/api/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
           'Authorization': `Basic ${btoa(`${SPOTIFY_CLIENT_ID}:${(import.meta as any).env.VITE_SPOTIFY_CLIENT_SECRET}`)}`,
    },
    body: new URLSearchParams({
      grant_type: 'refresh_token',
      refresh_token: refreshToken,
    }),
  });

  if (!response.ok) {
    throw new Error('Failed to refresh access token');
  }

  return response.json();
};

export const initializeSpotifyApi = (accessToken: string): void => {
  spotifyApi.setAccessToken(accessToken);
};

export const fetchUserProfile = async (accessToken: string): Promise<SpotifyUser> => {
  spotifyApi.setAccessToken(accessToken);
  return spotifyApi.getMe();
};

export const fetchRecentlyPlayed = async (accessToken: string, limit = 20): Promise<RecentlyPlayedItem[]> => {
  spotifyApi.setAccessToken(accessToken);
  const response = await spotifyApi.getMyRecentlyPlayedTracks({ limit });
  return response.items;
};

export const fetchTopTracks = async (accessToken: string, timeRange = 'short_term', limit = 20): Promise<SpotifyTrack[]> => {
  spotifyApi.setAccessToken(accessToken);
  const response = await spotifyApi.getMyTopTracks({ time_range: timeRange, limit });
  return response.items;
};

export const fetchTopArtists = async (accessToken: string, timeRange = 'short_term', limit = 20) => {
  spotifyApi.setAccessToken(accessToken);
  return spotifyApi.getMyTopArtists({ time_range: timeRange, limit });
};

export const createPlaylist = async (
  accessToken: string, 
  userId: string, 
  name: string, 
  description: string
): Promise<SpotifyPlaylist> => {
  spotifyApi.setAccessToken(accessToken);
  const playlist = await spotifyApi.createPlaylist(userId, {
    name,
    description,
    public: false,
  });
  return playlist;
};

export const addTracksToPlaylist = async (
  accessToken: string,
  playlistId: string,
  trackUris: string[]
): Promise<void> => {
  spotifyApi.setAccessToken(accessToken);
  await spotifyApi.addTracksToPlaylist(playlistId, trackUris);
};

export const playTrack = async (accessToken: string, trackUri: string): Promise<void> => {
  spotifyApi.setAccessToken(accessToken);
  await spotifyApi.play({
    uris: [trackUri],
  });
};

export const pausePlayback = async (accessToken: string): Promise<void> => {
  spotifyApi.setAccessToken(accessToken);
  await spotifyApi.pause();
};

export const getCurrentPlayback = async (accessToken: string) => {
  spotifyApi.setAccessToken(accessToken);
  return spotifyApi.getMyCurrentPlaybackState();
};

// Utility function to extract track features for playlist generation
export const analyzeTrackFeatures = (tracks: SpotifyTrack[]) => {
  const features = {
    genres: new Set<string>(),
    artists: new Set<string>(),
    avgPopularity: 0,
    totalDuration: 0,
    decades: new Set<string>(),
  };

  tracks.forEach(track => {
    // Extract genres from artists (simplified)
    track.artists.forEach(artist => features.artists.add(artist.name));
    
    // Calculate average popularity
    features.avgPopularity += track.popularity;
    
    // Add duration
    features.totalDuration += track.duration_ms;
    
    // Estimate decade from album name or other clues (simplified)
    // This would typically use more sophisticated analysis
  });

  features.avgPopularity /= tracks.length;

  return features;
};

// Generate mixed playlist based on both users' music
export const generateMixedPlaylist = (
  user1Tracks: SpotifyTrack[],
  user2Tracks: SpotifyTrack[],
  playlistName: string = "Our Mixed Vibes"
): SpotifyTrack[] => {
  const allTracks = [...user1Tracks, ...user2Tracks];
  
  // Remove duplicates based on track ID
  const uniqueTracks = allTracks.filter((track, index, self) =>
    index === self.findIndex(t => t.id === track.id)
  );

  // Sort by popularity and mix them
  const sortedByPopularity = uniqueTracks.sort((a, b) => b.popularity - a.popularity);
  
  // Take top tracks and shuffle them for variety
  const topTracks = sortedByPopularity.slice(0, 30);
  const shuffled = topTracks.sort(() => Math.random() - 0.5);
  
  return shuffled.slice(0, 25); // Return 25 tracks for the playlist
};
