function vincitoreSet(s) { if (s.vinc === 'h' || s.vinc === 'g') return s.vinc let h = 0, g = 0 for (const c of s.ris) c === 'h' ? h++ : g++ if (h > g) return 'h' if (g > h) return 'g' return null } // Costruisce l'HTML del referto (funzione pura, testabile). // `now` è iniettabile per rendere deterministica la data nei test. export function buildRefertoHtml(state, now = new Date()) { const { sp, modalitaPartita } = state const { nomi, striscia } = sp const setReali = striscia.filter(s => !s._phantom) const setVinti = { home: 0, guest: 0 } for (const s of setReali) { const v = vincitoreSet(s) if (v === 'h') setVinti.home++ else if (v === 'g') setVinti.guest++ } const dataOra = now.toLocaleString('it-IT', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', }) const giocatoreHtml = (n) => `
${n}
` const formazioneHtml = (formazioneSet) => { if (!formazioneSet) return 'non disponibile' return `
${nomi.home}
${formazioneSet.home.map(giocatoreHtml).join('')}
${nomi.guest}
${formazioneSet.guest.map(giocatoreHtml).join('')}
` } const nomeTeam = (team) => team === 'home' ? nomi.home : nomi.guest const eventiHtml = (s) => { const eventi = [ ...(s.timeouts ?? []).map(t => ({ tipo: 'timeout', ...t })), ...(s.cambi ?? []).map(c => ({ tipo: 'cambio', ...c })), ].sort((a, b) => (a.punteggio.home + a.punteggio.guest) - (b.punteggio.home + b.punteggio.guest)) if (eventi.length === 0) return '' const righe = eventi.map(e => { const sul = `sul ${e.punteggio.home}-${e.punteggio.guest}` const testo = e.tipo === 'timeout' ? `Time out ${nomeTeam(e.team)} ${sul}` : `Cambio ${nomeTeam(e.team)}: entra ${e.in} per ${e.out} ${sul}` return `
  • ${testo}
  • ` }).join('') return `
    Cambi e time out
    ` } const setsHtml = setReali.map((s, i) => { let h = 0, g = 0 const punti = [] for (const c of s.ris) { c === 'h' ? h++ : g++ punti.push({ chi: c, h, g }) } const vinc = vincitoreSet(s) const nomeVinc = vinc === 'h' ? nomi.home : vinc === 'g' ? nomi.guest : '' const etichettaVinc = nomeVinc ? `  ·  vinto da ${nomeVinc}` : '' const servIcon = 'Servizio' const servHomeIcon = s.serv === 'h' ? servIcon : '' const servGuestIcon = s.serv === 'g' ? servIcon : '' const puntiHtml = punti.map(p => `${p.h}-${p.g}` ).join('') return `
    SET${i + 1}
    ${servHomeIcon}${nomi.home} ${h} · ${g} ${nomi.guest}${servGuestIcon}${etichettaVinc}
    Formazione di partenza
    ${formazioneHtml(s.formInizio)}
    ${eventiHtml(s)}
    ${puntiHtml || 'Nessun punto registrato'}
    ` }).join('') const risultatoSetHtml = setReali.map((s, i) => { let h = 0, g = 0 for (const c of s.ris) c === 'h' ? h++ : g++ const vinc = vincitoreSet(s) return ` ${i + 1} ${h} ${g} ` }).join('') const html = ` Referto — ${nomi.home} vs ${nomi.guest}
    Referto di Gara
    ${dataOra}  ·  Modalità: ${modalitaPartita}
    Casa ${nomi.home} vs ${nomi.guest} Ospiti
    ${setsHtml}
    Risultato finale
    ${risultatoSetHtml}
    Set${nomi.home}${nomi.guest}
    Vince ${setVinti.home >= setVinti.guest ? nomi.home : nomi.guest}  ${setVinti.home} – ${setVinti.guest}
    ` return html } // Apre il referto in una nuova scheda e avvia la stampa (effetto collaterale, // solo browser). La generazione dell'HTML è delegata a buildRefertoHtml. export function generaReferto(state) { const html = buildRefertoHtml(state) const w = window.open('', '_blank') w.document.write(html) w.document.close() // Aspetta il caricamento delle immagini (icona servizio) prima di stampare, // altrimenti la stampa parte con risorse ancora in caricamento e appaiono vuote. w.addEventListener('load', () => w.print()) }