import {
  BE_GESTIONMESSAGERIE_CONVERSATIONS_URL,
  BE_GESTIONMESSAGERIE_SEND_MESSAGE_URL,
  BE_GESTIONMESSAGERIE_CREATE_CONVERSATION_URL,
  BE_GESTIONMESSAGERIE_SEARCH_RECIPIENTS_URL,
  BE_GESTIONMESSAGERIE_MARK_AS_READ_URL,
  BE_GESTIONMESSAGERIE_UPLOAD_FILE_URL,
  BE_GESTIONMESSAGERIE_DELETE_CONVERSATION_URL,
} from '@/utils/Url';
import { fetchWithAuth, getAuthToken } from '@/utils/fetchWithAuth';
import logger from '@/utils/logger';

/**
 * Récupère les conversations d'un utilisateur
 */
export const fetchConversations = async (userId, csrfToken) => {
  try {
    // Utiliser la nouvelle route avec user_id en paramètre d'URL
    const url = `${BE_GESTIONMESSAGERIE_CONVERSATIONS_URL}/user/${userId}/`;
    return await fetchWithAuth(url, {
      headers: { 'X-CSRFToken': csrfToken },
    });
  } catch (error) {
    logger.error('Erreur lors de la récupération des conversations:', error);
    throw error;
  }
};

/**
 * Récupère les messages d'une conversation
 */
export const fetchMessages = async (
  conversationId,
  page = 1,
  limit = 50,
  csrfToken,
  userId = null
) => {
  try {
    // Utiliser la nouvelle URL avec conversation_id en paramètre d'URL
    let url = `${BE_GESTIONMESSAGERIE_CONVERSATIONS_URL}/${conversationId}/messages/?page=${page}&limit=${limit}`;

    // Ajouter user_id si fourni pour calculer correctement is_read
    if (userId) {
      url += `&user_id=${userId}`;
    }

    return await fetchWithAuth(url, {
      headers: { 'X-CSRFToken': csrfToken },
    });
  } catch (error) {
    logger.error('Erreur lors de la récupération des messages:', error);
    throw error;
  }
};

/**
 * Envoie un message dans une conversation
 */
export const sendMessage = async (messageData, csrfToken) => {
  try {
    return await fetchWithAuth(BE_GESTIONMESSAGERIE_SEND_MESSAGE_URL, {
      method: 'POST',
      headers: { 'X-CSRFToken': csrfToken },
      body: JSON.stringify(messageData),
    });
  } catch (error) {
    logger.error("Erreur lors de l'envoi du message:", error);
    throw error;
  }
};

/**
 * Crée une nouvelle conversation
 */
export const createConversation = async (participantIds, csrfToken) => {
  try {
    const requestBody = {
      participant_ids: participantIds, // Le backend attend "participant_ids"
      conversation_type: 'private', // Spécifier le type de conversation
      name: '', // Le nom sera généré côté backend
    };

    return await fetchWithAuth(BE_GESTIONMESSAGERIE_CREATE_CONVERSATION_URL, {
      method: 'POST',
      headers: { 'X-CSRFToken': csrfToken },
      body: JSON.stringify(requestBody),
    });
  } catch (error) {
    logger.error('Erreur lors de la création de la conversation:', error);
    throw error;
  }
};

/**
 * Recherche des destinataires pour la messagerie
 */
export const searchMessagerieRecipients = async (
  establishmentId,
  query,
  csrfToken
) => {
  try {
    const baseUrl = BE_GESTIONMESSAGERIE_SEARCH_RECIPIENTS_URL.endsWith('/')
      ? BE_GESTIONMESSAGERIE_SEARCH_RECIPIENTS_URL
      : BE_GESTIONMESSAGERIE_SEARCH_RECIPIENTS_URL + '/';

    const url = `${baseUrl}?establishment_id=${establishmentId}&q=${encodeURIComponent(query)}`;

    return await fetchWithAuth(url, {
      headers: { 'X-CSRFToken': csrfToken },
    });
  } catch (error) {
    logger.error('Erreur lors de la recherche des destinataires:', error);
    throw error;
  }
};

/**
 * Marque des messages comme lus
 */
export const markAsRead = async (conversationId, userId, csrfToken) => {
  try {
    return await fetchWithAuth(BE_GESTIONMESSAGERIE_MARK_AS_READ_URL, {
      method: 'POST',
      headers: { 'X-CSRFToken': csrfToken },
      body: JSON.stringify({
        conversation_id: conversationId,
        user_id: userId,
      }),
    });
  } catch (error) {
    logger.error('Erreur lors du marquage des messages comme lus:', error);
    throw error;
  }
};

/**
 * Upload un fichier pour la messagerie
 */
export const uploadFile = async (
  file,
  conversationId,
  senderId,
  csrfToken,
  onProgress = null
) => {
  const formData = new FormData();
  formData.append('file', file);
  formData.append('conversation_id', conversationId);
  formData.append('sender_id', senderId);

  const token = await getAuthToken();
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();

    if (onProgress) {
      xhr.upload.addEventListener('progress', (event) => {
        if (event.lengthComputable) {
          const percentComplete = (event.loaded / event.total) * 100;
          onProgress(percentComplete);
        }
      });
    }

    xhr.addEventListener('load', () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        try {
          const response = JSON.parse(xhr.responseText);
          resolve(response);
        } catch (error) {
          reject(new Error('Réponse invalide du serveur'));
        }
      } else {
        try {
          const errorResponse = JSON.parse(xhr.responseText);
          reject(new Error(errorResponse.message || "Erreur lors de l'upload"));
        } catch {
          reject(new Error(`Erreur HTTP: ${xhr.status}`));
        }
      }
    });

    xhr.addEventListener('error', () => {
      reject(new Error("Erreur réseau lors de l'upload"));
    });

    xhr.addEventListener('timeout', () => {
      reject(new Error("Timeout lors de l'upload"));
    });

    xhr.open('POST', BE_GESTIONMESSAGERIE_UPLOAD_FILE_URL);
    xhr.withCredentials = true;
    xhr.timeout = 30000;

    // Ajouter les headers d'authentification pour XMLHttpRequest
    if (token) {
      xhr.setRequestHeader('Authorization', `Bearer ${token}`);
    }
    if (csrfToken) {
      xhr.setRequestHeader('X-CSRFToken', csrfToken);
    }

    xhr.send(formData);
  });
};

/**
 * Supprime une conversation
 */
export const deleteConversation = async (conversationId, csrfToken) => {
  try {
    const url = `${BE_GESTIONMESSAGERIE_DELETE_CONVERSATION_URL}/${conversationId}/`;
    return await fetchWithAuth(url, {
      method: 'DELETE',
      headers: { 'X-CSRFToken': csrfToken },
    });
  } catch (error) {
    logger.error('Erreur lors de la suppression de la conversation:', error);
    throw error;
  }
};
