import { describe, it, expect } from 'vitest'
import { buildRefertoHtml } from '../../src/referto.js'
import { createInitialState } from '../../src/gameState.js'

// Data fissa per asserzioni deterministiche
const NOW = new Date('2026-03-14T20:30:00')

// Costruisce uno stato con una striscia di set arbitraria
function statoConSet(striscia, extra = {}) {
    const state = createInitialState()
    state.sp.striscia = striscia
    state.sp.nomi = { home: 'Antoniana', guest: 'Rivali' }
    return { ...state, ...extra }
}

describe('buildRefertoHtml (referto.js)', () => {
    it('esclude i set _phantom dal referto', () => {
        const striscia = [
            { serv: 'h', ris: 'h'.repeat(25) + 'g'.repeat(20), vinc: 'h' },
            { serv: 'g', ris: '', vinc: 'g', _phantom: true },
            { serv: 'h', ris: 'h'.repeat(25) + 'g'.repeat(18), vinc: 'h' },
        ]
        const html = buildRefertoHtml(statoConSet(striscia), NOW)
        // due set reali → numeri "1" e "2" nella barra SET, mai "3"
        expect(html).toContain('<span class="set-numero">1</span>')
        expect(html).toContain('<span class="set-numero">2</span>')
        expect(html).not.toContain('<span class="set-numero">3</span>')
    })

    it('calcola il punteggio finale di ogni set dalla ris', () => {
        const striscia = [
            { serv: 'h', ris: 'h'.repeat(25) + 'g'.repeat(20), vinc: 'h' },
            { serv: 'h', ris: '', vinc: null },
        ]
        const html = buildRefertoHtml(statoConSet(striscia), NOW)
        // header del set: "Antoniana 25 · 20 Rivali"
        expect(html).toContain('<strong>25</strong>')
        expect(html).toContain('<strong>20</strong>')
    })

    it('conta i set vinti usando vinc', () => {
        const striscia = [
            { serv: 'h', ris: '', vinc: 'h' },
            { serv: 'g', ris: '', vinc: 'g' },
            { serv: 'h', ris: '', vinc: 'h' },
            { serv: 'h', ris: '', vinc: null },
        ]
        const html = buildRefertoHtml(statoConSet(striscia), NOW)
        // risultato 2 – 1
        expect(html).toContain('2 – 1')
    })

    it('ricava il vincitore dal conteggio punti se vinc è nullo', () => {
        const striscia = [
            { serv: 'h', ris: 'h'.repeat(25) + 'g'.repeat(23), vinc: null },
            { serv: 'h', ris: '', vinc: null },
        ]
        const html = buildRefertoHtml(statoConSet(striscia), NOW)
        // il primo set, pur con vinc null, conta come vinto da home → 1 – 0
        expect(html).toContain('1 – 0')
    })

    it('ricava il vincitore guest dal conteggio punti se vinc è nullo', () => {
        const striscia = [
            { serv: 'h', ris: 'g'.repeat(25) + 'h'.repeat(20), vinc: null },
        ]
        const html = buildRefertoHtml(statoConSet(striscia), NOW)
        // conteggio punti guest > home, pur con vinc null → 0 – 1
        expect(html).toContain('0 – 1')
    })

    it('include la progressione punto-punto con classi per squadra', () => {
        const striscia = [
            { serv: 'h', ris: 'hhg', vinc: null },
        ]
        const html = buildRefertoHtml(statoConSet(striscia), NOW)
        expect(html).toContain('punto-h')
        expect(html).toContain('punto-g')
        expect(html).toContain('1-0')
        expect(html).toContain('2-0')
        expect(html).toContain('2-1')
    })

    it('rende la formazione di partenza quando presente', () => {
        const striscia = [
            {
                serv: 'h', ris: 'h', vinc: null,
                formInizio: { home: ['4', '8', '15'], guest: ['16', '23', '42'] },
            },
        ]
        const html = buildRefertoHtml(statoConSet(striscia), NOW)
        expect(html).toContain('Formazione di partenza')
        expect(html).toContain('>4<')
        expect(html).toContain('>42<')
    })

    it('mostra "non disponibile" se manca formInizio', () => {
        const striscia = [{ serv: 'h', ris: 'h', vinc: null }]
        const html = buildRefertoHtml(statoConSet(striscia), NOW)
        expect(html).toContain('non disponibile')
    })

    it('mostra "Nessun punto registrato" per un set senza punti', () => {
        const striscia = [{ serv: 'h', ris: '', vinc: null }]
        const html = buildRefertoHtml(statoConSet(striscia), NOW)
        expect(html).toContain('Nessun punto registrato')
    })

    it('elenca time out e cambi del set con squadra e punteggio', () => {
        const striscia = [{
            serv: 'h', ris: 'hhhg', vinc: null,
            timeouts: [{ team: 'guest', punteggio: { home: 3, guest: 1 } }],
            cambi: [{ team: 'home', in: '10', out: '3', punteggio: { home: 2, guest: 0 } }],
        }]
        const html = buildRefertoHtml(statoConSet(striscia), NOW)
        expect(html).toContain('Cambi e time out')
        expect(html).toContain('Time out <strong>Rivali</strong> sul 3-1')
        expect(html).toContain('Cambio <strong>Antoniana</strong>: entra 10 per 3 sul 2-0')
    })

    it('ordina gli eventi per punteggio crescente', () => {
        const striscia = [{
            serv: 'h', ris: 'hhhgg', vinc: null,
            timeouts: [{ team: 'home', punteggio: { home: 3, guest: 2 } }],
            cambi: [{ team: 'guest', in: '9', out: '4', punteggio: { home: 1, guest: 0 } }],
        }]
        const html = buildRefertoHtml(statoConSet(striscia), NOW)
        const idxCambio = html.indexOf('entra 9 per 4')
        const idxTimeout = html.indexOf('Time out')
        expect(idxCambio).toBeGreaterThan(-1)
        expect(idxTimeout).toBeGreaterThan(-1)
        expect(idxCambio).toBeLessThan(idxTimeout)
    })

    it('omette la sezione eventi se il set non ne ha', () => {
        const striscia = [{ serv: 'h', ris: 'h', vinc: null }]
        const html = buildRefertoHtml(statoConSet(striscia), NOW)
        expect(html).not.toContain('Cambi e time out')
    })

    it('header contiene nomi squadre, modalità e data iniettata', () => {
        const striscia = [{ serv: 'h', ris: '', vinc: null }]
        const state = statoConSet(striscia)
        state.modalitaPartita = '2/3'
        const html = buildRefertoHtml(state, NOW)
        expect(html).toContain('Antoniana')
        expect(html).toContain('Rivali')
        expect(html).toContain('Modalità: 2/3')
        expect(html).toContain('14/03/2026')
    })
})
