import { useCallback } from 'react'; import { environment } from '../environments/environment.ts'; import { useHttpService } from './HttpService.tsx'; import type { SaveTransport } from '../utils/saveOperation'; import { decodeAutopayPage, decodeAutopayResult, type AutopaySetupResult } from '../utils/autopaySetup'; export type { AgencyAutopayArrangement, AutopayMarkup, AutopayPage, AutopaySetupResult } from '../utils/autopaySetup'; export type AutopayTransport = SaveTransport & { organizationId: string }; export interface AutopayAcceptance { operationId: string; offerIdentity: string; packageVersion: number } const API_URL = `${environment.orgAuthorizationApi}/contractor-autopay`; export const useContractorAutopayService = () => { const { get, post } = useHttpService(); const listArrangements = useCallback(async (transport?: AutopayTransport, cursor?: string) => { const body = await get(`${API_URL}${cursor ? `?cursor=${encodeURIComponent(cursor)}` : ''}`, { ...transport }); transport?.admit(); return decodeAutopayPage(body, transport?.organizationId); }, [get]); const operationRequest = useCallback(async ( contractorId: string, operationId: string, transport: AutopayTransport, action: 'accept' | 'check' | 'continue', input?: AutopayAcceptance, ): Promise => { const base = `${API_URL}/${encodeURIComponent(contractorId)}`; const url = action === 'accept' ? `${base}/accept` : `${base}/operations/${encodeURIComponent(operationId)}${action === 'continue' ? '/continue' : ''}`; let body: unknown; try { body = action === 'check' ? await get(url, { ...transport }) : await post(url, input ?? {}, { ...transport }); } catch (failure) { transport.admit(); const errorBody = (failure as { body?: unknown } | null)?.body; if (errorBody && typeof errorBody === 'object' && (errorBody as { operationId?: unknown }).operationId) { const originalPending = action === 'accept' && (errorBody as { code?: unknown }).code === 'SETUP_PENDING'; return decodeAutopayResult(errorBody, { organizationId: transport.organizationId, contractorId, ...(originalPending ? {} : { operationId }), ...(input && !originalPending ? { offerIdentity: input.offerIdentity, packageVersion: input.packageVersion } : {}), }); } throw failure; } transport.admit(); return decodeAutopayResult(body, { organizationId: transport.organizationId, contractorId, operationId, ...(input ? { offerIdentity: input.offerIdentity, packageVersion: input.packageVersion } : {}), }, action !== 'check'); }, [get, post]); const acceptArrangement = useCallback((contractorId: string, input: AutopayAcceptance, transport: AutopayTransport) => operationRequest(contractorId, input.operationId, transport, 'accept', input), [operationRequest]); const checkSetup = useCallback((contractorId: string, operationId: string, transport: AutopayTransport) => operationRequest(contractorId, operationId, transport, 'check'), [operationRequest]); const continueSetup = useCallback((contractorId: string, operationId: string, transport: AutopayTransport) => operationRequest(contractorId, operationId, transport, 'continue'), [operationRequest]); return { listArrangements, acceptArrangement, checkSetup, continueSetup }; };