import { useCallback, useMemo } from 'react'; const useDocumentCorrespondentActions = ({ apiClient, correspondents, handleCorrespondentCreate, refreshCurrentFolder, notifyApiError, setStatusMessage, }) => { const correspondentLookupByName = useMemo(() => { const map = new Map(); correspondents.forEach((correspondent) => { if (correspondent?.name) { map.set(correspondent.name.toLowerCase(), correspondent); } }); return map; }, [correspondents]); const handleDocumentCorrespondentAttach = useCallback( async ({ documentId, correspondentId }, { notify = true, refresh = true } = {}) => { if (!documentId || !correspondentId) { throw new Error('Missing document or correspondent.'); } try { await apiClient.post(`/documents/${documentId}/correspondents`, { assignments: [{ correspondent_id: correspondentId }], replace: false, }); if (refresh) { await refreshCurrentFolder(); } if (notify) { setStatusMessage('Correspondent assigned.', 'success'); } return true; } catch (error) { const message = error.response?.data?.error || 'Failed to assign correspondent.'; notifyApiError(error, message); throw new Error(message); } }, [apiClient, refreshCurrentFolder, notifyApiError, setStatusMessage], ); const handleCorrespondentRemove = useCallback( async ({ documentId, correspondentId }, { notify = true, refresh = true } = {}) => { if (!documentId || !correspondentId) { throw new Error('Missing document or correspondent.'); } try { await apiClient.delete(`/documents/${documentId}/correspondents/${correspondentId}`); if (refresh) { await refreshCurrentFolder(); } if (notify) { setStatusMessage('Correspondent removed.', 'success'); } return true; } catch (error) { const message = error.response?.data?.error || 'Failed to remove correspondent.'; notifyApiError(error, message); throw new Error(message); } }, [apiClient, refreshCurrentFolder, notifyApiError, setStatusMessage], ); const handleCorrespondentAdd = useCallback( async ({ document, name, input = null, option = null }) => { if (!document?.id) { throw new Error('Missing document for correspondent assignment.'); } const trimmed = typeof name === 'string' ? name.trim() : ''; if (!trimmed) { setStatusMessage('Correspondent name is required.', 'error'); return; } let target = null; if (option && option.id) { target = correspondentLookupByName.get(trimmed.toLowerCase()) || option; } else { target = correspondentLookupByName.get(trimmed.toLowerCase()) || null; } if (!target) { try { target = await handleCorrespondentCreate({ name: trimmed }); } catch { return; } } if (!target?.id) { setStatusMessage('Unable to resolve correspondent.', 'error'); return; } try { await handleDocumentCorrespondentAttach({ documentId: document.id, correspondentId: target.id, }); if (input) { input.value = ''; } } catch (error) { setStatusMessage('Failed to assign correspondent.', 'error'); console.error('[documents] assign correspondent failed', error); } }, [ correspondentLookupByName, handleCorrespondentCreate, handleDocumentCorrespondentAttach, setStatusMessage, ], ); return { correspondentLookupByName, handleDocumentCorrespondentAttach, handleCorrespondentRemove, handleCorrespondentAdd, }; }; export default useDocumentCorrespondentActions;