/* Console interne — revue : file des dossiers, revue d'un dossier (pièces déchiffrées, décision par pièce,
   décision finale), dépôts à rapprocher (design dev-admin.jsx, données réelles). */
function AdmQueue(){
  const [f, setF] = React.useState(0); const keys = ['', 'submitted', 'review', 'info', 'approved', 'refused'];
  const [d, recharger, etat] = useDonnees(() => api('GET', `dossiers${keys[f] ? `?stage=${keys[f]}` : ''}`), [f]);
  return <Page max={1240}><PageHead title="Dossiers de production" sub="File d'attente des partenaires qui demandent l'accès à la production. Les plus anciens envois d'abord."/>
    <Seg opts={['Tous','Soumis','En revue','Infos demandées','Approuvés','Refusés']} i={f} set={setF}/>
    {etat.erreur ? <Erreur e={etat.erreur} recharger={recharger}/> :
    <Tbl chargement={!d} cols={[{k:'n',l:'Partenaire',w:'2fr'},{k:'s',l:'Secteur',w:'.9fr',hideM:1},{k:'d',l:'Soumis le',w:'1fr'},{k:'o',l:'Déposé par',w:'1fr',hideM:1},{k:'st',l:'Statut',w:'1.3fr'},{k:'x',l:'',w:'24px'}]}
      rows={(d?.donnees||[]).map(q=>({n:<span style={{display:'flex', alignItems:'center', gap:10, minWidth:0}}><PLogo p={{nom:q.partenaire}} s={30}/><span style={{fontWeight:700, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>{q.partenaire}</span>{q.version > 1 && <Badge>v{q.version}</Badge>}</span>, s:<span style={{color:V.ink2}}>{SECTEUR_L[q.secteur]||'—'}</span>, d:<span style={{color:V.ink2}}>{q.soumis_le ? DC(q.soumis_le) : '—'}</span>, o:<span style={{color:V.ink2}}>{q.soumis_par||'—'}</span>, st:<StageB st={q.stage}/>, x:<I n="caret-right" s={16} c={V.ink3}/>}))}
      onRow={i=>aller('dossier', d.donnees[i].partenaire_id)} empty={<EmptyS icon="folder-open" title="File vide" sub="Aucun dossier dans ce statut."/>}/>}
  </Page>;
}

const LIB_ID = {cni_cedeao:'Carte d\'identité CEDEAO', passeport:'Passeport', carte_sejour:'Carte de séjour'};
function AdmDossier({param}){
  const pid = param; const toast = useToast(); const {peut, rechargerMoi} = useAdm(); const m = useMob();
  const [dos, recharger, etat] = useDonnees(() => api('GET', `dossiers/${pid}`), [pid]);
  const [sel, setSel] = React.useState(null), [cm, setCm] = React.useState({}), [dec, setDec] = React.useState(null), [grade, setGrade] = React.useState('silver'), [motif, setMotif] = React.useState(''), [occupe, setOccupe] = React.useState(false);
  const [fic, setFic] = React.useState({}), [pieceId, setPieceId] = React.useState('recto');
  React.useEffect(() => { if(dos && !sel) { setSel(dos.documents[0]?.type || 'identite'); setGrade(dos.partenaire.grade || 'silver'); } }, [dos]);
  const cleFichier = sel === 'identite' ? `identite_${pieceId}` : sel;
  React.useEffect(() => { if(!cleFichier || !dos || fic[cleFichier] !== undefined) return;
    const d = dos.documents.find(x=>x.type===sel); if(sel !== 'identite' && (!d || d.statut === 'a_fournir')) { setFic(f=>({...f, [cleFichier]:null})); return; }
    if(sel === 'identite' && dos.identite.statut === 'a_faire') { setFic(f=>({...f, [cleFichier]:null})); return; }
    setFic(f=>({...f, [cleFichier]:'chargement'}));
    api('GET', `dossiers/${pid}/documents/${cleFichier}/fichier`).then(r=>setFic(f=>({...f, [cleFichier]:r})), ()=>setFic(f=>({...f, [cleFichier]:null}))); }, [cleFichier, dos]);
  if(etat.erreur) return <Page max={1320}><PageHead back="Dossiers" onBack={()=>aller('queue')} title="Dossier"/><Erreur e={etat.erreur} recharger={recharger}/></Page>;
  if(!dos || !sel) return <Page max={1320}><Skel h={60}/><Skel h={420}/></Page>;
  const enRevue = dos.stage === 'review' && peut('dossiers');
  const pieces = [...dos.documents.filter(d=>d.requis || d.statut !== 'a_fournir'), {type:'identite', libelle:`Vérification d'identité${dos.identite.type_piece ? ` · ${LIB_ID[dos.identite.type_piece]||dos.identite.type_piece}` : ''}`, statut:{verifiee:'valide', a_refaire:'a_corriger', soumise:'depose'}[dos.identite.statut] || 'a_fournir', commentaire:dos.identite.commentaire, requis:true}];
  const d = pieces.find(x=>x.type===sel) || pieces[0];
  const requises = pieces.filter(x=>x.requis);
  const allOk = requises.every(x=>x.statut==='valide'), anyFix = pieces.some(x=>x.statut==='a_corriger');
  const decider = async (type, statut) => { setOccupe(true); try { await api('PATCH', `dossiers/${pid}/documents/${type}`, {statut, commentaire:cm[type]||''}); await recharger(); toast(statut==='valide'?'Pièce validée':'Pièce à corriger'); } catch(e){ toast(e.message, 'bad'); } setOccupe(false); };
  const final = async () => { setOccupe(true); try { await api('POST', `dossiers/${pid}/decision`, {decision:{ok:'approuver', info:'corrections', refuse:'refuser'}[dec], grade, motif}); toast({ok:'Dossier approuvé : production ouverte', info:'Corrections demandées', refuse:'Dossier refusé'}[dec]); setDec(null); rechargerMoi(); aller('queue'); } catch(e){ toast(e.message, 'bad'); } setOccupe(false); };
  const f = fic[cleFichier]; const e = dos.entreprise || {}, r = dos.representant || {};
  const apercu = f === 'chargement' ? <span className="kspin" style={{width:30, height:30, borderRadius:99, border:`3px solid ${V.line}`, borderTopColor:V.acc}}></span>
    : !f ? <EmptyS icon="file-dashed" title="Aucune pièce" sub="Le partenaire n'a pas encore déposé ce document."/>
    : /^image\//.test(f.mime) ? <img src={urlFichier(f)} alt={f.nom} style={{maxWidth:'100%', maxHeight:'100%', borderRadius:8, boxShadow:'0 4px 20px rgba(0,0,0,.08)', background:'#fff'}}/>
    : f.mime === 'application/pdf' ? <iframe title={f.nom} src={urlFichier(f)} style={{width:'100%', height:'100%', border:0, borderRadius:8, background:'#fff'}}></iframe>
    : <EmptyS icon="file" title={f.nom} sub="Aperçu indisponible : téléchargez le fichier."/>;
  return <Page max={1320}>
    <PageHead back="Dossiers" onBack={()=>aller('queue')} title={<span style={{display:'flex', alignItems:'center', gap:12, flexWrap:'wrap'}}>{dos.partenaire.nom}<StageB st={dos.stage}/></span>} sub={[e.forme_juridique, e.ninea && `NINEA ${e.ninea}`, e.rccm && `RCCM ${e.rccm}`, dos.soumis_le && `soumis le ${D(dos.soumis_le)}${dos.soumis_par ? ` par ${dos.soumis_par}` : ''}`].filter(Boolean).join(' · ')}
      actions={enRevue && <><Btn kind="danger" icon="x-circle" onClick={()=>{setMotif(''); setDec('refuse');}}>Refuser</Btn><Btn kind="secondary" icon="chat-circle-text" disabled={!anyFix} onClick={()=>{setMotif(''); setDec('info');}}>Demander des corrections</Btn><Btn icon="seal-check" disabled={!allOk} onClick={()=>setDec('ok')}>Approuver</Btn></>}/>
    {!enRevue && dos.stage !== 'review' && <Notice tone="info">{dos.stage === 'approved' ? 'Dossier approuvé : la production est ouverte.' : dos.stage === 'info' ? 'Corrections demandées : en attente du renvoi par le partenaire.' : dos.stage === 'refused' ? `Dossier refusé${dos.motif_refus ? ` : ${dos.motif_refus}` : ''}.` : 'Dossier en lecture seule.'}</Notice>}
    <div style={{display:'grid', gridTemplateColumns:m?'1fr':'300px minmax(0,1fr) 300px', gap:16, alignItems:'start'}}>
      <div style={{display:'flex', flexDirection:'column', gap:16}}>
        <Card pad={8}>{pieces.map(x=>{ const s = x.statut; return <button key={x.type} className="lb lr" onClick={()=>setSel(x.type)} style={{display:'flex', alignItems:'center', gap:10, width:'100%', padding:'10px 12px', border:0, borderRadius:14, cursor:'pointer', textAlign:'left', background:sel===x.type?V.mint:'transparent', fontFamily:V.body}}>
          <I n={s==='valide'?'check-circle':s==='a_corriger'?'warning-circle':s==='a_fournir'?'circle-dashed':x.type==='identite'?'identification-card':'file-text'} s={19} c={s==='valide'?V.acc:s==='a_corriger'?V.bad:V.ink3} fill={s==='valide'||s==='a_corriger'}/><span style={{flex:1, fontWeight:700, fontSize:13, color:V.ink, lineHeight:1.3}}>{x.libelle}</span></button>; })}</Card>
        <Card><Lbl style={{marginBottom:8}}>Entreprise</Lbl><KV rows={[['Raison sociale', e.raison_sociale||'—'], ['Forme', e.forme_juridique||'—'], ['Siège', e.adresse_siege||'—'], ['Site', e.site_web||'—']]}/>
          <Lbl style={{margin:'14px 0 8px'}}>Représentant légal</Lbl><KV rows={[['Nom', `${r.prenom||''} ${r.nom||''}`.trim()||'—'], ['Fonction', r.fonction||'—'], ['Email', r.email||'—'], ['Téléphone', r.telephone||'—'], ['Naissance', r.date_naissance ? new Date(r.date_naissance).toLocaleDateString('fr-FR') : '—']]}/></Card>
      </div>
      <Card pad={0} style={{overflow:'hidden'}}>
        <div style={{display:'flex', alignItems:'center', gap:10, padding:'12px 16px', borderBottom:`1px solid ${V.line}`, flexWrap:'wrap'}}>
          <I n={f && f !== 'chargement' && f.mime === 'application/pdf' ? 'file-pdf' : 'file-image'} s={20} c={V.bad}/><span style={{flex:1, fontWeight:700, fontSize:13.5, minWidth:0, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>{f && f !== 'chargement' ? f.nom : d.libelle}</span>
          {sel === 'identite' && <Seg opts={['Recto'].concat(dos.identite_verso ? ['Verso'] : []).concat(['Selfie'])} i={['recto'].concat(dos.identite_verso ? ['verso'] : []).concat(['selfie']).indexOf(pieceId)} set={k=>setPieceId(['recto'].concat(dos.identite_verso ? ['verso'] : []).concat(['selfie'])[k])}/>}
          {f && f !== 'chargement' && <><Mono s={11.5}>{Math.round((f.taille||0)/1024)} Ko</Mono><Btn kind="ghost" sm icon="arrow-square-out" label="Ouvrir" onClick={()=>ouvrirFichier(f)}/></>}</div>
        <div style={{height:m?360:540, background:V.sub, display:'grid', placeItems:'center', padding:16}}>{apercu}</div>
      </Card>
      <div style={{display:'flex', flexDirection:'column', gap:16}}>
        <Card style={{display:'flex', flexDirection:'column', gap:14}}>
          <Lbl>Décision sur ce document</Lbl><span style={{fontWeight:800, fontSize:14.5}}>{d.libelle}</span><StatusB st={d.statut}/>
          {d.commentaire && d.statut === 'a_corriger' && <Notice tone="warn">{d.commentaire}</Notice>}
          {enRevue && d.statut !== 'a_fournir' && <><div style={{display:'flex', gap:8}}><Btn sm kind={d.statut==='valide'?'accent':'secondary'} icon="check" style={{flex:1}} disabled={occupe} onClick={()=>decider(d.type, 'valide')}>Valider</Btn><Btn sm kind={d.statut==='a_corriger'?'danger':'secondary'} icon="pencil-simple" style={{flex:1}} disabled={occupe || (cm[d.type]||'').length<3} onClick={()=>decider(d.type, 'a_corriger')}>À corriger</Btn></div>
            <Field label="Commentaire pour le partenaire" hint="Obligatoire pour « À corriger »."><textarea className="li" rows={3} value={cm[d.type]||''} onChange={ev=>setCm({...cm,[d.type]:ev.target.value})} placeholder="Ce qui manque ou doit être refait…" style={{...inpCss, height:'auto', padding:12, resize:'vertical', lineHeight:1.5, fontSize:13}}></textarea></Field></>}
          <div style={{borderTop:`1px solid ${V.line}`, paddingTop:12}}><Lbl style={{marginBottom:8}}>Tests sandbox</Lbl>{dos.tests_sandbox.map(c=><span key={c.code} style={{display:'flex', alignItems:'center', gap:8, padding:'4px 0', fontSize:12.5, fontWeight:600, color:c.fait?V.ink:V.ink3}}><I n={c.fait?'check-circle':'circle'} s={16} c={c.fait?V.acc:V.ink3} fill={c.fait}/>{c.libelle}</span>)}</div>
          <div style={{borderTop:`1px solid ${V.line}`, paddingTop:12}}><Lbl style={{marginBottom:8}}>Technique</Lbl><KV rows={[['IP', dos.technique.ip_autorisees.length ? dos.technique.ip_autorisees.join(' · ') : 'Aucune', null, 1], ['Webhooks', dos.technique.webhooks.length ? dos.technique.webhooks.map(u=>{ try { return new URL(u).host; } catch(x){ return u; } }).join(' · ') : 'Aucun', null, 1]]}/></div>
          <div style={{borderTop:`1px solid ${V.line}`, paddingTop:12}}><Lbl style={{marginBottom:8}}>Contacts</Lbl><KV rows={[['Technique', dos.contacts?.technique||'—'], ['Urgence', dos.contacts?.urgence||'—'], ['Finance', dos.contacts?.finance||'—']]}/></div>
        </Card>
      </div>
    </div>
    {dec && <Modal title={{ok:'Approuver le dossier ?', info:'Demander des corrections', refuse:'Refuser le dossier'}[dec]} icon={{ok:'seal-check', info:'chat-circle-text', refuse:'x-circle'}[dec]} tone={dec==='refuse'?'bad':dec==='info'?'warn':undefined} onClose={()=>setDec(null)}
      foot={<><Btn kind="secondary" onClick={()=>setDec(null)}>Annuler</Btn><Btn kind={dec==='refuse'?'danger':'primary'} disabled={occupe || (dec==='refuse' && motif.length<5)} onClick={final}>Confirmer</Btn></>}>
      {dec==='ok' && <><Muted>La production est déverrouillée pour {dos.partenaire.nom}. Le partenaire reçoit un email et peut créer ses clés live.</Muted><Field label="Grade commercial (interne)" hint="Visible uniquement dans cette console."><Sel value={grade} onChange={setGrade} opts={GRADES}/></Field></>}
      {dec==='info' && <><Muted>Le partenaire verra la liste suivante et pourra redéposer les documents.</Muted>{pieces.filter(x=>x.statut==='a_corriger').map(x=><Notice key={x.type} tone="warn" title={x.libelle}>{x.commentaire||'Sans commentaire'}</Notice>)}<Field label="Message général" opt><textarea className="li" rows={3} value={motif} onChange={ev=>setMotif(ev.target.value)} style={{...inpCss, height:'auto', padding:12, lineHeight:1.5}}></textarea></Field></>}
      {dec==='refuse' && <Field label="Motif du refus (visible par le partenaire)"><textarea className="li" rows={4} value={motif} onChange={ev=>setMotif(ev.target.value)} style={{...inpCss, height:'auto', padding:12, lineHeight:1.5}} placeholder="Expliquez clairement la raison."></textarea></Field>}
    </Modal>}
  </Page>;
}

const MOTIFS_REJET = [['non_recu','Virement non reçu'],['montant_different','Montant différent'],['reference_introuvable','Référence introuvable'],['preuve_illisible','Preuve illisible'],['autre','Autre']];
const MOYENS = {virement:'Virement bancaire', wave:'Wave', orange_money:'Orange Money', carte:'Carte', sandbox:'Sandbox'};
function AdmDeps(){
  const toast = useToast(); const {peut, rechargerMoi} = useAdm(); const m = useMob();
  const [f, setF] = React.useState(0); const statuts = ['attente', '', 'valide', 'rejete'];
  const [d, recharger, etat] = useDonnees(() => api('GET', `depots${statuts[f] ? `?statut=${statuts[f]}` : ''}`), [f]);
  const [vue, setVue] = React.useState(0), [recu, setRecu] = React.useState(''), [rej, setRej] = React.useState(null), [occupe, setOccupe] = React.useState(false);
  const liste = d?.donnees || []; const x = liste[vue];
  React.useEffect(() => { setVue(0); }, [f]);
  React.useEffect(() => { if(x) setRecu(String(x.montant_declare)); }, [x?.id]);
  const valider = async () => { setOccupe(true); try { await api('POST', `depots/${x.id}/valider`, {montant_recu:+recu}); toast(`${fmt(+recu)} F CFA crédités`); recharger(); rechargerMoi(); } catch(e){ toast(e.message, 'bad'); } setOccupe(false); };
  const rejeter = async () => { setOccupe(true); try { await api('POST', `depots/${x.id}/rejeter`, {motif:rej.motif, detail:rej.detail}); toast('Dépôt rejeté'); setRej(null); recharger(); rechargerMoi(); } catch(e){ toast(e.message, 'bad'); } setOccupe(false); };
  const preuve = async () => { try { ouvrirFichier(await api('GET', `depots/${x.id}/preuve`)); } catch(e){ toast(e.message, 'bad'); } };
  const ecart = x ? +recu - x.montant_declare : 0;
  return <Page max={1240}><PageHead title="Dépôts à rapprocher" sub="Virements déclarés par les partenaires, à confronter au relevé bancaire. Le solde est crédité du montant reçu."/>
    <Seg opts={[`En attente${d ? ` · ${d.en_attente}` : ''}`,'Tous','Validés','Rejetés']} i={f} set={setF}/>
    {etat.erreur ? <Erreur e={etat.erreur} recharger={recharger}/> :
    <div style={{display:'grid', gridTemplateColumns:m?'1fr':'minmax(0,1.3fr) minmax(0,1fr)', gap:16, alignItems:'start'}}>
      <Tbl chargement={!d} cols={[{k:'r',l:'Dépôt',w:'1.1fr'},{k:'p',l:'Partenaire',w:'1.6fr'},{k:'a',l:'Déclaré',w:'1fr',r:1},{k:'s',l:'Statut',w:'1fr'}]}
        rows={liste.map((y,i)=>({r:<span><Mono c={V.ink}>{y.id}</Mono><span style={{display:'block', fontSize:11.5, color:V.ink3}}>{DC(y.cree_le)}</span></span>, p:<span style={{fontWeight:vue===i?800:600}}>{y.partenaire}</span>, a:<Money n={y.montant_declare} s={13.5}/>, s:<StatusB st={y.statut}/>}))} onRow={setVue}
        empty={<EmptyS icon="bank" title="Rien à rapprocher" sub="Aucun dépôt dans ce statut."/>}/>
      {x && <Card style={{display:'flex', flexDirection:'column', gap:14}}>
        <div style={{display:'flex', alignItems:'center'}}><Mono c={V.ink} s={14}>{x.id}</Mono><span style={{flex:1}}></span><StatusB st={x.statut}/></div>
        <KV rows={[['Partenaire', x.partenaire], ['Moyen', MOYENS[x.moyen]||x.moyen], ['Référence attendue', x.reference_attendue||'—', null, 1], ['Référence déclarée', x.reference_virement||'—', x.reference_virement && x.reference_attendue && x.reference_virement !== x.reference_attendue ? V.bad : null, 1], ['Montant déclaré', `${fmt(x.montant_declare)} F CFA`], ...(x.statut==='valide' ? [['Montant crédité', `${fmt(x.montant_credite)} F CFA`, V.accD]] : []), ['Déclaré le', D(x.cree_le)], ...(x.traite_le ? [['Traité le', D(x.traite_le)]] : [])]}/>
        {x.statut==='rejete' && <Notice tone="bad" title={(MOTIFS_REJET.find(y=>y[0]===x.motif_rejet)||[])[1]}>{x.motif_detail}</Notice>}
        {x.justificatif && <div style={{display:'flex', alignItems:'center', gap:10, padding:'12px 14px', borderRadius:16, border:`1px solid ${V.line}`}}><I n="file-pdf" s={22} c={V.bad}/><span style={{flex:1, fontWeight:700, fontSize:13.5}}>Avis de virement</span><Btn kind="ghost" sm icon="eye" onClick={preuve}>Voir la preuve</Btn></div>}
        {x.statut==='attente' && peut('depots') && <>
          <Field label="Montant reçu (relevé bancaire)" hint="Le solde est crédité de ce montant."><Inp value={recu ? fmt(+recu) : ''} onChange={ev=>setRecu(ev.target.value.replace(/[^\d]/g,''))} trail="F CFA" inputMode="numeric"/></Field>
          {ecart !== 0 && +recu > 0 && <Notice tone="warn" title={`Écart de ${fmt(Math.abs(ecart))} F CFA`}>Probablement des frais bancaires. Validez le montant reçu ou rejetez.</Notice>}
          {!x.reference_virement && <Notice tone="bad" title="Référence absente du virement">Rapprochez manuellement avec le nom de l'émetteur.</Notice>}
          <div style={{display:'flex', gap:8}}><Btn kind="danger" icon="x" style={{flex:1}} onClick={()=>setRej({motif:'non_recu', detail:''})}>Rejeter</Btn><Btn icon="check" style={{flex:1}} disabled={!(+recu>0) || occupe} onClick={valider}>Valider {fmt(+recu||0)} F</Btn></div></>}
      </Card>}
    </div>}
    {rej && <Modal title="Rejeter le dépôt" icon="x-circle" tone="bad" onClose={()=>setRej(null)} foot={<><Btn kind="secondary" onClick={()=>setRej(null)}>Annuler</Btn><Btn kind="danger" disabled={occupe} onClick={rejeter}>Rejeter</Btn></>}>
      <Field label="Motif (visible par le partenaire)"><Sel value={rej.motif} onChange={v=>setRej({...rej, motif:v})} opts={MOTIFS_REJET}/></Field>
      <Field label="Précision" opt><Inp value={rej.detail} onChange={ev=>setRej({...rej, detail:ev.target.value})} placeholder="Aucun virement reçu à cette date…"/></Field></Modal>}
  </Page>;
}
Object.assign(window, {AdmQueue, AdmDossier, AdmDeps});
