import { apiClient } from '@/services/api/client';
import { handleApiServiceError } from '@/utils/serviceErrorHandler';
import type {
  LoginFormData,
  RegisterFormData,
  ForgotPasswordFormData,
  ResetPasswordFormData,
} from '../types';

// INT-TYPE-008: AuthResponse aligned with backend LoginResponse (dto.LoginResponse)
// Backend format: { user: UserResponse, token: TokenResponse, requires_2fa?: boolean }
export interface AuthResponse {
  user: {
    id: string;
    email: string;
    username?: string;
  };
  token: {
    access_token: string;
    refresh_token: string;
    expires_in: number;
  };
  requires_2fa?: boolean; // BE-API-001: Flag indicating 2FA is required
}

/**
 * Authentifie un utilisateur avec email et mot de passe
 * @param data - Données de connexion (email, password)
 * @returns Promise avec les tokens et les informations utilisateur
 * @throws ApiError en cas d'erreur
 */
// INT-API-003: Standardized error handling using handleApiServiceError
export async function login(data: LoginFormData): Promise<AuthResponse> {
  try {
    const response = await apiClient.post<AuthResponse>('/auth/login', data);
    return response.data;
  } catch (error) {
    handleApiServiceError(error, {
      context: 'auth',
      customMessages: {
        401: 'Email ou mot de passe incorrect',
        403: "Votre compte n'est pas vérifié. Veuillez vérifier votre email.",
      },
    });
  }
}

/**
 * Enregistre un nouvel utilisateur
 * @param data - Données d'inscription (email, password, username)
 * @returns Promise avec les tokens et les informations utilisateur
 * @throws ApiError en cas d'erreur
 */
// INT-API-003: Standardized error handling using handleApiServiceError
export async function register(data: RegisterFormData): Promise<AuthResponse> {
  try {
    const response = await apiClient.post<AuthResponse>('/auth/register', {
      email: data.email,
      password: data.password,
      password_confirm: data.password_confirm, // Envoyer la confirmation du mot de passe
      username: data.username,
    });
    return response.data;
  } catch (error) {
    handleApiServiceError(error, {
      context: 'auth',
      customMessages: {
        409: "Cet email ou ce nom d'utilisateur est déjà utilisé",
        400: 'Les données fournies sont invalides',
      },
    });
  }
}

/**
 * Déconnecte l'utilisateur actuel
 * @throws ApiError en cas d'erreur
 */
// INT-API-003: Standardized error handling using handleApiServiceError
export async function logout(): Promise<void> {
  try {
    await apiClient.post('/auth/logout');
  } catch (error) {
    handleApiServiceError(error, { context: 'auth' });
  }
}

/**
 * Rafraîchit le token d'accès avec un refresh token
 * @param refreshToken - Le refresh token
 * @returns Promise avec les nouveaux tokens et les informations utilisateur
 * @throws ApiError en cas d'erreur
 */
// INT-API-003: Standardized error handling using handleApiServiceError
export async function refreshToken(
  refreshToken: string,
): Promise<AuthResponse> {
  try {
    const response = await apiClient.post<AuthResponse>('/auth/refresh', {
      refreshToken,
    });
    return response.data;
  } catch (error) {
    handleApiServiceError(error, { context: 'auth' });
  }
}

/**
 * Demande une réinitialisation de mot de passe
 * @param data - Données contenant l'email
 * @throws ApiError en cas d'erreur
 */
// INT-API-003: Standardized error handling using handleApiServiceError
export async function requestPasswordReset(
  data: ForgotPasswordFormData,
): Promise<void> {
  try {
    await apiClient.post('/auth/password/reset-request', data);
  } catch (error) {
    handleApiServiceError(error, { context: 'auth' });
  }
}

/**
 * Réinitialise le mot de passe avec un token
 * @param data - Données contenant le token et le nouveau mot de passe
 * @throws ApiError en cas d'erreur
 */
// INT-API-003: Standardized error handling using handleApiServiceError
export async function resetPassword(
  data: ResetPasswordFormData,
): Promise<void> {
  try {
    await apiClient.post('/auth/password/reset', {
      token: data.token,
      password: data.password,
    });
  } catch (error) {
    handleApiServiceError(error, { context: 'auth' });
  }
}

/**
 * Vérifie l'email avec un token de vérification
 * @param token - Token de vérification
 * @throws ApiError en cas d'erreur
 */
// INT-API-003: Standardized error handling using handleApiServiceError
export async function verifyEmail(token: string): Promise<void> {
  try {
    await apiClient.get(`/auth/verify-email?token=${token}`);
  } catch (error) {
    handleApiServiceError(error, { context: 'auth' });
  }
}

/**
 * Renvoie l'email de vérification
 * @param email - Email de l'utilisateur
 * @throws ApiError en cas d'erreur
 */
// INT-API-003: Standardized error handling using handleApiServiceError
export async function resendVerificationEmail(email: string): Promise<void> {
  try {
    await apiClient.post('/auth/resend-verification', { email });
  } catch (error) {
    handleApiServiceError(error, { context: 'auth' });
  }
}

/**
 * Vérifie la disponibilité d'un nom d'utilisateur
 * @param username - Le nom d'utilisateur à vérifier
 * @returns Promise avec true si disponible, false sinon
 * @throws ApiError en cas d'erreur
 */
// INT-API-003: Standardized error handling using handleApiServiceError
export async function checkUsernameAvailability(
  username: string,
): Promise<boolean> {
  try {
    const response = await apiClient.get<{ available: boolean }>(
      `/auth/check-username?username=${encodeURIComponent(username)}`,
    );
    return response.data.available;
  } catch (error) {
    handleApiServiceError(error, { context: 'auth' });
  }
}
