/**
 * Hooks React Query pour la gestion des utilisateurs - COOP-CA AMIFOND
 *
 * Hooks pour les requêtes et mutations des utilisateurs
 */

import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";

import { UsersService } from "@/services/users.service";
import { UserListParams, CreateUserRequest, UpdateUserRequest, UserAction, ApiError } from "@/types/users";

// Helper function to extract error message
const getErrorMessage = (error: ApiError, defaultMessage: string): string => {
  return error.response?.data?.detail ?? error.response?.data?.email?.[0] ?? (error.message || defaultMessage);
};

// Clés de requêtes
export const USERS_QUERY_KEYS = {
  all: ["users"] as const,
  lists: () => [...USERS_QUERY_KEYS.all, "list"] as const,
  list: (params: UserListParams) => [...USERS_QUERY_KEYS.lists(), params] as const,
  details: () => [...USERS_QUERY_KEYS.all, "detail"] as const,
  detail: (id: number) => [...USERS_QUERY_KEYS.details(), id] as const,
  stats: () => [...USERS_QUERY_KEYS.all, "stats"] as const,
  profile: (id: number) => [...USERS_QUERY_KEYS.all, "profile", id] as const,
};

/**
 * Hook pour récupérer la liste des utilisateurs
 */
export function useUsers(params: UserListParams = {}) {
  return useQuery({
    queryKey: USERS_QUERY_KEYS.list(params),
    queryFn: () => UsersService.getUsers(params),
    staleTime: 5 * 60 * 1000, // 5 minutes
  });
}

/**
 * Hook pour récupérer un utilisateur par ID
 */
export function useUser(id: number) {
  return useQuery({
    queryKey: USERS_QUERY_KEYS.detail(id),
    queryFn: () => UsersService.getUserById(id),
    enabled: !!id,
    staleTime: 5 * 60 * 1000,
  });
}

/**
 * Hook pour récupérer les statistiques des utilisateurs
 */
export function useUserStats() {
  return useQuery({
    queryKey: USERS_QUERY_KEYS.stats(),
    queryFn: () => UsersService.getUserStats(),
    staleTime: 10 * 60 * 1000, // 10 minutes
  });
}

/**
 * Hook pour récupérer le profil d'un utilisateur
 */
export function useUserProfile(userId: number) {
  return useQuery({
    queryKey: USERS_QUERY_KEYS.profile(userId),
    queryFn: () => UsersService.getUserProfile(userId),
    enabled: !!userId,
    staleTime: 5 * 60 * 1000,
  });
}

/**
 * Hook pour créer un utilisateur
 */
export function useCreateUser() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (userData: CreateUserRequest) => UsersService.createUser(userData),
    onSuccess: (newUser) => {
      // Invalider et recharger les listes d'utilisateurs
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.lists() });
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.stats() });

      toast.success(`Utilisateur ${newUser.email} créé avec succès`);
    },
    onError: (error: ApiError) => {
      const message = getErrorMessage(error, "Erreur lors de la création de l'utilisateur");
      toast.error(message);
    },
  });
}

/**
 * Hook pour modifier un utilisateur
 */
export function useUpdateUser() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, data }: { id: number; data: UpdateUserRequest }) => UsersService.updateUser(id, data),
    onSuccess: (updatedUser, { id }) => {
      // Mettre à jour le cache pour cet utilisateur
      queryClient.setQueryData(USERS_QUERY_KEYS.detail(id), updatedUser);

      // Invalider les listes pour recharger avec les nouvelles données
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.lists() });
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.stats() });

      toast.success(`Utilisateur ${updatedUser.email} modifié avec succès`);
    },
    onError: (error: ApiError) => {
      const message = getErrorMessage(error, "Erreur lors de la modification de l'utilisateur");
      toast.error(message);
    },
  });
}

/**
 * Hook pour supprimer un utilisateur
 */
export function useDeleteUser() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: number) => UsersService.deleteUser(id),
    onSuccess: (_, id) => {
      // Supprimer du cache
      queryClient.removeQueries({ queryKey: USERS_QUERY_KEYS.detail(id) });

      // Invalider les listes
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.lists() });
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.stats() });

      toast.success("Utilisateur supprimé avec succès");
    },
    onError: (error: ApiError) => {
      const message = getErrorMessage(error, "Erreur lors de la suppression de l'utilisateur");
      toast.error(message);
    },
  });
}

/**
 * Hook pour activer un utilisateur
 */
export function useActivateUser() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: number) => UsersService.activateUser(id),
    onSuccess: (_, id) => {
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.detail(id) });
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.lists() });
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.stats() });

      toast.success("Utilisateur activé avec succès");
    },
    onError: (error: ApiError) => {
      const message = getErrorMessage(error, "Erreur lors de l'activation de l'utilisateur");
      toast.error(message);
    },
  });
}

/**
 * Hook pour désactiver un utilisateur
 */
export function useDeactivateUser() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: number) => UsersService.deactivateUser(id),
    onSuccess: (_, id) => {
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.detail(id) });
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.lists() });
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.stats() });

      toast.success("Utilisateur désactivé avec succès");
    },
    onError: (error: ApiError) => {
      const message = getErrorMessage(error, "Erreur lors de la désactivation de l'utilisateur");
      toast.error(message);
    },
  });
}

/**
 * Hook pour changer le mot de passe d'un utilisateur
 */
export function useChangeUserPassword() {
  return useMutation({
    mutationFn: ({ id, password }: { id: number; password: string }) =>
      UsersService.changeUserPassword(id, { new_password: password }),
    onSuccess: () => {
      toast.success("Mot de passe modifié avec succès");
    },
    onError: (error: ApiError) => {
      const message = getErrorMessage(error, "Erreur lors du changement de mot de passe");
      toast.error(message);
    },
  });
}

/**
 * Hook pour les actions en lot
 */
export function useBulkUserAction() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (action: UserAction) => UsersService.bulkUserAction(action),
    onSuccess: (result, action) => {
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.lists() });
      queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEYS.stats() });

      const actionText = {
        activate: "activés",
        deactivate: "désactivés",
        reset_password: "mots de passe réinitialisés",
        send_verification: "emails de vérification envoyés",
      }[action.action];

      toast.success(`${action.user_ids.length} utilisateur(s) ${actionText} avec succès`);
    },
    onError: (error: ApiError) => {
      const message = getErrorMessage(error, "Erreur lors de l'action en lot");
      toast.error(message);
    },
  });
}

/**
 * Hook pour envoyer un email de vérification
 */
export function useSendVerificationEmail() {
  return useMutation({
    mutationFn: (id: number) => UsersService.sendVerificationEmail(id),
    onSuccess: () => {
      toast.success("Email de vérification envoyé avec succès");
    },
    onError: (error: ApiError) => {
      const message = getErrorMessage(error, "Erreur lors de l'envoi de l'email de vérification");
      toast.error(message);
    },
  });
}
