import { LoginCredentials, RegisterData, UserInfo, UserRole } from '@/types';
import { apiClient } from './api';
import { tokenManager } from './tokenManager';

export class AuthService {
  private static instance: AuthService;
  
  private constructor() {}
  
  static getInstance(): AuthService {
    if (!AuthService.instance) {
      AuthService.instance = new AuthService();
    }
    return AuthService.instance;
  }

  async login(credentials: LoginCredentials): Promise<{
    user: UserInfo;
    accessToken: string;
    refreshToken: string;
  }> {
    const response = await apiClient.post<{
      user: UserInfo;
      access_token: string;
      refresh_token: string;
    }>('/auth/login', credentials);

    const { user, access_token, refresh_token } = response.data;
    tokenManager.setTokens(access_token, refresh_token);

    return {
      user,
      accessToken: access_token,
      refreshToken: refresh_token,
    };
  }

  async register(data: RegisterData): Promise<{
    user: UserInfo;
    accessToken: string;
    refreshToken: string;
  }> {
    const response = await apiClient.post<{
      user: UserInfo;
      access_token: string;
      refresh_token: string;
    }>('/auth/register', data);

    const { user, access_token, refresh_token } = response.data;
    tokenManager.setTokens(access_token, refresh_token);

    return {
      user,
      accessToken: access_token,
      refreshToken: refresh_token,
    };
  }

  async logout(): Promise<void> {
    try {
      await apiClient.post('/auth/logout');
    } catch (error) {
      // 로그아웃 API 호출 실패해도 로컬 토큰은 삭제
      console.error('Logout API call failed:', error);
    } finally {
      tokenManager.clearTokens();
    }
  }

  async refreshToken(): Promise<string> {
    const refreshToken = tokenManager.getRefreshToken();
    if (!refreshToken) {
      throw new Error('No refresh token available');
    }

    const response = await apiClient.post<{
      access_token: string;
      refresh_token: string;
    }>('/auth/refresh', {
      refresh_token: refreshToken,
    });

    const { access_token, refresh_token: newRefreshToken } = response.data;
    tokenManager.setTokens(access_token, newRefreshToken);

    return access_token;
  }

  async getCurrentUser(): Promise<UserInfo> {
    const response = await apiClient.get<UserInfo>('/auth/me');
    return response.data;
  }

  async updateProfile(data: Partial<UserInfo>): Promise<UserInfo> {
    const response = await apiClient.put<UserInfo>('/auth/profile', data);
    return response.data;
  }

  async changePassword(currentPassword: string, newPassword: string): Promise<void> {
    await apiClient.post('/auth/change-password', {
      current_password: currentPassword,
      new_password: newPassword,
    });
  }

  async forgotPassword(email: string): Promise<void> {
    await apiClient.post('/auth/forgot-password', { email });
  }

  async resetPassword(token: string, password: string): Promise<void> {
    await apiClient.post('/auth/reset-password', {
      token,
      password,
    });
  }

  isAuthenticated(): boolean {
    return tokenManager.hasValidTokens();
  }

  getCurrentUserFromToken(): UserInfo | null {
    return tokenManager.getUserInfoFromToken();
  }

  hasRole(role: UserRole): boolean {
    const user = this.getCurrentUserFromToken();
    return user?.role === role;
  }

  hasPermission(permission: string): boolean {
    const user = this.getCurrentUserFromToken();
    if (!user) return false;

    // 권한 체크 로직 구현
    const permissions = this.getRolePermissions(user.role);
    return permissions.includes(permission);
  }

  private getRolePermissions(role: UserRole): string[] {
    const permissionMap: Record<UserRole, string[]> = {
      [UserRole.ADMIN]: [
        'user:read',
        'user:write',
        'user:delete',
        'payment:read',
        'payment:write',
        'payment:refund',
        'system:config',
      ],
      [UserRole.MERCHANT]: [
        'payment:read',
        'payment:write',
        'payment:refund',
        'profile:read',
        'profile:write',
      ],
      [UserRole.USER]: [
        'payment:read',
        'profile:read',
        'profile:write',
      ],
    };

    return permissionMap[role] || [];
  }

  async verifyEmail(token: string): Promise<void> {
    await apiClient.post('/auth/verify-email', { token });
  }

  async resendVerificationEmail(): Promise<void> {
    await apiClient.post('/auth/resend-verification');
  }

  shouldRefreshToken(): boolean {
    return tokenManager.shouldRefreshToken();
  }

  getAccessToken(): string | null {
    return tokenManager.getAccessToken();
  }

  getRefreshToken(): string | null {
    return tokenManager.getRefreshToken();
  }
}

export const authService = AuthService.getInstance();