import { apiClient } from '@/services/api/client';
import { Role, UserRole, AssignRoleRequest } from '../types/role';
import { AxiosError } from 'axios';

/**
 * Role Service
 * T0246: Service frontend pour gérer les rôles et permissions
 */

/**
 * Récupère tous les rôles
 * @returns Liste des rôles
 * @throws Error si la requête échoue
 */
export async function getRoles(): Promise<Role[]> {
  try {
    const response = await apiClient.get<{ roles: Role[] }>('/roles');
    return response.data.roles;
  } catch (error) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 401) {
        throw new Error('Unauthorized: Please log in to access roles');
      }
      if (error.response?.status === 403) {
        throw new Error('Forbidden: You do not have permission to view roles');
      }
      const errorMessage = error.response?.data?.error || error.message || 'Failed to fetch roles';
      throw new Error(errorMessage);
    }
    throw error;
  }
}

/**
 * Récupère un rôle par son ID
 * @param roleId ID du rôle
 * @returns Le rôle
 * @throws Error si la requête échoue
 */
export async function getRole(roleId: number): Promise<Role> {
  try {
    const response = await apiClient.get<{ role: Role }>(`/roles/${roleId}`);
    return response.data.role;
  } catch (error) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 401) {
        throw new Error('Unauthorized: Please log in to access role');
      }
      if (error.response?.status === 403) {
        throw new Error('Forbidden: You do not have permission to view this role');
      }
      if (error.response?.status === 404) {
        throw new Error('Role not found');
      }
      const errorMessage = error.response?.data?.error || error.message || 'Failed to fetch role';
      throw new Error(errorMessage);
    }
    throw error;
  }
}

/**
 * Récupère tous les rôles d'un utilisateur
 * @param userId ID de l'utilisateur
 * @returns Liste des rôles de l'utilisateur
 * @throws Error si la requête échoue
 */
export async function getUserRoles(userId: number): Promise<Role[]> {
  try {
    const response = await apiClient.get<{ roles: Role[] }>(`/users/${userId}/roles`);
    return response.data.roles;
  } catch (error) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 401) {
        throw new Error('Unauthorized: Please log in to access user roles');
      }
      if (error.response?.status === 403) {
        throw new Error('Forbidden: You do not have permission to view user roles');
      }
      if (error.response?.status === 404) {
        throw new Error('User not found');
      }
      const errorMessage = error.response?.data?.error || error.message || 'Failed to fetch user roles';
      throw new Error(errorMessage);
    }
    throw error;
  }
}

/**
 * Assigne un rôle à un utilisateur
 * @param userId ID de l'utilisateur
 * @param request Données de la requête (role_id, expires_at optionnel)
 * @throws Error si la requête échoue
 */
export async function assignRole(userId: number, request: AssignRoleRequest): Promise<void> {
  try {
    await apiClient.post(`/users/${userId}/roles`, request);
  } catch (error) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 400) {
        const errorMessage = error.response?.data?.error || 'Invalid request data';
        throw new Error(errorMessage);
      }
      if (error.response?.status === 401) {
        throw new Error('Unauthorized: Please log in to assign roles');
      }
      if (error.response?.status === 403) {
        throw new Error('Forbidden: You do not have permission to assign roles');
      }
      if (error.response?.status === 404) {
        throw new Error('User or role not found');
      }
      const errorMessage = error.response?.data?.error || error.message || 'Failed to assign role';
      throw new Error(errorMessage);
    }
    throw error;
  }
}

/**
 * Révoque un rôle d'un utilisateur
 * @param userId ID de l'utilisateur
 * @param roleId ID du rôle à révoquer
 * @throws Error si la requête échoue
 */
export async function revokeRole(userId: number, roleId: number): Promise<void> {
  try {
    await apiClient.delete(`/users/${userId}/roles/${roleId}`);
  } catch (error) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 401) {
        throw new Error('Unauthorized: Please log in to revoke roles');
      }
      if (error.response?.status === 403) {
        throw new Error('Forbidden: You do not have permission to revoke roles');
      }
      if (error.response?.status === 404) {
        throw new Error('User role assignment not found');
      }
      const errorMessage = error.response?.data?.error || error.message || 'Failed to revoke role';
      throw new Error(errorMessage);
    }
    throw error;
  }
}

/**
 * Crée un nouveau rôle
 * @param role Données du rôle à créer
 * @returns Le rôle créé
 * @throws Error si la requête échoue
 */
export async function createRole(role: Partial<Role>): Promise<Role> {
  try {
    const response = await apiClient.post<{ role: Role }>('/roles', role);
    return response.data.role;
  } catch (error) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 400) {
        const errorMessage = error.response?.data?.error || 'Invalid role data';
        throw new Error(errorMessage);
      }
      if (error.response?.status === 401) {
        throw new Error('Unauthorized: Please log in to create roles');
      }
      if (error.response?.status === 403) {
        throw new Error('Forbidden: You do not have permission to create roles');
      }
      const errorMessage = error.response?.data?.error || error.message || 'Failed to create role';
      throw new Error(errorMessage);
    }
    throw error;
  }
}

/**
 * Met à jour un rôle
 * @param roleId ID du rôle à mettre à jour
 * @param updates Données à mettre à jour
 * @throws Error si la requête échoue
 */
export async function updateRole(roleId: number, updates: Partial<Role>): Promise<void> {
  try {
    await apiClient.put(`/roles/${roleId}`, updates);
  } catch (error) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 400) {
        const errorMessage = error.response?.data?.error || 'Invalid role data';
        throw new Error(errorMessage);
      }
      if (error.response?.status === 401) {
        throw new Error('Unauthorized: Please log in to update roles');
      }
      if (error.response?.status === 403) {
        throw new Error('Forbidden: You do not have permission to update roles');
      }
      if (error.response?.status === 404) {
        throw new Error('Role not found or is a system role');
      }
      const errorMessage = error.response?.data?.error || error.message || 'Failed to update role';
      throw new Error(errorMessage);
    }
    throw error;
  }
}

/**
 * Supprime un rôle
 * @param roleId ID du rôle à supprimer
 * @throws Error si la requête échoue
 */
export async function deleteRole(roleId: number): Promise<void> {
  try {
    await apiClient.delete(`/roles/${roleId}`);
  } catch (error) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 400) {
        const errorMessage = error.response?.data?.error || 'Cannot delete system role';
        throw new Error(errorMessage);
      }
      if (error.response?.status === 401) {
        throw new Error('Unauthorized: Please log in to delete roles');
      }
      if (error.response?.status === 403) {
        throw new Error('Forbidden: You do not have permission to delete roles');
      }
      if (error.response?.status === 404) {
        throw new Error('Role not found');
      }
      const errorMessage = error.response?.data?.error || error.message || 'Failed to delete role';
      throw new Error(errorMessage);
    }
    throw error;
  }
}

