import React,{useEffect,useMemo,useState,useRef} from 'react';
import {fiscalMapDownload} from './statement-download.js';
import {WorkshopStockOperation} from './workshop-stock-operation.js';
import {checkedObligations,obligationsPageCsv,obligationLabels,decisionLabels} from './fiscal-obligations-view.js';
const qs=q=>new URLSearchParams(Object.entries(q).filter(([,v])=>v!==''&&v!==null)).toString();
export function FiscalObligationRows({data,onSelect,disabled}){return
{r.effective?.due_on??'Prazo desconhecido'}{r.days_overdue===null?'Atraso indeterminado':r.days_overdue+' dia(s) à referência '+data.reference_on}
{r.effective?'QA'+r.effective.responsible_id:'Por aprovar'}{r.effective?.evidence??'Preparação não equivale a aprovação.'}{r.effective?.delivery_evidence&&SHA da evidência interna: {r.effective.delivery_evidence.export_sha256}. Entrega apenas simulada.}
QA{r.actor_id} · {r.created_at}{r.reason}
)}
{!data.records.data.length&&
Nenhum registo corresponde ao âmbito/filtros.
}
;}
export default function FiscalObligationsWorkspace({context,api}){
const initial={reference_on:'',period:'',status:'',due_state:'',due_from:'',due_to:'',per_page:'25'},[filters,setFilters]=useState(initial),[query,setQuery]=useState(null),[data,setData]=useState(null),[selected,setSelected]=useState(null),[form,setForm]=useState(null),[preview,setPreview]=useState(null),[busy,setBusy]=useState(false),[error,setError]=useState(''),[notice,setNotice]=useState(''),[receiptKey,setReceiptKey]=useState(''),[receipt,setReceipt]=useState(null);
const mounted=useRef(true),generation=useRef(context.token);generation.current=context.token;useEffect(()=>{mounted.current=true;return()=>{mounted.current=false;};},[context.token]);
const operation=useMemo(()=>new WorkshopStockOperation(api),[context.token]),locked=busy||operation.uncertain;
useEffect(()=>{if(!query)return;let active=true;setData(null);setBusy(true);setError('');api('/api/fiscal-obligations?'+qs(query)).then(r=>{if(active)setData(checkedObligations(r,query));}).catch(e=>{if(active)setError(e.message);}).finally(()=>{if(active)setBusy(false);});return()=>{active=false;};},[context.token,query]);
const choose=r=>{setSelected(r);setReceipt(null);setNotice('');};
function start(op,review=false,newRecord=false){const target=newRecord?null:selected;if(newRecord)setSelected(null);const source=data.source,e=target?.effective;setPreview(null);setError('');setForm({action:review?'review':'prepare',record_key:target?.record_key??crypto.randomUUID(),version:target?.version??0,reason:'',data:review?{decision:''}:{operation:op,form_id:source.form_id,period:source.period,responsible_id:e?.responsible_id??'',due_on:e?.due_on??'',evidence:'',export_sha256:''},unknown:review?false:Boolean(e&&e.due_on===null)});}
async function prepare(e){e.preventDefault();setBusy(true);setError('');try{const{unknown,...input}=form;if(input.action==='prepare')input.data={...input.data,responsible_id:Number(input.data.responsible_id),due_on:unknown?null:input.data.due_on,export_sha256:input.data.operation==='delivery'?input.data.export_sha256:null};const key=crypto.randomUUID(),p=await api('/api/fiscal-obligations/preview','POST',input,undefined,key);setPreview({...p,key});}catch(e){setError(e.message);}finally{setBusy(false);}}
async function confirm(retry=false){setBusy(true);setError('');try{const out=retry?await operation.retry():await operation.send('/api/fiscal-obligations/confirm',{preview:preview.preview},preview.key);setReceiptKey(preview.key);setNotice('v'+out.version+' · '+decisionLabels[out.state]+(out.replayed?' · recibo recuperado':''));setSelected(null);setForm(null);setPreview(null);setQuery(q=>({...q,page:1}));}catch(e){setError(e.message);if(!operation.uncertain)setPreview(null);}finally{setBusy(false);}}
async function downloadMap(){const token=context.token;setBusy(true);setError('');try{const result=await fiscalMapDownload({id:data.source.form_id,token,sha256:data.source.export_sha256,isCurrent:()=>mounted.current&&generation.current===token});const url=URL.createObjectURL(new Blob([result.bytes],{type:'text/csv;charset=utf-8'}));const a=document.createElement('a');a.href=url;a.download='sgf-mapa-interno-IVA-QA.csv';a.click();setTimeout(()=>URL.revokeObjectURL(url),1000);setNotice('Mapa interno descarregado e SHA verificado; sem submissão.');}catch(e){if(mounted.current&&generation.current===token)setError(e.message);}finally{if(mounted.current&&generation.current===token)setBusy(false);}}
const exportPage=()=>{const url=URL.createObjectURL(new Blob(['\uFEFF'+obligationsPageCsv(data,query)],{type:'text/csv;charset=utf-8'}));const a=document.createElement('a');a.href=url;a.download='sgf-obrigacoes-QA-pagina-'+data.records.current_page+'.csv';a.click();setTimeout(()=>URL.revokeObjectURL(url),1000);};
async function recover(){setBusy(true);setError('');try{setReceipt(await api('/api/fiscal-obligations/receipts/'+encodeURIComponent(receiptKey)));}catch(e){setError(e.message);}finally{setBusy(false);}}
return
CONTABILIDADE
Obrigações e prazos administrativos QA
Prazo artificial e entrega apenas simulada ligados ao mapa interno revisto. Sem prazo legal, submissão à AT, apuramento ou pagamento. A referência classifica o prazo; não reconstrói um estado histórico.
{error&&
{error}
}{notice&&
{notice}
}
{data&&<>{data.blocked&&
{data.blocked} Pode consultar o histórico; não há origem válida para novas decisões.
}{data.source&&
Origem disponível para escolha: mapa interno #{data.source.form_id} v{data.source.form_version}, período{data.source.period}, {data.source.document_reference}. SHA da exportação: {data.source.export_sha256}.
Página{data.records.current_page} de{data.records.last_page} · {data.records.total} registo(s). O estado temporal do prazo é independente da entrega/cancelamento.
Impacto registado nesta versão: antes v{selected.impact.before.version}, {obligationLabels[selected.impact.before.effective?.administrative_status??'unapproved']}, prazo{selected.impact.before.effective?.due_on??'desconhecido'}; depois v{selected.impact.after.version}, {obligationLabels[selected.impact.after.effective?.administrative_status??'unapproved']}, prazo{selected.impact.after.effective?.due_on??'desconhecido'}.