import apiClient from '../utils/api';
import { encryptAES256 } from '../utils/crypto';
import type {
  ApiResponse,
  VibeLoginRequest,
  VibePlaylistsResponse,
  VibePlaylist,
  VibeUrlRequest,
  VibeTracksRequest,
  VibeTracksResponse,
} from '../types/api';

/**
 * VIBE 서비스 클래스
 * VIBE API와의 통신을 담당
 */
class VibeService {
  private tokenKey = 'vibe_access_token';
  private sessionIdKey = 'vibe_session_id';
  private currentUserId: string | null = null;

  /**
   * 로그인 및 플레이리스트 가져오기 (통합 API)
   * @param credentials - 이메일(id)과 비밀번호
   * @returns 플레이리스트 목록
   */
  async login(credentials: VibeLoginRequest): Promise<ApiResponse<VibePlaylistsResponse>> {
    // 아이디와 비밀번호를 AES256으로 암호화
    const encryptedCredentials = {
      id: encryptAES256(credentials.id),
      password: encryptAES256(credentials.password),
    };

    const response = await apiClient.post<VibePlaylistsResponse>('/v2/vibe/playlists', encryptedCredentials);

    // 로그인 성공 시 사용자 ID 및 session_id 저장
    if (response.success && response.data?.success) {
      this.currentUserId = credentials.id;

      if (response.data.session_id) {
        this.setSessionId(response.data.session_id);
      }
    }

    return response;
  }

  /**
   * URL로 플레이리스트 가져오기
   * @param urlData - 플레이리스트 URL
   * @returns 플레이리스트 정보
   */
  async getPlaylistByUrl(urlData: VibeUrlRequest): Promise<ApiResponse<VibePlaylist>> {
    return await apiClient.post<VibePlaylist>('/vibe/playlist/url', urlData);
  }

  /**
   * 현재 로그인한 사용자 ID 반환
   */
  getCurrentUserId(): string | null {
    return this.currentUserId;
  }

  /**
   * 플레이리스트의 트랙 목록 가져오기
   * @param playlistId - 플레이리스트 ID
   * @returns 트랙 목록
   */
  async getPlaylistTracks(playlistId: string): Promise<ApiResponse<VibeTracksResponse>> {
    const sessionId = this.getSessionId();

    if (!sessionId) {
      return {
        success: false,
        error: '세션 정보가 없습니다. 다시 로그인해주세요.',
      };
    }

    const headers: Record<string, string> = {
      'X-Session-Id': sessionId,
    };

    return await apiClient.get<VibeTracksResponse>(
      `/v2/vibe/playlists/${playlistId}/tracks`,
      { headers }
    );
  }

  /**
   * 특정 플레이리스트 상세 정보 가져오기
   * @param playlistId - 플레이리스트 ID
   * @returns 플레이리스트 상세 정보
   */
  async getPlaylistById(playlistId: string): Promise<ApiResponse<VibePlaylist>> {
    const token = this.getToken();

    if (!token) {
      return {
        success: false,
        error: '로그인이 필요합니다.',
      };
    }

    return await apiClient.get<VibePlaylist>(`/vibe/playlist/${playlistId}`, { token });
  }

  /**
   * 로그아웃
   */
  logout(): void {
    this.removeToken();
    this.removeSessionId();
  }

  /**
   * 토큰 저장
   */
  private setToken(token: string): void {
    try {
      localStorage.setItem(this.tokenKey, token);
    } catch (error) {
      console.error('토큰 저장 실패:', error);
    }
  }

  /**
   * 토큰 가져오기
   */
  private getToken(): string | null {
    try {
      return localStorage.getItem(this.tokenKey);
    } catch (error) {
      console.error('토큰 가져오기 실패:', error);
      return null;
    }
  }

  /**
   * 토큰 삭제
   */
  private removeToken(): void {
    try {
      localStorage.removeItem(this.tokenKey);
    } catch (error) {
      console.error('토큰 삭제 실패:', error);
    }
  }

  /**
   * Session ID 저장
   */
  private setSessionId(sessionId: string): void {
    try {
      localStorage.setItem(this.sessionIdKey, sessionId);
    } catch (error) {
      console.error('Session ID 저장 실패:', error);
    }
  }

  /**
   * Session ID 가져오기
   */
  private getSessionId(): string | null {
    try {
      return localStorage.getItem(this.sessionIdKey);
    } catch (error) {
      console.error('Session ID 가져오기 실패:', error);
      return null;
    }
  }

  /**
   * Session ID 삭제
   */
  private removeSessionId(): void {
    try {
      localStorage.removeItem(this.sessionIdKey);
    } catch (error) {
      console.error('Session ID 삭제 실패:', error);
    }
  }

  /**
   * 로그인 상태 확인
   */
  isLoggedIn(): boolean {
    return !!this.getToken();
  }
}

// 싱글톤 인스턴스 생성 및 export
const vibeService = new VibeService();
export default vibeService;
