import { useState, useEffect, useCallback, useMemo } from 'react';
import axiosInstance from '@/utils/axios';
import { fleetDocumentEndpoints, fleetFolderEndpoints } from '@/shared/api/endpoints/fleet/fleet-documents';
import { useStorageStore } from '@/shared/api/stores/document-service/storageStore';
import type { DocumentDTO, FolderDTO, AddDocumentRequest, NewFolderRequest } from '@/shared/types/document';
import { FleetFileNode, ViewMode, SortBy } from './use-fleet-file-manager';


export function useFleetDocuments(ownerUuid: string) {
  
  const storageStore = useStorageStore();

  // ✅ Récupérer le nom d'utilisateur depuis localStorage
  const getUserDisplayName = useCallback(() => {
    const userName = localStorage.getItem('userName');
    const userEmail = localStorage.getItem('userEmail');
    return userName || userEmail || ownerUuid;
  }, [ownerUuid]);

  
  const [currentFolderId, setCurrentFolderId] = useState<number | null>(null);
  const [currentPath, setCurrentPath] = useState<{ id: number | null; name: string }[]>([
    { id: null, name: 'Accueil' }
  ]);
  const [currentDocuments, setCurrentDocuments] = useState<DocumentDTO[]>([]);
  const [currentFolders, setCurrentFolders] = useState<FolderDTO[]>([]);
  const [viewMode, setViewMode] = useState<ViewMode>('grid');
  const [searchQuery, setSearchQuery] = useState('');
  const [filterType, setFilterType] = useState('Tous les types');
  const [sortBy, setSortBy] = useState<SortBy>('name');
  const [selectedItems, setSelectedItems] = useState<string[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const loadData = useCallback(async () => {
    if (!ownerUuid) return;
    
    setLoading(true);
    setError(null);
    try {
      if (currentFolderId === null) {
        const [docsResponse, foldersResponse] = await Promise.all([
          axiosInstance.get(fleetDocumentEndpoints.root, { params: { ownerUuid } }),
          axiosInstance.get(fleetFolderEndpoints.root, { params: { ownerUuid } })
        ]);
        
        // Fetch storage quota separately to avoid dependency issues
        storageStore.fetchStorageQuota(ownerUuid);
        
        setCurrentDocuments(docsResponse.data || []);
        setCurrentFolders(foldersResponse.data || []);
      } else {
        const [docsResponse, subfoldersResponse] = await Promise.all([
          axiosInstance.get(fleetDocumentEndpoints.folder(currentFolderId), { 
            params: { ownerUuid } 
          }),
          axiosInstance.get(fleetFolderEndpoints.subfolders(currentFolderId), { 
            params: { ownerUuid } 
          })
        ]);
        
        setCurrentDocuments(docsResponse.data || []);
        setCurrentFolders(subfoldersResponse.data || []);
      }
    } catch (err: any) {
      console.error('Erreur lors du chargement des données:', err);
      setError(err.response?.data?.message || err.message || 'Erreur lors du chargement des données');
    } finally {
      setLoading(false);
    }
  }, [ownerUuid, currentFolderId]);

  useEffect(() => {
    loadData();
  }, [loadData]);

  const mapDocumentToNode = useCallback((doc: DocumentDTO): FleetFileNode => {
    let fileType: 'pdf' | 'image' | 'word' | 'excel' | 'other' = 'other';
    switch (doc.contentType) {
      case 'PDF':
        fileType = 'pdf';
        break;
      case 'IMAGE':
        fileType = 'image';
        break;
      case 'WORD':
        fileType = 'word';
        break;
      case 'EXCEL':
        fileType = 'excel';
        break;
    }

    return {
      id: `doc-${doc.id}`,
      name: doc.name,
      type: 'file',
      fileType,
      documentType: doc.customDocumentType || doc.documentType, // ✅ FIX: Utiliser customDocumentType en priorité
      size: formatFileSize(doc.size),
      addedBy: getUserDisplayName(), // ✅ FIX: Utiliser le vrai nom d'utilisateur
      addedDate: doc.createdAt ? new Date(doc.createdAt) : new Date(),
      lastModified: doc.updatedAt ? new Date(doc.updatedAt) : new Date(),
      isFavorite: doc.favorite,
      path: doc.path,
    };
  }, [getUserDisplayName]);

  const mapFolderToNode = useCallback((folder: FolderDTO): FleetFileNode => {
    return {
      id: `folder-${folder.id}`,
      name: folder.name,
      type: 'folder',
      addedBy: getUserDisplayName(), // ✅ FIX: Utiliser le vrai nom d'utilisateur
      addedDate: new Date(), // Les dossiers n'ont pas de date de création dans le DTO
      lastModified: new Date(),
      isFavorite: folder.favorite,
      children: [],
    };
  }, [getUserDisplayName]);

  const currentFolderItems = useMemo((): FleetFileNode[] => {
    const items: FleetFileNode[] = [];

    currentFolders.forEach(folder => {
      items.push(mapFolderToNode(folder));
    });

    currentDocuments.forEach(doc => {
      items.push(mapDocumentToNode(doc));
    });

    return items;
  }, [currentDocuments, currentFolders, mapDocumentToNode, mapFolderToNode]);

  const filteredAndSortedItems = useMemo(() => {
    let items = [...currentFolderItems];

    if (searchQuery) {
      items = items.filter(item =>
        item.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
        item.vehicleId?.toLowerCase().includes(searchQuery.toLowerCase()) ||
        item.addedBy?.toLowerCase().includes(searchQuery.toLowerCase())
      );
    }

    if (filterType !== 'Tous les types') {
      items = items.filter(item =>
        item.type === 'folder' || item.documentType === filterType
      );
    }

    
    items.sort((a, b) => {
      switch (sortBy) {
        case 'name':
          return a.name.localeCompare(b.name);
        case 'date':
          return (b.addedDate?.getTime() || 0) - (a.addedDate?.getTime() || 0);
        case 'type':
          if (a.type !== b.type) return a.type === 'folder' ? -1 : 1;
          return (a.documentType || '').localeCompare(b.documentType || '');
        case 'user':
          return (a.addedBy || '').localeCompare(b.addedBy || '');
        default:
          return 0;
      }
    });

    return items;
  }, [currentFolderItems, searchQuery, filterType, sortBy]);

  const navigateToFolder = useCallback(async (folder: FleetFileNode) => {
    if (folder.type !== 'folder') return;

    const folderId = parseInt(folder.id.replace('folder-', ''));
    setCurrentFolderId(folderId);
    setCurrentPath(prev => [...prev, { id: folderId, name: folder.name }]);
    setSelectedItems([]);
  }, []);

  const navigateToBreadcrumb = useCallback((index: number) => {
    const newPath = currentPath.slice(0, index + 1);
    const targetFolder = newPath[newPath.length - 1];
    
    setCurrentPath(newPath);
    setCurrentFolderId(targetFolder.id);
    setSelectedItems([]);
  }, [currentPath]);

  const addFolder = useCallback(async (folderName: string) => {
    if (!ownerUuid) return;

    try {
      const request: NewFolderRequest = {
        name: folderName,
        ownerUuid,
        ownerId: 1, 
        parentId: currentFolderId,
      };

      await axiosInstance.post(fleetFolderEndpoints.create, request);
      await loadData(); 
    } catch (err: any) {
      console.error('Erreur lors de la création du dossier:', err);
      setError(err.response?.data?.message || err.message || 'Erreur lors de la création du dossier');
      throw err;
    }
  }, [ownerUuid, currentFolderId, loadData]);

  
  const uploadFile = useCallback(async (file: File, metadata: Partial<FleetFileNode>) => {
    if (!ownerUuid) return;

    try {
      const formData = new FormData();
      formData.append('file', file);
      formData.append('name', file.name);
      
      let customType = 'document';
      const fileName = file.name.toLowerCase();
      
      if (fileName.includes('assurance') || fileName.includes('insurance')) {
        customType = 'assurance';
      } else if (fileName.includes('contrat') || fileName.includes('contract')) {
        customType = 'contrat';
      } else if (fileName.includes('facture') || fileName.includes('invoice')) {
        customType = 'facture';
      } else if (metadata.documentType) {
        customType = metadata.documentType;
      }
      
      formData.append('customDocumentType', customType);
      formData.append('ownerUuid', ownerUuid);
      formData.append('ownerId', '1'); // ✅ AJOUT: ownerId requis
      
      if (currentFolderId) {
        formData.append('folderId', currentFolderId.toString());
      }

      await axiosInstance.post(fleetDocumentEndpoints.upload, formData, {
        headers: { 'Content-Type': 'multipart/form-data' }
      });
      
      await loadData(); 
    } catch (err: any) {
      console.error('Erreur lors de l\'upload:', err);
      setError(err.response?.data?.message || err.message || 'Erreur lors de l\'upload');
      throw err;
    }
  }, [ownerUuid, currentFolderId, loadData]);

  
  const deleteItems = useCallback(async (itemIds: string[]) => {
    if (!ownerUuid) return;

    try {
      const documentIds: number[] = [];
      const folderIds: number[] = [];

      itemIds.forEach(id => {
        if (id.startsWith('doc-')) {
          documentIds.push(parseInt(id.replace('doc-', '')));
        } else if (id.startsWith('folder-')) {
          folderIds.push(parseInt(id.replace('folder-', '')));
        }
      });

      if (documentIds.length > 0) {
        await axiosInstance.post(
          fleetDocumentEndpoints.bulkDelete,
          documentIds,
          { params: { ownerUuid } }
        );
      }

      if (folderIds.length > 0) {
        await axiosInstance.post(
          fleetFolderEndpoints.bulkDelete,
          folderIds,
          { params: { ownerUuid } }
        );
      }

      setSelectedItems([]);
      await loadData(); 
    } catch (err: any) {
      console.error('Erreur lors de la suppression:', err);
      setError(err.response?.data?.message || err.message || 'Erreur lors de la suppression');
      throw err;
    }
  }, [ownerUuid, loadData]);

  
  const renameItem = useCallback(async (itemId: string, newName: string) => {
    if (!ownerUuid) return;

    try {
      if (itemId.startsWith('doc-')) {
        const docId = parseInt(itemId.replace('doc-', ''));
        await axiosInstance.post(fleetDocumentEndpoints.rename, null, {
          params: { documentId: docId, newName, ownerUuid }
        });
      } else if (itemId.startsWith('folder-')) {
        const folderId = parseInt(itemId.replace('folder-', ''));
        await axiosInstance.put(fleetFolderEndpoints.rename(folderId), null, {
          params: { newName, ownerUuid }
        });
      }

      await loadData(); 
    } catch (err: any) {
      console.error('Erreur lors du renommage:', err);
      setError(err.response?.data?.message || err.message || 'Erreur lors du renommage');
      throw err;
    }
  }, [ownerUuid, loadData]);

  
  const downloadDocument = useCallback(async (item: FleetFileNode) => {
    if (item.type !== 'file' || !ownerUuid) return;

    try {
      const docId = parseInt(item.id.replace('doc-', ''));
      const response = await axiosInstance.get(fleetDocumentEndpoints.download, {
        params: { documentId: docId, ownerUuid },
        responseType: 'blob'
      });

      const url = window.URL.createObjectURL(response.data);
      const link = document.createElement('a');
      link.href = url;
      link.download = item.name;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
    } catch (err: any) {
      console.error('Erreur lors du téléchargement:', err);
      setError(err.response?.data?.message || err.message || 'Erreur lors du téléchargement');
      throw err;
    }
  }, [ownerUuid]);

  const downloadFolder = useCallback(async (item: FleetFileNode) => {
    if (item.type !== 'folder' || !ownerUuid) return;

    try {
      const folderId = parseInt(item.id.replace('folder-', ''));
      const response = await axiosInstance.get(fleetFolderEndpoints.download(folderId), {
        params: { ownerUuid },
        responseType: 'blob'
      });

      const blob = new Blob([response.data], { type: 'application/zip' });
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = `${item.name}.zip`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
    } catch (err: any) {
      console.error('Erreur lors du téléchargement du dossier:', err);
      setError(err.response?.data?.message || err.message || 'Erreur lors du téléchargement du dossier');
      throw err;
    }
  }, [ownerUuid]);

  const selectItem = useCallback((itemId: string) => {
    setSelectedItems(prev =>
      prev.includes(itemId)
        ? prev.filter(id => id !== itemId)
        : [...prev, itemId]
    );
  }, []);

  const selectAll = useCallback(() => {
    const allIds = filteredAndSortedItems.map(item => item.id);
    if (selectedItems.length === allIds.length) {
      setSelectedItems([]);
    } else {
      setSelectedItems(allIds);
    }
  }, [filteredAndSortedItems, selectedItems]);

  const getExportData = useCallback(() => {
    return filteredAndSortedItems.map(item => ({
      Nom: item.name,
      Type: item.type === 'folder' ? 'Dossier' : 'Fichier',
      'Type de document': item.documentType || '-',
      Véhicule: item.vehicleId || '-',
      Catégorie: item.category || '-',
      Statut: item.status || '-',
      Taille: item.size || '-',
      'Ajouté par': item.addedBy || '-',
      "Date d'ajout": item.addedDate?.toLocaleDateString() || '-',
      'Dernière modification': item.lastModified?.toLocaleDateString() || '-',
    }));
  }, [filteredAndSortedItems]);

  return {
    // State
    currentPath: currentPath.map(p => p.name),
    viewMode,
    searchQuery,
    filterType,
    sortBy,
    selectedItems,
    filteredAndSortedItems,
    loading,
    error,
    storageQuota: storageStore.quota,

    // Actions
    setViewMode,
    setSearchQuery,
    setFilterType,
    setSortBy,
    navigateToFolder,
    navigateToBreadcrumb,
    addFolder,
    uploadFile,
    deleteItems,
    renameItem,
    downloadDocument,
    downloadFolder,
    selectItem,
    selectAll,
    getExportData,
    refreshData: loadData,
  };
}

// Helper function
function formatFileSize(bytes: number): string {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

