
import { supabase } from "@/integrations/supabase/client";
import { Document } from "@/types";
import { isManagedDocumentStoragePath } from "@/services/documentGuards";
import { normalizeDocumentCategory } from "@/services/documentCategories";

const mapDocument = (document: {
  id: string; name: string; type: string; url: string; uploaded_at: string;
  step_id: string | null; mime_type: string | null; size_bytes: number | null;
  uploaded_by: string | null;
}): Document => ({
  id: document.id,
  name: document.name,
  type: normalizeDocumentCategory(document.type),
  url: document.url,
  uploadedAt: document.uploaded_at,
  stepId: document.step_id ?? undefined,
  mimeType: document.mime_type ?? undefined,
  sizeBytes: document.size_bytes ?? undefined,
  uploadedBy: document.uploaded_by ?? undefined,
});

export function useSupabaseDocuments() {
  const getDocumentsForTrip = async (tripId: string): Promise<Document[]> => {
    const { data, error } = await supabase
      .from('documents')
      .select('id, name, type, url, uploaded_at, step_id, mime_type, size_bytes, uploaded_by')
      .eq('trip_id', tripId)
      .order('uploaded_at', { ascending: false })
      .order('id', { ascending: true });

    if (error) throw error;

    return (data ?? []).map(mapDocument);
  };

  const getDocumentForDeletion = async (tripId: string, documentId: string) => {
    const { data, error } = await supabase
      .from('documents')
      .select('id, trip_id, url')
      .eq('id', documentId)
      .eq('trip_id', tripId)
      .maybeSingle();

    if (error) throw error;
    if (!data) throw new Error("Document introuvable ou non autorisé");
    return {
      id: data.id,
      tripId: data.trip_id,
      storagePath: isManagedDocumentStoragePath(tripId, data.url) ? data.url : null,
    };
  };

  const addDocument = async (tripId: string, document: Omit<Document, "uploadedAt">) => {
    try {
      // Préparer les données du document, en s'assurant que stepId n'est pas une chaîne vide
      const documentData = {
        id: document.id,
        trip_id: tripId,
        name: document.name,
        type: document.type,
        url: document.url,
        mime_type: document.mimeType,
        size_bytes: document.sizeBytes,
      };

      // Ajouter step_id uniquement s'il existe et n'est pas vide
      if (document.stepId && document.stepId.trim() !== '') {
        Object.assign(documentData, { step_id: document.stepId });
      }

      const { data: newDocument, error } = await supabase
        .from('documents')
        .insert(documentData)
        .select('id, name, type, url, uploaded_at, step_id, mime_type, size_bytes, uploaded_by')
        .single();

      if (error) throw error;
      const expectedStepId = document.stepId?.trim() || null;
      if (newDocument.step_id !== expectedStepId) {
        const { error: cleanupError } = await supabase.from("documents").delete()
          .eq("id", newDocument.id).eq("trip_id", tripId);
        if (cleanupError) throw new Error("Association d’étape incorrecte et nettoyage SQL impossible.");
        throw new Error("Le document n’a pas été associé à l’étape demandée.");
      }
      // Transformation pour le frontend
      return mapDocument(newDocument);
    } catch (error) {
      console.error("Erreur lors de l'ajout du document:", error);
      throw error;
    }
  };

  const deleteDocumentRow = async (tripId: string, documentId: string) => {
    try {
      const { data, error } = await supabase
        .from('documents')
        .delete()
        .eq('id', documentId)
        .eq('trip_id', tripId)
        .select('id')
        .maybeSingle();

      if (error) throw error;
      if (!data) throw new Error("Document introuvable ou non autorisé");
      return;
    } catch (error) {
      console.error("Erreur lors de la suppression du document:", error);
      throw error;
    }
  };

  return {
    addDocument,
    getDocumentsForTrip,
    getDocumentForDeletion,
    deleteDocumentRow,
  };
}
