import { useMemo, useState, useEffect } from 'react'; import { IoIosLink, IoIosCloudDownload } from 'react-icons/io'; import { ColumnConfig } from '../FormGenerator'; import { useSharePointTest } from '../../hooks/useSharePointTest'; import { useLanguage } from '../../contexts/LanguageContext'; import type { TableAction, SharePointConnection, SharePointDocument, TestSharepointLogicReturn } from './testSharepointInterfaces'; export function useTestSharepointLogic(): TestSharepointLogicReturn { const { getConnections, testConnection, listDocuments, discoverSites, debugTokenDetails, cleanupTokens, isLoading } = useSharePointTest(); const { t } = useLanguage(); // State management const [connections, setConnections] = useState([]); const [selectedConnection, setSelectedConnection] = useState(null); const [connectionLoading, setConnectionLoading] = useState(false); const [connectionError, setConnectionError] = useState(null); const [documents, setDocuments] = useState([]); const [documentsLoading, setDocumentsLoading] = useState(false); const [documentsError, setDocumentsError] = useState(null); const [testingConnections, setTestingConnections] = useState>(new Set()); const [connectionTestResults, setConnectionTestResults] = useState>({}); const [discoveredSites, setDiscoveredSites] = useState([]); const [sitesDiscovered, setSitesDiscovered] = useState(false); const [tokenDebugInfo, setTokenDebugInfo] = useState(null); // Load connections on mount useEffect(() => { loadConnections(); }, []); const loadConnections = async () => { setConnectionLoading(true); setConnectionError(null); try { const conns = await getConnections(); setConnections(conns); if (conns.length > 0 && !selectedConnection) { setSelectedConnection(conns[0]); } } catch (error) { console.error('Failed to load connections:', error); setConnectionError(error instanceof Error ? error.message : 'Failed to load connections'); } finally { setConnectionLoading(false); } }; // Configure columns for the SharePoint documents table const columns: ColumnConfig[] = useMemo(() => [ { key: 'documentName', label: t('sharepoint.column.documentName', 'Document Name'), type: 'string', width: 300, minWidth: 200, maxWidth: 400, sortable: true, filterable: true, searchable: true, formatter: (value: string, row: any) => ( {row?.type === 'folder' ? '📁' : '📄'} {value} ) }, { key: 'mimeType', label: t('sharepoint.column.mimeType', 'MIME Type'), type: 'string', width: 200, minWidth: 150, maxWidth: 300, sortable: true, filterable: true, searchable: true, }, { key: 'size', label: t('sharepoint.column.size', 'Size'), type: 'number', width: 140, minWidth: 120, maxWidth: 180, sortable: true, filterable: false, formatter: (value: number | string | undefined) => { if (!value || value === 0) return '-'; const sizeInBytes = typeof value === 'string' ? parseInt(value, 10) : value; const units = ['Bytes', 'KB', 'MB', 'GB']; let size = sizeInBytes; let unitIndex = 0; while (size >= 1024 && unitIndex < units.length - 1) { size /= 1024; unitIndex++; } return ( {`${size.toFixed(1)} ${units[unitIndex]}`} ); } }, { key: 'path', label: t('sharepoint.column.path', 'Path'), type: 'string', width: 250, minWidth: 200, maxWidth: 400, sortable: true, filterable: true, searchable: true, }, ], [t]); // Handle connection selection const handleSelectConnection = (connectionId: string) => { const connection = connections.find(conn => conn.id === connectionId); if (connection) { setSelectedConnection(connection); // Clear documents when changing connection setDocuments([]); setDocumentsError(null); } }; // Handle connection testing const handleTestConnection = async (connectionId: string) => { setTestingConnections(prev => new Set(prev).add(connectionId)); try { const result = await testConnection(connectionId); setConnectionTestResults(prev => ({ ...prev, [connectionId]: result })); } catch (error) { console.error('Connection test failed:', error); setConnectionTestResults(prev => ({ ...prev, [connectionId]: { success: false, error: error instanceof Error ? error.message : 'Connection test failed' } })); } finally { setTestingConnections(prev => { const newSet = new Set(prev); newSet.delete(connectionId); return newSet; }); } }; // Handle listing documents const handleListDocuments = async (siteUrl?: string, folderPaths?: string[]) => { if (!selectedConnection) { setDocumentsError('No connection selected'); return; } setDocumentsLoading(true); setDocumentsError(null); try { const connectionReference = `connection:${selectedConnection.authority}:${selectedConnection.externalUsername}:${selectedConnection.id}`; const response = await listDocuments({ connectionReference, siteUrl: siteUrl || 'https://your-tenant.sharepoint.com/sites/your-site', folderPaths: folderPaths || ['/'], includeSubfolders: false, expectedDocumentFormats: [{ extension: '.json', mimeType: 'application/json' }] }); console.log('SharePoint response:', response); if (response.success && response.data?.documents) { // Extract the actual files from the nested structure const documents = response.data.documents; if (documents.length > 0 && documents[0].documentData?.listResults) { // Flatten all files from all folder results const allFiles: SharePointDocument[] = []; documents[0].documentData.listResults.forEach((folderResult: any) => { if (folderResult.items && Array.isArray(folderResult.items)) { folderResult.items.forEach((item: any) => { // Convert SharePoint item to our document format allFiles.push({ documentName: item.name || 'Unknown', mimeType: item.file?.mimeType || (item.type === 'folder' ? 'folder' : 'unknown'), size: item.size || 0, path: folderResult.folderPath || '/', type: item.type || (item.folder ? 'folder' : 'file'), id: item.id, documentData: item // Store the full item data }); }); } }); console.log('Extracted files:', allFiles); console.log('Sample file structure:', allFiles[0]); setDocuments(allFiles); } else { console.log('No listResults found in response'); setDocuments([]); } } else { console.log('Response error or no documents:', response); setDocumentsError(response.error || 'Failed to list documents'); setDocuments([]); } } catch (error) { console.error('Failed to list documents:', error); setDocumentsError(error instanceof Error ? error.message : 'Failed to list documents'); setDocuments([]); } finally { setDocumentsLoading(false); } }; // Handle site discovery const handleDiscoverSites = async () => { if (!selectedConnection) { return; } try { const result = await discoverSites(); if (result.success && result.data && result.data.sites) { setDiscoveredSites(result.data.sites); setSitesDiscovered(true); setDocumentsError(null); // Clear any previous errors } else { console.error('Site discovery failed:', result); setDiscoveredSites([]); setSitesDiscovered(true); // Set to true so we show the "no sites" message // Set error message to help user understand what went wrong const errorMsg = result.error || result.message || 'Unknown error occurred'; setDocumentsError(`Site discovery failed: ${errorMsg}`); } } catch (error) { console.error('Site discovery failed:', error); setDiscoveredSites([]); setSitesDiscovered(true); setDocumentsError(`Site discovery error: ${error instanceof Error ? error.message : 'Network or authentication error'}`); } }; // Handle site selection const handleSelectSite = (siteUrl: string) => { // This will be used by the parent component console.log('Site selected:', siteUrl); }; // Handle token debug const handleDebugTokens = async () => { try { const result = await debugTokenDetails(); setTokenDebugInfo(result); console.log('Token debug info:', result); } catch (error) { console.error('Token debug failed:', error); setTokenDebugInfo({ error: error instanceof Error ? error.message : 'Failed to get token info' }); } }; // Handle token cleanup const handleCleanupTokens = async () => { try { const result = await cleanupTokens(); console.log('Token cleanup result:', result); // Clear the debug info to force refresh setTokenDebugInfo(null); // Show success message setDocumentsError(null); alert(`Success! Deleted ${result.data?.tokensDeleted || 0} tokens. Please reconnect your Microsoft account now.`); } catch (error) { console.error('Token cleanup failed:', error); alert(`Token cleanup failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } }; // Handle folder navigation const handleFolderNavigation = (document: SharePointDocument, currentPath: string) => { if (document.type === 'folder') { // Build the new path by combining current path with folder name const newPath = currentPath === '/' ? `/${document.documentName}` : `${currentPath}/${document.documentName}`; console.log('Navigating to folder:', newPath); return newPath; } return currentPath; }; // Handle document actions const handleViewDocument = async (document: SharePointDocument) => { console.log('View document:', document); // TODO: Implement document viewing }; const handleDownloadDocument = async (document: SharePointDocument) => { console.log('Download document:', document); // TODO: Implement document download }; // Configure action buttons const actions: TableAction[] = useMemo(() => [ { label: t('sharepoint.action.view', 'View'), icon: , onClick: (document: SharePointDocument) => { handleViewDocument(document); } }, { label: t('sharepoint.action.download', 'Download'), icon: , onClick: (document: SharePointDocument) => { handleDownloadDocument(document); } } ], [t]); // Refetch connections const refetchConnections = async () => { await loadConnections(); }; return { // Connection data connections, selectedConnection, connectionLoading, connectionError, // Document data documents, documentsLoading: documentsLoading || isLoading, documentsError, // Table configuration columns, actions, // Connection testing testingConnections, connectionTestResults, // Site discovery discoveredSites, sitesDiscovered, // Token debug tokenDebugInfo, // Handlers handleSelectConnection, handleTestConnection, handleListDocuments, handleDiscoverSites, handleSelectSite, handleDebugTokens, handleCleanupTokens, handleFolderNavigation, refetchConnections }; }