/**
 * Hooks TanStack Query pour les clients - COOP-CA AMIFOND
 *
 * Hooks personnalisés pour les requêtes clients avec TanStack Query
 */

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

import {
  ClientService,
  ClientDocumentService,
  ClientContactService,
  ClientReferralService,
  ClientActivityService,
} from "@/services/clients.service";
import type {
  Client,
  ClientListParams,
  ClientCreateRequest,
  ClientUpdateRequest,
  MemberConversionRequest,
} from "@/types/clients";

// Clés de requête pour les clients
export const CLIENTS_QUERY_KEYS = {
  all: ["clients"] as const,
  lists: () => [...CLIENTS_QUERY_KEYS.all, "list"] as const,
  list: (params: ClientListParams) => [...CLIENTS_QUERY_KEYS.lists(), params] as const,
  details: () => [...CLIENTS_QUERY_KEYS.all, "detail"] as const,
  detail: (id: number) => [...CLIENTS_QUERY_KEYS.details(), id] as const,
  stats: () => [...CLIENTS_QUERY_KEYS.all, "stats"] as const,
  documents: (clientId?: number) => ["clients", "documents", clientId] as const,
  contacts: (clientId?: number) => ["clients", "contacts", clientId] as const,
  referrals: (params?: any) => ["clients", "referrals", params] as const,
  activities: (clientId?: number) => ["clients", "activities", clientId] as const,
};

/**
 * Hook pour récupérer la liste des clients
 */
export const useClients = (params: ClientListParams = {}) => {
  return useQuery({
    queryKey: CLIENTS_QUERY_KEYS.list(params),
    queryFn: () => ClientService.getClients(params),
    staleTime: 5 * 60 * 1000, // 5 minutes
  });
};

/**
 * Hook pour récupérer un client par son ID
 */
export const useClient = (id: number) => {
  return useQuery({
    queryKey: CLIENTS_QUERY_KEYS.detail(id),
    queryFn: () => ClientService.getClient(id),
    enabled: !!id,
  });
};

/**
 * Hook pour récupérer les statistiques des clients
 */
export const useClientStats = () => {
  return useQuery({
    queryKey: CLIENTS_QUERY_KEYS.stats(),
    queryFn: () => ClientService.getClientStats(),
    staleTime: 10 * 60 * 1000, // 10 minutes
  });
};

/**
 * Hook pour créer un nouveau client
 */
export const useCreateClient = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: ClientCreateRequest) => ClientService.createClient(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: CLIENTS_QUERY_KEYS.lists() });
      queryClient.invalidateQueries({ queryKey: CLIENTS_QUERY_KEYS.stats() });
      toast.success("Client créé avec succès");
    },
    onError: (error: any) => {
      toast.error("Erreur lors de la création du client");
      console.error("Erreur création client:", error);
    },
  });
};

/**
 * Hook pour mettre à jour un client
 */
export const useUpdateClient = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, data }: { id: number; data: ClientUpdateRequest }) => ClientService.updateClient(id, data),
    onSuccess: (updatedClient) => {
      queryClient.invalidateQueries({ queryKey: CLIENTS_QUERY_KEYS.lists() });
      queryClient.invalidateQueries({ queryKey: CLIENTS_QUERY_KEYS.detail(updatedClient.id) });
      queryClient.invalidateQueries({ queryKey: CLIENTS_QUERY_KEYS.stats() });
      toast.success("Client mis à jour avec succès");
    },
    onError: (error: any) => {
      toast.error("Erreur lors de la mise à jour du client");
      console.error("Erreur mise à jour client:", error);
    },
  });
};

/**
 * Hook pour supprimer un client
 */
export const useDeleteClient = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: number) => ClientService.deleteClient(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: CLIENTS_QUERY_KEYS.lists() });
      queryClient.invalidateQueries({ queryKey: CLIENTS_QUERY_KEYS.stats() });
      toast.success("Client supprimé avec succès");
    },
    onError: (error: any) => {
      toast.error("Erreur lors de la suppression du client");
      console.error("Erreur suppression client:", error);
    },
  });
};

/**
 * Hook pour convertir un client en membre
 */
export const useConvertToMember = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ id, data }: { id: number; data: MemberConversionRequest }) =>
      ClientService.convertToMember(id, data),
    onSuccess: (convertedClient) => {
      queryClient.invalidateQueries({ queryKey: CLIENTS_QUERY_KEYS.lists() });
      queryClient.invalidateQueries({ queryKey: CLIENTS_QUERY_KEYS.detail(convertedClient.id) });
      queryClient.invalidateQueries({ queryKey: CLIENTS_QUERY_KEYS.stats() });
      toast.success("Client converti en membre avec succès");
    },
    onError: (error: any) => {
      toast.error("Erreur lors de la conversion en membre");
      console.error("Erreur conversion membre:", error);
    },
  });
};

/**
 * Hook pour récupérer le score d'un client
 */
export const useClientScore = (id: number) => {
  return useQuery({
    queryKey: [...CLIENTS_QUERY_KEYS.detail(id), "score"],
    queryFn: () => ClientService.getClientScore(id),
    enabled: !!id,
  });
};

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

  return useMutation({
    mutationFn: ({ action, client_ids, data }: { action: string; client_ids: number[]; data?: any }) =>
      ClientService.bulkAction(action, client_ids, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: CLIENTS_QUERY_KEYS.lists() });
      queryClient.invalidateQueries({ queryKey: CLIENTS_QUERY_KEYS.stats() });
      toast.success("Action effectuée avec succès");
    },
    onError: (error: any) => {
      toast.error("Erreur lors de l'action en lot");
      console.error("Erreur action en lot:", error);
    },
  });
};

/**
 * Hook pour enregistrer une activité
 */
export const useLogActivity = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({
      clientId,
      activityType,
      description,
    }: {
      clientId: number;
      activityType: string;
      description: string;
    }) => ClientService.logActivity(clientId, activityType, description),
    onSuccess: (_, variables) => {
      queryClient.invalidateQueries({
        queryKey: CLIENTS_QUERY_KEYS.activities(variables.clientId),
      });
    },
    onError: (error: any) => {
      console.error("Erreur log activité:", error);
    },
  });
};

/**
 * Hook pour récupérer les documents d'un client
 */
export const useClientDocuments = (clientId?: number) => {
  return useQuery({
    queryKey: CLIENTS_QUERY_KEYS.documents(clientId),
    queryFn: () => ClientDocumentService.getClientDocuments(clientId),
    enabled: !!clientId,
  });
};

/**
 * Hook pour télécharger un document
 */
export const useUploadDocument = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: ({ clientId, file, documentType }: { clientId: number; file: File; documentType: string }) =>
      ClientDocumentService.uploadDocument(clientId, file, documentType),
    onSuccess: (_, variables) => {
      queryClient.invalidateQueries({
        queryKey: CLIENTS_QUERY_KEYS.documents(variables.clientId),
      });
      toast.success("Document téléchargé avec succès");
    },
    onError: (error: any) => {
      toast.error("Erreur lors du téléchargement du document");
      console.error("Erreur upload document:", error);
    },
  });
};

/**
 * Hook pour récupérer les contacts d'un client
 */
export const useClientContacts = (clientId?: number) => {
  return useQuery({
    queryKey: CLIENTS_QUERY_KEYS.contacts(clientId),
    queryFn: () => ClientContactService.getClientContacts(clientId),
    enabled: !!clientId,
  });
};

/**
 * Hook pour récupérer les parrainages
 */
export const useClientReferrals = (params?: any) => {
  return useQuery({
    queryKey: CLIENTS_QUERY_KEYS.referrals(params),
    queryFn: () => ClientReferralService.getReferrals(params),
  });
};

/**
 * Hook pour récupérer les activités d'un client
 */
export const useClientActivities = (clientId?: number) => {
  return useQuery({
    queryKey: CLIENTS_QUERY_KEYS.activities(clientId),
    queryFn: () => ClientActivityService.getClientActivities(clientId),
    enabled: !!clientId,
  });
};
