// FOOTPASS v2 · Message entrant d'un agent HORS contacts (démo Tiago Moreira)
// PAS de flux « demande de message » : le message arrive comme une conversation NORMALE (WhatsApp).
// PAS de bandeau d’autorisation en chat (retiré 27.07 — backend trop complexe pour cette version).
// La vérification se fait par la fiche contact (⋯) : Identité → Pass ID · Structure → page structure publique.
// État : localStorage fp_msgreq = 'new' (non lu) | 'seen' | 'off'.
const { useState: useStateRQ, useEffect: useEffectRQ } = React;

const FPREQ = {
  pid: 'tiago',
  peer: {
    id: 'tiago', name: 'Tiago MOREIRA', initials: 'TM', role: 'Agent', org: 'Ibéria Talents', orgId: 'iberia',
    passNo: '2480 7741 0163', online: true, fam: 'agent',
  },
  msg: 'Bonjour Alexandre. Nous ne nous connaissons pas — je représente João Tavares, ailier de Boavista. Votre travail sur la filière nantaise parle pour vous : j’aimerais collaborer avec vous pour son arrivée en Ligue 1 cet été.',
  time: '16:12',
};

function fpReqState() {
  try {
    const v = localStorage.getItem('fp_msgreq') || 'new';
    return v === 'accepted' ? 'seen' : v === 'declined' ? 'off' : v;
  } catch (e) { return 'new'; }
}
function fpReqSet(v) { try { localStorage.setItem('fp_msgreq', v); } catch (e) {} window.dispatchEvent(new CustomEvent('fp:msgreq')); }

// Annuaire : le contact et le fil existent dès le chargement, comme n'importe quel autre
window.FP_PEERS = window.FP_PEERS || {};
window.FP_PEERS[FPREQ.pid] = FPREQ.peer;
window.FP_THREADS = window.FP_THREADS || {};
window.FP_THREADS[FPREQ.pid] = window.FP_THREADS[FPREQ.pid] || [
  { id: 1, kind: 'day', label: "AUJOURD'HUI" },
  { id: 2, kind: 'text', side: 'received', time: FPREQ.time, text: FPREQ.msg },
  { id: 3, kind: 'text', side: 'received', time: '16:13', text: 'Pour que tout soit clair d\u00e8s le d\u00e9part, voici mon autorisation \u2014 elle se v\u00e9rifie ici m\u00eame.' },
  { id: 4, kind: 'auth', side: 'received', time: '16:13',
    auth: { id: 'TM1', who: { name: 'Jo\u00e3o TAVARES', role: 'Ailier', org: 'Boavista FC', initials: 'JT', fam: 'joueur' },
      benef: { name: 'Tiago MOREIRA', role: 'Agent', org: 'Ib\u00e9ria Talents', initials: 'TM', pid: 'tiago', fam: 'agent' },
      type: 'Autorisation de repr\u00e9sentation', level: 'N\u00e9gociation', terr: 'Monde', until: '30 juin 2027', status: 'active', num: 'FP-A-2026-0187' } },
];

// ── Registre des structures · pages publiques consultables depuis les fiches contact ──
// Chaque personne du roster/équipe : passNo (Pass ID), cp (personne de contact CHOISIE par le joueur),
// pid (contact FOOTPASS existant), phone (si ON a son numéro), fam (teinte de rôle).
window.FP_STRUCTS = Object.assign(window.FP_STRUCTS || {}, {
  iberia: {
    id: 'iberia', name: 'Ibéria Talents', initials: 'IT', type: 'Agence de représentation',
    roster: [
      { initials: 'JT', name: 'João TAVARES', id2: 'Ailier · Boavista FC', fam: 'joueur', passNo: 'FP-6621-4402-JT', cp: 'Tiago MOREIRA', terr: 'Monde', hot: true },
      { initials: 'RP', name: 'Rúben PIRES', id2: 'Défenseur central · SC Braga', fam: 'joueur', passNo: 'FP-9034-1187-RP', cp: 'Tiago MOREIRA', terr: 'Europe' },
      { initials: 'DC', name: 'Diego CARDOSO', id2: 'Milieu offensif · Getafe CF', fam: 'joueur', passNo: 'FP-4419-7702-DC', cp: 'Inês SAMPAIO', terr: 'Monde' },
      { initials: 'BL', name: 'Bernardo LOPES', id2: 'Gardien · Vitória SC', fam: 'joueur', passNo: 'FP-1163-0248-BL', cp: 'Inês SAMPAIO', terr: 'Portugal' },
      { initials: 'NB', name: 'Nuno BARROS', id2: 'Latéral droit · FC Famalicão', fam: 'joueur', passNo: 'FP-8850-6613-NB', cp: 'Tiago MOREIRA', terr: 'Portugal' },
      { initials: 'TR', name: 'Tomás ROCHA', id2: 'Milieu défensif · Rio Ave FC', fam: 'joueur', passNo: 'FP-3327-9915-TR', cp: [{ n: 'Pascal LEROY', terr: 'France' }, { n: 'Inês SAMPAIO', terr: 'Portugal' }, { n: 'Tiago MOREIRA', terr: 'Monde' }], phone: '+351 913 552 078', terr: 'Europe' },
      { initials: 'AF', name: 'André FONSECA', id2: 'Attaquant · Casa Pia AC', fam: 'joueur', passNo: 'FP-7208-4431-AF', cp: 'Tiago MOREIRA', terr: 'Portugal' },
      { initials: 'RM', name: 'Rafael MENDES', id2: 'Ailier gauche · Estoril Praia', fam: 'joueur', passNo: 'FP-5540-2276-RM', cp: 'Inês SAMPAIO', terr: 'Monde' },
      { initials: 'HM', name: 'Hugo MARTINS', id2: 'Défenseur central · Moreirense FC', fam: 'joueur', passNo: 'FP-0912-8834-HM', cp: 'Tiago MOREIRA', terr: 'Portugal' },
      { initials: 'MS', name: 'Marco SILVA', id2: 'Entraîneur · FC Porto', fam: 'staff', pid: 'marco', passNo: 'FP-3310-7728-MS', cp: 'Tiago MOREIRA', phone: '+351 912 380 664', terr: 'Europe' },
    ],
    team: [
      { initials: 'TM', name: 'Tiago MOREIRA', id2: 'Agent · Monde', fam: 'agent', pid: 'tiago', passNo: '2480 7741 0163' },
      { initials: 'IS', name: 'Inês SAMPAIO', id2: 'Agente · Portugal', fam: 'agent', passNo: 'FP-8812-3306-IS' },
      { initials: 'PL', name: 'Pascal LEROY', id2: 'Agent · France', fam: 'agent', passNo: 'FP-7731-2209-PL' },
      { initials: 'PA', name: 'Pedro ALVES', id2: 'Direction', fam: 'staff', passNo: 'FP-2216-9904-PA' },
    ],
  },
  classico: {
    id: 'classico', name: 'Classico Sport', initials: 'CS', type: 'Agence de représentation',
    roster: [
      { initials: 'NK', name: 'Nenad KRSTIĆ', id2: 'Milieu offensif · Étoile Rouge', fam: 'joueur', passNo: 'FP-6134-0921-NK', cp: 'Amadou MBAYE', terr: 'Europe' },
      { initials: 'IC', name: 'Ismaïla CAMARA', id2: 'Attaquant · Génération Foot', fam: 'joueur', passNo: 'FP-2209-5518-IC', cp: 'Amadou MBAYE', terr: 'Monde' },
      { initials: 'YD', name: 'Youssou DIAGNE', id2: 'Défenseur central · Casa Sports', fam: 'joueur', passNo: 'FP-9917-3342-YD', cp: 'Amadou MBAYE', terr: 'Afrique' },
    ],
    team: [
      { initials: 'AM', name: 'Amadou MBAYE', id2: 'Agent · Monde', fam: 'agent', pid: 'amadou', passNo: 'FP-1908-2215-AM' },
      { initials: 'SK', name: 'Sira KEÏTA', id2: 'Juriste', fam: 'reseau', pid: 'sira', passNo: 'FP-5521-0937-SK' },
    ],
  },
});

// ── Personne de contact selon MA région (le joueur décide qui est visible, par territoire) ──
// cp = nom (une seule personne) OU [{ n, terr }] : ma région → sinon Monde → sinon la première.
window.FP_MY_REGION = 'France';
window.fpResolveCp = (cp, team) => {
  if (!cp) return null;
  const find = (name) => (team || []).find((t) => t.name === name) || null;
  if (typeof cp === 'string') return find(cp);
  const pick = cp.find((x) => x.terr === window.FP_MY_REGION) || cp.find((x) => x.terr === 'Monde') || cp[0];
  return pick ? find(pick.n) : null;
};

// ── Mini-fiche personne (roster / équipe) : Pass ID · Message direct · agence · personne de contact ──
function FPStContact({ p, st, onClose, onSwap }) {
  const tx = window.TX || ((s) => s);
  const [passOpen, setPassOpen] = useStateRQ(false);
  const [added, setAdded] = useStateRQ(false);
  const cpM = p.cp ? window.fpResolveCp(p.cp, st && st.team) : null;
  const stPeer = () => {
    const bits = (p.id2 || '').split(' · ');
    return { id: 'st_' + p.name.toLowerCase().replace(/[^a-z0-9]+/g, ''), name: p.name, initials: p.initials, role: bits[0] || 'Membre', org: bits[1] || (st ? st.name : ''), fam: p.fam || 'joueur', passNo: p.passNo, phone: p.phone, orgId: st ? st.id : undefined };
  };
  const openMsg = () => window.dispatchEvent(new CustomEvent('fp:openchat', { detail: p.pid ? { pid: p.pid } : { peer: stPeer() } }));
  const openCall = (kind) => window.dispatchEvent(new CustomEvent('fp:call', { detail: p.pid ? { pid: p.pid, kind } : { peer: stPeer(), kind } }));
  return (
    <React.Fragment>
    <PgSheet inChat onClose={onClose} title="Contact" centerTitle>
      <div className="pg-peer">
        <FPAvatar size={64} initials={p.initials} />
        <span>
          <div className="pg-peer-name" style={{ justifyContent: 'center' }}>{p.name}</div>
          <div className="pg-peer-role" style={{ textAlign: 'center' }}>{window.m4RoleColor && p.fam ? <React.Fragment><span style={{ color: window.m4RoleColor(p.fam) }}>{(p.id2 || '').split(' · ')[0]}</span>{(p.id2 || '').indexOf(' · ') > -1 ? ' · ' + p.id2.split(' · ').slice(1).join(' · ') : ''}</React.Fragment> : p.id2}</div>
        </span>
        {!p.me ? (
          <span className={`pg-peer-acts ${p.phone ? 'three' : ''}`} style={p.phone ? undefined : { gridTemplateColumns: '1fr' }}>
            {p.phone ? <button className="pg-btn" onClick={() => openCall('voice-out')}><FPIcon.Phone s={16} /> {tx('Appel')}</button> : null}
            {p.phone ? <button className="pg-btn" onClick={() => openCall('video')}><FPIcon.Video s={18} /> {tx('Vidéo')}</button> : null}
            <button className="pg-btn" onClick={openMsg}><svg width="15" height="15" viewBox="0 0 16 16" fill="none"><path d="M8 2.3c3.6 0 6.4 2.4 6.4 5.3S11.6 13 8 13c-.8 0-1.5-.1-2.2-.3L2.9 13.8l.9-2.3C2.5 10.5 1.6 9.1 1.6 7.6 1.6 4.7 4.4 2.3 8 2.3z" stroke="currentColor" strokeWidth="1.4" strokeLinejoin="round"></path></svg> {tx('Message')}</button>
          </span>
        ) : null}
      </div>
      <div className="pg-info">
        {p.passNo ? <button className="pg-inforow fpst-link" onClick={() => setPassOpen(true)}><span>{tx('Identité')}</span><b>Pass ID <svg width="12" height="12" viewBox="0 0 14 14" fill="none"><path d="M5 3l4 4-4 4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"></path></svg></b></button> : null}
        {st ? <div className="pg-inforow"><span>{tx(st.type && st.type.indexOf('Agence') === 0 ? 'Agence' : 'Structure')}</span><b>{st.name}</b></div> : null}
        {cpM ? <button className="pg-inforow fpst-link" onClick={() => onSwap(cpM)}><span>{tx('Personne de contact')}</span><b>{cpM.name} {Array.isArray(p.cp) ? <i className="pg-cpreg">{window.FP_MY_REGION}</i> : null} <svg width="12" height="12" viewBox="0 0 14 14" fill="none"><path d="M5 3l4 4-4 4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"></path></svg></b></button> : null}
        {p.phone ? <div className="pg-inforow"><span>{tx('Téléphone')}</span><b className="ok"><FPIcon.Phone c="currentColor" s={12} /> {p.phone}</b></div> : null}
        {!p.me && !added && !p.pid && !(window.FP_PEERS && window.FP_PEERS['st_' + p.name.toLowerCase().replace(/[^a-z0-9]+/g, '')]) ? <button className="pg-inforow fpst-link" onClick={() => { window.dispatchEvent(new CustomEvent('fp:addcontact', { detail: { peer: stPeer() } })); setAdded(true); }}><span style={{ color: 'var(--acc-bright, #00C49A)', fontWeight: 700 }}>+ {tx('Ajouter aux contacts')}</span></button> : null}
        {added ? <div className="pg-inforow"><span style={{ color: 'var(--acc-bright, #00C49A)', fontWeight: 700 }}>✓ {tx('Ajouté aux contacts')}</span></div> : null}
      </div>
      {p.phone ? <div className="hm-empty" style={{ paddingTop: 4 }}>{tx('Vous avez son numéro — joignable en direct, hors FOOTPASS.')}</div> : null}
    </PgSheet>
    {passOpen ? (
      <PgSheet inChat onClose={() => setPassOpen(false)} title="Pass ID" centerTitle>
        <div className="fpcard passid fpst-pass">
          <div className="passid-head"><FPIcon.Shield s={13} /><span className="passid-verified">{tx('IDENTITÉ VÉRIFIÉE')}</span></div>
          <div className="fpcard-row">
            <FPAvatar size={40} initials={p.initials} ring />
            <div className="fpcard-main">
              <div className="passid-name">{p.name}</div>
              <div className="passid-num">{p.passNo}</div>
            </div>
          </div>
          <div className="passid-foot"><span className="passid-bio"><FPIcon.FaceScan s={12} />{tx('Biométrie confirmée')}</span><span className="passid-since">{tx('Membre FOOTPASS')}</span></div>
        </div>
        <div className="hm-empty" style={{ paddingTop: 6 }}>{tx('Chaque membre FOOTPASS est vérifié à l’entrée · le Pass ID est sa carte d’identité numérique.')}</div>
      </PgSheet>
    ) : null}
    </React.Fragment>
  );
}

// ── Page structure PUBLIQUE (celle que tout le monde voit) ──
// mine=true (aperçu de SA propre page) : territoires en clair, bannière « aperçu », pas de demande.
// Sinon : territoires floutés — visibles des parties concernées, sur demande.
function FPStructSheet({ id, struct, onClose }) {
  const tx = window.TX || ((s) => s);
  const [asked, setAsked] = useStateRQ(false);
  const [contact, setContact] = useStateRQ(null); // mini-fiche : personne du roster dont ON a le numéro
  const st = struct || (window.FP_STRUCTS || {})[id];
  if (!st) return null;
  const mine = !!st.mine;
  return (
    <React.Fragment>
    <PgSheet inChat onClose={onClose} title="Page structure" centerTitle>
      {mine ? (
        <div className="fpst-mine">
          <svg width="13" height="13" viewBox="0 0 16 16" fill="none"><path d="M2.5 8c1.5-3 3.3-4.5 5.5-4.5S12 5 13.5 8c-1.5 3-3.3 4.5-5.5 4.5S4 11 2.5 8z" stroke="currentColor" strokeWidth="1.3"></path><circle cx="8" cy="8" r="1.8" stroke="currentColor" strokeWidth="1.3"></circle></svg>
          {tx('Aperçu public · votre page telle que les autres la voient')}
        </div>
      ) : null}
      <div className="pg-peer">
        <span className="fpst-logo">{st.initials}</span>
        <span>
          <div className="pg-peer-name" style={{ justifyContent: 'center' }}>{st.name} <FPIcon.Shield s={13} /></div>
          <div className="pg-peer-role" style={{ textAlign: 'center' }}>{tx(st.type)}</div>
        </span>
      </div>
      <div className="fpst-lbl"><FPIcon.Shield s={10} c="currentColor" /> {tx(mine ? 'Vous représentez · autorisations publiques' : 'Ils représentent · autorisations publiques')}</div>
      <div className="fpst-list fpst-scroll">
        {st.roster.map((p) => (
          <button key={p.name} className={`fpst-row ${p.hot ? 'hot' : ''}`} onClick={() => setContact(p)}>
            <FPAvatar size={38} initials={p.initials} />
            <span className="fpst-tx"><b>{p.name}{p.phone ? <i className="fpst-hasnum"><FPIcon.Phone c="currentColor" s={9} /></i> : null}</b><em>{p.id2}</em></span>
            <span className="fpst-lvl"><b>{tx('Représentation')}</b><em className={mine ? '' : 'fpst-terr-mask'}>{tx(p.terr)}</em></span>
          </button>
        ))}
      </div>
      {!mine ? (
        <button className={`fpst-req ${asked ? 'sent' : ''}`} disabled={asked} onClick={() => setAsked(true)}>
          {asked ? tx('Demande envoyée · les territoires seront visibles après accord de la structure') : tx('Territoires visibles des parties concernées · demander l’accès')}
        </button>
      ) : null}
      <div className="fpst-lbl">{tx(mine ? 'Votre équipe' : 'Leur équipe')}</div>
      <div className="fpst-list">
        {st.team.map((p) => (
          <button key={p.name} className="fpst-row" onClick={() => setContact(p)}>
            <FPAvatar size={38} initials={p.initials} />
            <span className="fpst-tx"><b>{p.name}{p.phone ? <i className="fpst-hasnum"><FPIcon.Phone c="currentColor" s={9} /></i> : null}</b><em>{tx(p.id2)}</em></span>
          </button>
        ))}
      </div>
    </PgSheet>
    {contact ? <FPStContact p={contact} st={st} onClose={() => setContact(null)} onSwap={(m) => setContact(m)} /> : null}
    </React.Fragment>
  );
}

// ── Tête de « Tous » : une conversation comme les autres (aucun style dédié) ──
function FPReqZone({ onOpenChat }) {
  const T = window.TX || ((s) => s);
  const [st, setSt] = useStateRQ(fpReqState());
  // Dès qu'on a RÉPONDU à Tiago, sa conversation entre dans la liste vivante (fp:convos) :
  // la rangée injectée disparaît pour ne pas faire doublon.
  const inList = () => (window.FP_CONVOS || []).some((c) => c.id === FPREQ.pid);
  const [dup, setDup] = useStateRQ(inList());
  useEffectRQ(() => {
    const f = () => setSt(fpReqState());
    const g = () => setDup(inList());
    window.addEventListener('fp:msgreq', f);
    window.addEventListener('fp:convos', g);
    return () => { window.removeEventListener('fp:msgreq', f); window.removeEventListener('fp:convos', g); };
  }, []);
  if (st === 'off' || dup) return null;
  const unread = st === 'new';
  const open = () => { fpReqSet('seen'); onOpenChat(FPREQ.pid); };
  return (
    <button className="hm-convo" onClick={open}>
      <span className="hm-convo-av"><FPAvatar size={46} initials={FPREQ.peer.initials} /></span>
      <span className="hm-convo-main">
        <span className="hm-convo-top"><b>{window.fpUpperLast(FPREQ.peer.name)}</b><span className={`hm-convo-time ${unread ? 'acc' : ''}`}>{FPREQ.time}</span></span>
        <span className="hm-convo-id"><span className="ci-role" style={{ color: window.m4RoleColor ? window.m4RoleColor('agent') : undefined }}>{T('Agent')}</span><span className="ci-sep"> · </span><span className="ci-org">{FPREQ.peer.org}</span></span>
        <span className="hm-convo-prev"><em>{FPREQ.msg}</em>{unread ? <span className="hm-unread">1</span> : null}</span>
      </span>
    </button>
  );
}

Object.assign(window, { FPReqZone, fpReqSet, FPStructSheet, FPStContact });
