import type { SpotifyTokenResponse } from './types';

const SPOTIFY_AUTH_BASE = 'https://accounts.spotify.com';
const SPOTIFY_SCOPES = [
  'user-read-playback-state',
  'user-modify-playback-state',
  'user-read-currently-playing',
  'streaming',
].join(' ');

function generateRandomString(length: number): string {
  const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  const values = crypto.getRandomValues(new Uint8Array(length));
  return values.reduce((acc, x) => acc + possible[x % possible.length], '');
}

export class SpotifyAuth {
  private clientId: string;
  private redirectUri: string;

  constructor(clientId: string, redirectUri: string) {
    this.clientId = clientId;
    this.redirectUri = redirectUri;
  }

  async startAuthFlow(returnPath: string = window.location.pathname): Promise<void> {
    const randomState = generateRandomString(16);
    
    const stateWithPath = btoa(JSON.stringify({
      state: randomState,
      returnPath: returnPath
    }));
    
    sessionStorage.setItem('spotify_state', randomState);
    
    const params = new URLSearchParams({
      response_type: 'code',
      client_id: this.clientId,
      scope: SPOTIFY_SCOPES,
      redirect_uri: this.redirectUri,
      state: stateWithPath,
    });

    const authUrl = `${SPOTIFY_AUTH_BASE}/authorize?${params.toString()}`;
    window.location.href = authUrl;
  }

  async refreshAccessToken(refreshToken: string): Promise<SpotifyTokenResponse> {
    const response = await fetch('/api/spotify/token', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        refresh_token: refreshToken,
      }),
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(`Token refresh failed: ${error.error || 'Unknown error'}`);
    }

    return response.json();
  }

  getReturnPath(): string {
    return '/';
  }

  clearStoredData(): void {
    sessionStorage.removeItem('spotify_state');
  }
}