import { apiClient } from '@/services/api/client';
import { handleApiServiceError } from '@/utils/serviceErrorHandler';

/**
 * Conversation Service
 * FE-API-012: Service frontend pour gérer les conversations (chat rooms) avec toutes les opérations CRUD
 * FE-API-013: Improved error handling with user-friendly messages
 *
 * Backend endpoints:
 * - GET /api/v1/conversations - Get user conversations
 * - POST /api/v1/conversations - Create conversation
 * - GET /api/v1/conversations/:id - Get conversation by ID
 * - PUT /api/v1/conversations/:id - Update conversation
 * - DELETE /api/v1/conversations/:id - Delete conversation
 * - POST /api/v1/conversations/:id/participants - Add participant
 * - DELETE /api/v1/conversations/:id/participants/:userId - Remove participant
 * - GET /api/v1/conversations/:id/history - Get conversation history
 */

export interface Conversation {
  id: string;
  name: string;
  description?: string;
  type: 'public' | 'private' | 'direct';
  is_private: boolean;
  created_by?: string;
  participants: string[];
  created_at: string;
  updated_at: string;
}

export interface CreateConversationRequest {
  name: string;
  description?: string;
  type: 'public' | 'private' | 'direct';
  is_private?: boolean;
}

export interface UpdateConversationRequest {
  name?: string;
  description?: string;
}

export interface ConversationListResponse {
  conversations: Conversation[];
  total: number;
}

export interface ChatMessage {
  id: string;
  conversation_id: string;
  sender_id: string;
  sender_username?: string;
  content: string;
  created_at: string;
  parent_message_id?: string | null;
}

export interface ConversationHistoryResponse {
  messages: ChatMessage[];
}

/**
 * Récupère toutes les conversations de l'utilisateur connecté
 * @returns Liste des conversations avec le total
 * @throws Error si la requête échoue
 */
export async function getConversations(): Promise<ConversationListResponse> {
  try {
    // Backend returns { success: true, data: { conversations: Conversation[], total: number } }
    // apiClient unwraps to { conversations: Conversation[], total: number }
    const response =
      await apiClient.get<ConversationListResponse>('/conversations');
    return {
      conversations: response.data.conversations || [],
      total: response.data.total || 0,
    };
  } catch (error) {
    handleApiServiceError(error, {
      context: 'conversation',
      customMessages: {
        401: 'Vous devez être connecté pour voir vos conversations',
        403: "Vous n'avez pas les permissions nécessaires pour voir les conversations",
      },
    });
  }
}

/**
 * Récupère une conversation par son ID
 * @param conversationId ID de la conversation
 * @returns La conversation
 * @throws Error si la requête échoue
 */
export async function getConversation(
  conversationId: string,
): Promise<Conversation> {
  try {
    // Backend returns { success: true, data: Conversation }
    // apiClient unwraps to Conversation directly
    const response = await apiClient.get<Conversation>(
      `/conversations/${conversationId}`,
    );
    return response.data;
  } catch (error) {
    handleApiServiceError(error, {
      context: 'conversation',
      customMessages: {
        401: 'Vous devez être connecté pour accéder à cette conversation',
        403: "Vous n'avez pas accès à cette conversation",
        404: 'La conversation est introuvable',
      },
    });
  }
}

/**
 * Crée une nouvelle conversation
 * @param request Données de la conversation à créer
 * @returns La conversation créée
 * @throws Error si la requête échoue
 */
export async function createConversation(
  request: CreateConversationRequest,
): Promise<Conversation> {
  try {
    // Backend returns { success: true, data: Conversation }
    // apiClient unwraps to Conversation directly
    const response = await apiClient.post<Conversation>(
      '/conversations',
      request,
    );
    return response.data;
  } catch (error) {
    handleApiServiceError(error, {
      context: 'conversation',
      includeDetails: true, // Include validation details for 422 errors
      customMessages: {
        400: 'Les données de la conversation sont invalides',
        401: 'Vous devez être connecté pour créer une conversation',
        403: "Vous n'avez pas les permissions nécessaires pour créer des conversations",
      },
    });
  }
}

/**
 * Met à jour une conversation
 * @param conversationId ID de la conversation à mettre à jour
 * @param request Données à mettre à jour
 * @returns La conversation mise à jour
 * @throws Error si la requête échoue
 */
export async function updateConversation(
  conversationId: string,
  request: UpdateConversationRequest,
): Promise<Conversation> {
  try {
    // Backend returns { success: true, data: Conversation }
    // apiClient unwraps to Conversation directly
    const response = await apiClient.put<Conversation>(
      `/conversations/${conversationId}`,
      request,
    );
    return response.data;
  } catch (error) {
    handleApiServiceError(error, {
      context: 'conversation',
      includeDetails: true,
      customMessages: {
        400: 'Les données de mise à jour sont invalides',
        401: 'Vous devez être connecté pour mettre à jour la conversation',
        403: 'Seul le créateur de la conversation peut la modifier',
        404: 'La conversation est introuvable',
      },
    });
  }
}

/**
 * Supprime une conversation
 * @param conversationId ID de la conversation à supprimer
 * @throws Error si la requête échoue
 */
export async function deleteConversation(
  conversationId: string,
): Promise<void> {
  try {
    // Backend returns { success: true, data: { message: string } }
    // apiClient unwraps to { message: string }
    await apiClient.delete(`/conversations/${conversationId}`);
  } catch (error) {
    handleApiServiceError(error, {
      context: 'conversation',
      customMessages: {
        401: 'Vous devez être connecté pour supprimer une conversation',
        403: 'Seul le créateur de la conversation peut la supprimer',
        404: 'La conversation est introuvable',
      },
    });
  }
}

/**
 * Ajoute un participant à une conversation
 * @param conversationId ID de la conversation
 * @param userId ID de l'utilisateur à ajouter
 * @throws Error si la requête échoue
 */
export async function addParticipant(
  conversationId: string,
  userId: string,
): Promise<void> {
  try {
    // Backend returns { success: true, data: { message: string } }
    // apiClient unwraps to { message: string }
    await apiClient.post(`/conversations/${conversationId}/participants`, {
      user_id: userId,
    });
  } catch (error) {
    handleApiServiceError(error, {
      context: 'conversation',
      customMessages: {
        400: 'Les données de la requête sont invalides',
        401: 'Vous devez être connecté pour ajouter des participants',
        403: "Vous n'avez pas les permissions nécessaires pour ajouter des participants",
        404: "La conversation ou l'utilisateur est introuvable",
      },
    });
  }
}

/**
 * Retire un participant d'une conversation
 * @param conversationId ID de la conversation
 * @param userId ID de l'utilisateur à retirer
 * @throws Error si la requête échoue
 */
export async function removeParticipant(
  conversationId: string,
  userId: string,
): Promise<void> {
  try {
    // Backend returns { success: true, data: { message: string } }
    // apiClient unwraps to { message: string }
    await apiClient.delete(
      `/conversations/${conversationId}/participants/${userId}`,
    );
  } catch (error) {
    handleApiServiceError(error, {
      context: 'conversation',
      customMessages: {
        401: 'Vous devez être connecté pour retirer des participants',
        403: "Vous n'avez pas les permissions nécessaires pour retirer des participants",
        404: 'La conversation ou le participant est introuvable',
      },
    });
  }
}

/**
 * Récupère l'historique des messages d'une conversation
 * @param conversationId ID de la conversation
 * @param limit Nombre maximum de messages à récupérer (défaut: 50)
 * @param offset Nombre de messages à ignorer (défaut: 0)
 * @returns L'historique des messages
 * @throws Error si la requête échoue
 */
export async function getConversationHistory(
  conversationId: string,
  limit: number = 50,
  offset: number = 0,
): Promise<ConversationHistoryResponse> {
  try {
    // Backend returns { success: true, data: { messages: ChatMessage[] } }
    // apiClient unwraps to { messages: ChatMessage[] }
    const response = await apiClient.get<ConversationHistoryResponse>(
      `/conversations/${conversationId}/history`,
      {
        params: { limit, offset },
      },
    );
    return {
      messages: response.data.messages || [],
    };
  } catch (error) {
    handleApiServiceError(error, {
      context: 'conversation',
      customMessages: {
        401: "Vous devez être connecté pour voir l'historique de la conversation",
        403: "Vous n'avez pas les permissions nécessaires pour voir l'historique",
        404: 'La conversation est introuvable',
      },
    });
  }
}
