import { useMemo } from 'react'; import type { Resource } from 'fhir/r4'; import { useSnapshotRowLabels } from './useSnapshotRowLabels'; import type { SnapshotItem, SnapshotTypeResult } from './usePatientSnapshot'; import { SNAPSHOT_TYPES } from '../components/PatientSnapshot/snapshotRegistry'; /** Parse a FHIR reference's resource type: the substring before the first `/`. */ function refType(ref: string): string { const slash = ref.indexOf('/'); return slash === -1 ? ref : ref.slice(0, slash); } /** * Map a resolved care-view anchor (`resolvedResources` + `unresolvedRefs` from * `resolveCareViewAnchor`) into the same `SnapshotTypeResult[]` shape the Cap A reconstruction * produces, so the shared read-only `SnapshotChart` can render it verbatim. * * Every emitted result is `status: 'ready'` (the anchor resolve already completed server-side). * A type appears only if it has at least one resolved resource OR at least one unresolved ref of * that type; `truncatedCount` carries the unresolved count so the chart shows the "couldn't be * retrieved" note per section. Section ordering is handled downstream by `SnapshotChart` via the * registry section order. */ export function useAnchorResults( resolvedResources: Resource[], unresolvedRefs: string[], ): SnapshotTypeResult[] { const rowLabels = useSnapshotRowLabels(); return useMemo(() => { // Group resolved resources by resourceType. const byType = new Map(); for (const resource of resolvedResources) { const bucket = byType.get(resource.resourceType); if (bucket) { bucket.push(resource); } else { byType.set(resource.resourceType, [resource]); } } // Count unresolved refs by their parsed resource type. const unresolvedByType = new Map(); for (const ref of unresolvedRefs) { const type = refType(ref); unresolvedByType.set(type, (unresolvedByType.get(type) ?? 0) + 1); } const results: SnapshotTypeResult[] = []; for (const meta of SNAPSHOT_TYPES) { const resources = byType.get(meta.resourceType) ?? []; const truncatedCount = unresolvedByType.get(meta.resourceType) ?? 0; // Skip a type with neither a resolved resource nor an unresolved ref. if (resources.length === 0 && truncatedCount === 0) continue; const labelFor = rowLabels[meta.resourceType]; const items: SnapshotItem[] = resources.map((resource) => ({ resourceType: meta.resourceType, id: resource.id ?? '', resource, label: labelFor?.(resource) ?? meta.resourceType, lastUpdated: resource.meta?.lastUpdated, })); results.push({ resourceType: meta.resourceType, label: meta.label, section: meta.section, status: 'ready', items, truncatedCount, }); } return results; }, [resolvedResources, unresolvedRefs, rowLabels]); }