// FOOTPASS Messenger v2 · NOTES liées (rendez-vous & personnes)
// Dossier complet façon Notes iOS, rattaché au contexte :
//  • la fiche événement liste les notes du rendez-vous + celles des participants
//  • une note « personne » suit ce contact sur tous ses rendez-vous (dossier)
//  • éditeur plein écran : texte + photos + documents + mémos audio transcrits
const { useState: useStateN, useEffect: useEffectN, useRef: useRefN } = React;
const ntTX = (s) => (typeof TX === 'function' ? TX(s) : s);

window.FP_NOTES = window.FP_NOTES || [];

const fpNoteLines = (t) => {
  const ls = String(t || '').split('\n').map((x) => x.trim()).filter(Boolean);
  return { title: ls[0] || '', rest: ls.slice(1).join(' · ') };
};
// Notes visibles sur une fiche : celles du rendez-vous + les dossiers des participants
window.fpNotesFor = (ev) => {
  const whos = (ev.whos || [ev.who]).filter(Boolean);
  return (window.FP_NOTES || []).filter((n) => n.ev === ev.id || (!n.ev && n.who && whos.includes(n.who)));
};
// Regrouper par origine : prises en appel · notes du contexte · dossiers personnes
window.fpGroupNotes = (notes, ev) => {
  const out = []; const by = {};
  notes.forEach((n) => {
    const key = n.call ? 'call' : (!n.ev && n.who) ? 'p-' + n.who : 'ctx';
    if (!by[key]) {
      const p = key.charAt(0) === 'p' ? FP_PEERS[n.who] : null;
      by[key] = {
        key, p,
        label: key === 'call' ? ntTX('Prises en appel')
          : p ? ntTX('Dossier') + ' ' + p.name.split(' ')[0]
          : ntTX(ev && ev.kindLabel ? 'Notes du salon' : 'Ce rendez-vous'),
        items: [],
      };
      out.push(by[key]);
    }
    by[key].items.push(n);
  });
  return out;
};

const NtCam = ({ s = 15 }) => (
  <svg width={s} height={s} viewBox="0 0 20 20" fill="none">
    <path d="M2 6.2A2.2 2.2 0 014.2 4h1.6l1.3-1.7h5.8L14.2 4h1.6A2.2 2.2 0 0118 6.2v8.6a2.2 2.2 0 01-2.2 2.2H4.2A2.2 2.2 0 012 14.8V6.2z" stroke="currentColor" strokeWidth="1.5"></path>
    <circle cx="10" cy="10.3" r="3.2" stroke="currentColor" strokeWidth="1.5"></circle>
  </svg>
);
const ntFmtT = (s) => Math.floor(s / 60) + ':' + String(s % 60).padStart(2, '0');

// ── Mémo audio : lecture simulée + transcription dépliable ──
function NtAudio({ a, onRemove }) {
  const [open, setOpen] = useStateN(false);
  const [play, setPlay] = useStateN(false);
  useEffectN(() => {
    if (!play) return undefined;
    const secs = (a.dur.split(':').reduce((m, x) => m * 60 + +x, 0) || 8) * 1000;
    const id = setTimeout(() => setPlay(false), secs);
    return () => clearTimeout(id);
  }, [play]);
  return (
    <div className="ntv-aud">
      <div className="ntv-aud-main">
        <button className="ntv-aud-play" onClick={() => setPlay(!play)} aria-label="Lecture">
          {play ? <FPIcon.Pause c="currentColor" /> : <FPIcon.Play c="currentColor" />}
        </button>
        <span className={`ntv-aud-wave ${play ? 'live' : ''}`}>
          {[9, 14, 7, 16, 11, 6, 13, 17, 8, 12, 15, 7, 11, 16, 9, 13, 6, 10].map((h, i) => (
            <i key={i} style={{ height: h + 'px', animationDelay: (i * 70) % 560 + 'ms' }}></i>
          ))}
        </span>
        <em>{a.dur}</em>
        {onRemove ? <button className="ntv-att-x" onClick={onRemove} aria-label="Retirer">×</button> : null}
      </div>
      {a.tr ? (
        <>
          <button className={`ntv-aud-trbtn ${open ? 'on' : ''}`} onClick={() => setOpen(!open)}>
            {ntTX('Transcription')}
            <svg width="9" height="6" viewBox="0 0 9 6" fill="none"><path d="M1 1.2L4.5 4.8L8 1.2" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"></path></svg>
          </button>
          {open ? <div className="ntv-aud-tr">« {a.tr} »</div> : null}
        </>
      ) : null}
    </div>
  );
}

// ── Pièces jointes (éditeur) ──
function NtAtts({ att, onRemove }) {
  if (!att.length) return null;
  return (
    <div className="ntv-atts">
      {att.map((a, i) =>
        a.k === 'aud' ? (
          <NtAudio key={i} a={a} onRemove={onRemove ? () => onRemove(i) : null} />
        ) : (
          <div key={i} className={`ntv-att ${a.k}`}>
            <span className="ntv-att-ic">{a.k === 'img' ? <NtCam s={14} /> : <FPIcon.Doc s={13} />}</span>
            <span className="ntv-att-txt"><b>{a.name}</b>{a.size ? <em>{a.size}</em> : null}</span>
            {onRemove ? <button className="ntv-att-x" onClick={() => onRemove(i)} aria-label="Retirer">×</button> : null}
          </div>
        )
      )}
    </div>
  );
}

// ═══════ ÉDITEUR (plein écran, façon Notes iOS) ═══════
function NoteEditorV2({ note, ev, onDone, onDelete }) {
  const whos = (ev.whos || [ev.who]).filter((id) => FP_PEERS[id]);
  const [text, setText] = useStateN(note ? note.text : '');
  const [link, setLink] = useStateN(note ? (note.ev ? 'ev' : note.who) : 'ev');
  const [att, setAtt] = useStateN(note && note.att ? note.att.slice() : []);
  const [rec, setRec] = useStateN(null); // null | { t, wi }
  const taRef = useRefN(null);
  useEffectN(() => {
    const ta = taRef.current;
    if (ta && !note) { ta.focus(); }
  }, []);

  // Transcription en direct pendant l'enregistrement (simulation)
  const firstName = (FP_PEERS[whos[0]] || {}).name || 'le club';
  const trFull = ntTX('Confirmer l\u2019horaire avec ') + firstName.split(' ')[0] + ntTX(', r\u00e9cup\u00e9rer la convocation officielle et pr\u00e9parer la pi\u00e8ce d\u2019identit\u00e9 avant le rendez-vous.');
  const trWords = trFull.split(' ');
  useEffectN(() => {
    if (!rec) return undefined;
    const w = setInterval(() => setRec((r) => (r && r.wi < trWords.length ? { ...r, wi: r.wi + 1 } : r)), 300);
    const t = setInterval(() => setRec((r) => (r ? { ...r, t: r.t + 1 } : r)), 1000);
    return () => { clearInterval(w); clearInterval(t); };
  }, [!!rec]);
  const stopRec = () => {
    setAtt([...att, { k: 'aud', dur: ntFmtT(Math.max(rec.t, 2)), tr: trWords.slice(0, Math.max(rec.wi, 6)).join(' ') }]);
    setRec(null);
  };

  const nImg = att.filter((a) => a.k === 'img').length;
  const addPhoto = () => setAtt([...att, { k: 'img', name: ntTX('Photo') + ' · IMG_08' + (24 + nImg) + '.jpg', size: '1,8 Mo' }]);
  const addDoc = () => setAtt([...att, { k: 'doc', name: ntTX('Convocation officielle.pdf'), size: '340 Ko' }]);

  const themeC = (window.FP_EV_THEMES[ev.theme] || {}).c;
  const canSave = text.trim() || att.length;
  return ReactDOM.createPortal(
    <div className="ntv-ed" data-screen-label="Éditeur de note">
      <div className="ntv-ed-head">
        <button className="ntv-hbtn" onClick={() => onDone(null)}>{ntTX('Annuler')}</button>
        <b>{ntTX('Note')}</b>
        <button className="ntv-hbtn ok" disabled={!canSave} onClick={() => onDone(text, link, att)}>OK</button>
      </div>
      <div className="ntv-ed-meta">{note ? note.ts : ntTX("Aujourd'hui") + ' · 16:08'}</div>
      <div className="ntv-links">
        <span className="ntv-linklbl">{ntTX('Liée à')}</span>
        <button className={`ntv-link ${link === 'ev' ? 'on' : ''}`} onClick={() => setLink('ev')}>
          <span className="ntv-linkdot" style={{ background: themeC }}></span>{ntTX(ev.kindLabel || 'Ce rendez-vous')}
        </button>
        {whos.map((id) => {
          const p = FP_PEERS[id];
          return (
            <button key={id} className={`ntv-link ${link === id ? 'on' : ''}`} onClick={() => setLink(id)}>
              <FPAvatar size={16} initials={p.initials} src={p.photo} />{p.name.split(' ')[0]}
            </button>
          );
        })}
      </div>
      <div className="ntv-linkhint">
        {link === 'ev'
          ? ntTX(ev.kindLabel ? 'Note privée · visible dans ce salon uniquement, par vous seul' : 'Visible sur ce rendez-vous uniquement')
          : ntTX('Suit ce contact sur tous ses rendez-vous')}
      </div>
      <textarea ref={taRef} value={text} onChange={(e) => setText(e.target.value)}
        placeholder={ntTX('Écrivez… la première ligne devient le titre')} />
      <NtAtts att={att} onRemove={(i) => setAtt(att.filter((_, j) => j !== i))} />

      {rec ? (
        <div className="ntv-rec">
          <div className="ntv-rec-top">
            <span className="ntv-rec-dot"></span><b>{ntTX('Enregistrement…')}</b><em>{ntFmtT(rec.t)}</em>
          </div>
          <div className="ntv-rec-tr">
            <span className="ntv-rec-trlbl">{ntTX('Transcription')}</span>
            {rec.wi ? trWords.slice(0, rec.wi).join(' ') : <i>{ntTX('Parlez, le texte s\u2019\u00e9crit en direct…')}</i>}
            <span className="ntv-caret"></span>
          </div>
          <button className="ntv-rec-stop" onClick={stopRec}>{ntTX('Terminer')}</button>
        </div>
      ) : (
        <div className="ntv-tools">
          <button onClick={addPhoto}><NtCam /> {ntTX('Photo')}</button>
          <button onClick={addDoc}><FPIcon.Doc s={14} /> {ntTX('Document')}</button>
          <button className="mic" onClick={() => setRec({ t: 0, wi: 0 })}><FPIcon.Mic s={10} /> {ntTX('Audio')}</button>
        </div>
      )}
      {note && !rec ? (
        <div className="ntv-ed-foot">
          <button className="ntv-del" onClick={onDelete}>{ntTX('Supprimer la note')}</button>
        </div>
      ) : null}
    </div>,
    document.querySelector('.hm') || document.body
  );
}

// ═══════ BLOC « NOTES » (fiche événement) ═══════
function NotesBlockV2({ ev, showToast, dense }) {
  const [edit, setEdit] = useStateN(null); // null | {} (nouvelle) | { note }
  const [expanded, setExpanded] = useStateN({}); // groupes dépliés au-delà de 3 notes
  const [, force] = useStateN(0);
  const notes = window.fpNotesFor(ev);
  const themeC = (window.FP_EV_THEMES[ev.theme] || {}).c;

  const done = (text, link, att) => {
    if (text != null && (text.trim() || (att && att.length))) {
      const t = text.trim();
      const ts = ntTX("Aujourd'hui") + ' · 16:08';
      const evId = link === 'ev' ? ev.id : undefined;
      const who = link === 'ev' ? ev.who : link;
      const rec = { text: t, ev: evId, who, ts, att: att && att.length ? att : undefined };
      if (edit && edit.note) {
        window.FP_NOTES = window.FP_NOTES.map((n) => (n.id === edit.note.id ? { ...n, ...rec } : n));
      } else {
        window.FP_NOTES = [{ id: 'n' + Date.now(), ...rec }, ...window.FP_NOTES];
      }
      if (window.fpSaveNotes) window.fpSaveNotes();
      if (showToast) showToast(ntTX('Note enregistrée'));
    }
    setEdit(null); force((x) => x + 1);
  };
  const del = () => {
    window.FP_NOTES = window.FP_NOTES.filter((n) => n.id !== edit.note.id);
    if (window.fpSaveNotes) window.fpSaveNotes();
    setEdit(null); force((x) => x + 1);
    if (showToast) showToast(ntTX('Note supprimée'));
  };

  return (
    <div className="ntv-block">
      <div className="ntv-head">
        <b>{ntTX('Notes')}{notes.length ? <em> · {notes.length}</em> : null}</b>
        <button className="ntv-add" onClick={() => setEdit({})} aria-label="Nouvelle note">+</button>
      </div>
      {notes.length && dense ? (
        <div className="ntv-list">
          {(expanded.dense ? notes : notes.slice(0, 4)).map((n) => {
            const { title } = fpNoteLines(n.text);
            const p = !n.ev && n.who ? FP_PEERS[n.who] : null;
            const att = n.att || [];
            const aud = att.find((a) => a.k === 'aud');
            const nDoc = att.filter((a) => a.k !== 'aud').length;
            return (
              <button key={n.id} className="ntv-row dense" onClick={() => setEdit({ note: n })}>
                {p ? <FPAvatar size={16} initials={p.initials} src={p.photo} /> : <span className="ntv-dot" style={{ background: n.call ? 'var(--acc, #00A37E)' : themeC }}></span>}
                <b className="ntv-dtitle">{title || (aud ? ntTX('Note audio') : ntTX('Pièces jointes'))}</b>
                {aud ? <i className="ntv-dmini"><FPIcon.Mic s={8} /></i> : null}
                {nDoc ? <i className="ntv-dmini"><FPIcon.Doc s={9} /></i> : null}
                <em className={`ntv-dts ${n.call ? 'call' : ''}`}>{n.call ? ntTX('En appel') : String(n.ts || '').split(' · ')[0]}</em>
              </button>
            );
          })}
          {notes.length > 4 && !expanded.dense ? (
            <button className="ntv-more dense" onClick={() => setExpanded({ ...expanded, dense: true })}>
              + {notes.length - 4} {ntTX('autres notes')}
            </button>
          ) : null}
        </div>
      ) : notes.length ? (
        <div className="ntv-list">
          {window.fpGroupNotes(notes, ev).map((g, gi, arr) => {
            const showHead = arr.length > 1 || g.items.length > 3;
            const items = expanded[g.key] ? g.items : g.items.slice(0, 3);
            return (
              <React.Fragment key={g.key}>
                {showHead ? (
                  <div className="ntv-group"><span>{g.label}</span><em>{g.items.length}</em></div>
                ) : null}
                {items.map((n) => {
            const { title, rest } = fpNoteLines(n.text);
            const p = !n.ev && n.who ? FP_PEERS[n.who] : null;
            const att = n.att || [];
            const aud = att.find((a) => a.k === 'aud');
            const nDoc = att.filter((a) => a.k !== 'aud').length;
            return (
              <button key={n.id} className="ntv-row" onClick={() => setEdit({ note: n })}>
                {p ? <FPAvatar size={20} initials={p.initials} src={p.photo} /> : <span className="ntv-dot" style={{ background: n.call ? 'var(--acc, #00A37E)' : themeC }}></span>}
                <span className="ntv-txt">
                  <b>{title || (aud ? ntTX('Note audio') : ntTX('Pièces jointes'))}</b>
                  <em>{n.ts}{rest ? ' · ' + rest : (!rest && aud && aud.tr ? ' · ' + aud.tr : '')}</em>
                  {(p || att.length) ? (
                    <span className="ntv-minis">
                      {aud ? <i className="ntv-mini aud"><FPIcon.Mic s={8} /> {aud.dur}</i> : null}
                      {nDoc ? <i className="ntv-mini"><FPIcon.Doc s={9} /> {nDoc}</i> : null}
                      {p ? <i className="ntv-mini">{ntTX('Dossier')} {p.name.split(' ')[0]}</i> : null}
                    </span>
                  ) : null}
                </span>
              </button>
            );
                })}
                {g.items.length > 3 && !expanded[g.key] ? (
                  <button className="ntv-more" onClick={() => setExpanded({ ...expanded, [g.key]: true })}>
                    + {g.items.length - 3} {ntTX('autres notes')}
                  </button>
                ) : null}
              </React.Fragment>
            );
          })}
        </div>
      ) : (
        <button className="ntv-empty" onClick={() => setEdit({})}>{ntTX(ev.kindLabel ? 'Aucune note · touchez + pour une note privée' : 'Aucune note · touchez + pour briefer ce rendez-vous')}</button>
      )}
      {edit ? <NoteEditorV2 note={edit.note} ev={ev} onDone={done} onDelete={del} /> : null}
    </div>
  );
}

Object.assign(window, { NotesBlockV2, NoteEditorV2, NtAudio });
