import { useEffect, useRef, useState } from 'react'; import { InvestmentContextAssessment } from './investment-context-assessment'; import { Link } from '@inertiajs/react'; import { contextApi, contextFieldNames, type ContextView, } from '@/lib/investor-context'; import { inheritCompatibleFields } from '@/lib/context-inheritance'; type Props = { contextId?: string | null; consumer: 'simulator' | 'land' | 'desk' | 'submission'; values: Record; enabled?: boolean; readOnly?: boolean; allowedFields?: string[]; persistInheritance?: boolean; boundRevision?: number; onApply: (patch: Record, replace: boolean) => void; onReview?: (revision: number, reviewed: boolean) => void; }; const geo = ['province_id', 'district_id', 'admin_post_id', 'locality_id']; const empty = (v: unknown) => v === null || v === undefined || v === '' || (Array.isArray(v) && v.length === 0); const text = (v: unknown) => typeof v === 'string' ? v : JSON.stringify(v ?? ''); export function DossierPrefill(props: Props) { const { contextId, consumer, enabled = true, readOnly = false, boundRevision = 0, } = props; const latest = useRef(props); latest.current = props; const [view, setView] = useState(null); const [error, setError] = useState(''); const [retry, setRetry] = useState(0); const [selected, setSelected] = useState([]); const [reviewed, setReviewed] = useState(false); const [message, setMessage] = useState(''); useEffect(() => { if (!contextId) return; let stopped = false; setView(null); setError(''); void contextApi(`/investimentos/${contextId}/contexto`) .then((v) => { if (!stopped) { setView(v); setReviewed(false); } }) .catch((e) => { if (!stopped) setError(e.message); }); return () => { stopped = true; }; }, [contextId, retry]); useEffect(() => { if (!view || view.case.id !== contextId || !enabled || readOnly || !view.can_write) return; const source = view.prefill[consumer] ?? {}; const now = latest.current; const inherited = inheritCompatibleFields(`dossier:${contextId}:${consumer}`, now.values, source, now.values.context_reuse, now.allowedFields); if (Object.keys(inherited.patch).length || (now.persistInheritance !== false && now.values.context_reuse !== inherited.metadata)) { // The shared reconciliation has already selected safe fields; metadata travels with the same saved form. now.onApply({...inherited.patch, ...(now.persistInheritance === false ? {} : {context_reuse:inherited.metadata})}, true); setMessage( 'Dados compatíveis reutilizados do mesmo dossier. Os valores herdados acompanham o contexto; as suas alterações locais foram preservadas.', ); } setReviewed(true); now.onReview?.(view.context.revision, true); }, [view, enabled, readOnly, contextId, consumer, props.values]); if (!contextId) return null; if (error) return (

{error} Os dados do formulário foram preservados.

); if (!view) return (

A recuperar os dados autorizados do dossier…

); const source = Object.fromEntries( Object.entries(view.prefill[consumer] ?? {}).filter( ([k]) => !props.allowedFields || props.allowedFields.includes(k), ), ); const differences = Object.keys(source).filter( (k) => k !== 'context_applicability_snapshot' && text(props.values[k]) !== text(source[k]), ); const linkedRevision = consumer === 'simulator' ? (view.simulator_context_revision ?? 0) : boundRevision; const stale = view.context.revision !== linkedRevision && !reviewed; return (

Mesmo investimento · contexto v{view.context.revision}

UUID {contextId} ·{' '} recuperar dossier . Mestres, declarações deste formulário e conteúdo já submetido mantêm-se separados.

{stale && (

{linkedRevision > 0 ? `O contexto do dossier difere da revisão vinculada a este registo (v${linkedRevision}).` : 'Confira os valores deste formulário para o contexto atual; não há uma revisão anterior vinculada a estas entradas.'}{' '} Os valores e resultados anteriores permanecem guardados; confira os pressupostos antes de os usar no cenário atual.

)} {message &&

{message}

} {Object.values(view.context.selection).map( (r) => r && (

Fonte disponível:{' '} {r.title} {' '} · {r.kind} · v{r.version ?? 'não exposta'}. {r.key}

), )} {!readOnly && view.can_write && differences.length > 0 && (
Comparar com os campos já preenchidos

Os seus valores conservam-se por defeito. Selecione apenas os campos que pretende substituir; o formulário continua a precisar de ser guardado/submetido pela ação existente.

{differences.map((k) => ( ))}
Substituir Valor atual Valor proposto pelo dossier
{text(props.values[k]) || 'não informado'} {text(source[k]) || 'não informado'}
)} {!readOnly && reviewed &&

Contexto v{view.context.revision} recuperado neste formulário, sem nova confirmação dos dados compatíveis. As edições locais conservam-se; as declarações e submissões formais mantêm os seus controlos próprios.

}

Associar uma referência não confirma incentivos, licenças, terra disponível, reserva ou autorização.

); }