// Jasmine spec for my-sea-seats.js — the one-shot "seated" glow module
// (Phase B of the my-sea invite/voice sprint). Verifies the localStorage-
// gated first-view behaviour + the timed flare-class removal.
describe('my-sea-seats one-shot seated glow', function () {
    var seat;

    beforeEach(function () {
        window.localStorage.clear();
        seat = document.createElement('div');
        seat.className = 'table-seat seated';
        document.body.appendChild(seat);
    });

    afterEach(function () {
        if (seat && seat.parentNode) seat.parentNode.removeChild(seat);
        window.localStorage.clear();
    });

    it('exposes playSeatGlow globally', function () {
        expect(typeof window.playSeatGlow).toBe('function');
    });

    it('adds the seat-just-seated flare class', function () {
        window.playSeatGlow(seat);
        expect(seat.classList.contains('seat-just-seated')).toBe(true);
    });

    it('marks a tokened seat seen in localStorage', function () {
        seat.setAttribute('data-seat-token', 'visit-42');
        window.playSeatGlow(seat);
        expect(window.localStorage.getItem('mysea-seat-seen:visit-42')).toBe('1');
    });

    it('does not replay the flare for an already-seen token', function () {
        seat.setAttribute('data-seat-token', 'visit-42');
        window.localStorage.setItem('mysea-seat-seen:visit-42', '1');
        window.playSeatGlow(seat);
        expect(seat.classList.contains('seat-just-seated')).toBe(false);
    });

    it('always animates a tokenless seat (no persistence)', function () {
        window.playSeatGlow(seat);
        expect(seat.classList.contains('seat-just-seated')).toBe(true);
    });

    it('removes the flare class after the 2s glow window', function () {
        jasmine.clock().install();
        window.playSeatGlow(seat);
        expect(seat.classList.contains('seat-just-seated')).toBe(true);
        // Still flaring mid-window (bumped 1.5s → 2s, user-spec 2026-05-29).
        jasmine.clock().tick(1600);
        expect(seat.classList.contains('seat-just-seated')).toBe(true);
        jasmine.clock().tick(500);
        expect(seat.classList.contains('seat-just-seated')).toBe(false);
        jasmine.clock().uninstall();
    });
});

// mySeaRenderSeats — the shared seat-ring re-render driven by a `sea_seats`
// broadcast. Used by BOTH the owner's my_sea AND the spectator's my_sea_visit
// (DRY, 2026-05-30); each passes its own `myToken` to mark its own chair.
describe('my-sea-seats mySeaRenderSeats shared ring re-render', function () {
    var scene;

    beforeEach(function () {
        window.localStorage.clear();
        scene = document.createElement('div');
        scene.className = 'room-table-scene';
        document.body.appendChild(scene);
    });

    afterEach(function () {
        if (scene && scene.parentNode) scene.parentNode.removeChild(scene);
        window.localStorage.clear();
    });

    var SEATS = [
        { n: 1, label: '1C', present: true,  token: 'owner-9-3' },
        { n: 2, label: '2C', present: true,  token: 'visit-42' },
        { n: 3, label: '3C', present: false, token: '' },
    ];

    it('exposes mySeaRenderSeats globally', function () {
        expect(typeof window.mySeaRenderSeats).toBe('function');
    });

    it('rebuilds one .table-seat per seat with the present/seated state', function () {
        window.mySeaRenderSeats(SEATS, '');
        var seats = scene.querySelectorAll('.table-seat');
        expect(seats.length).toBe(3);
        expect(seats[0].classList.contains('seated')).toBe(true);
        expect(seats[2].classList.contains('seated')).toBe(false);
        // Present seats get the check icon; absent seats the ban icon.
        expect(seats[0].querySelector('.fa-circle-check')).not.toBeNull();
        expect(seats[2].querySelector('.fa-ban')).not.toBeNull();
        expect(seats[1].querySelector('.seat-position-label').textContent).toBe('2C');
    });

    it('marks only the seat matching myToken as --self', function () {
        window.mySeaRenderSeats(SEATS, 'visit-42');
        var self = scene.querySelectorAll('.table-seat--self');
        expect(self.length).toBe(1);
        expect(self[0].getAttribute('data-slot')).toBe('2');
    });

    it('marks no seat --self when myToken is empty (owner page)', function () {
        window.mySeaRenderSeats(SEATS, '');
        expect(scene.querySelectorAll('.table-seat--self').length).toBe(0);
    });

    it('clears prior seats before re-rendering (no duplicates)', function () {
        window.mySeaRenderSeats(SEATS, '');
        window.mySeaRenderSeats(SEATS, '');
        expect(scene.querySelectorAll('.table-seat').length).toBe(3);
    });

    it('flares freshly-seated tokened seats once (localStorage-gated)', function () {
        window.mySeaRenderSeats(SEATS, '');
        var owner = scene.querySelector('.table-seat[data-slot="1"]');
        expect(owner.classList.contains('seat-just-seated')).toBe(true);
        // Second render for the same token does not replay the flare.
        window.mySeaRenderSeats(SEATS, '');
        owner = scene.querySelector('.table-seat[data-slot="1"]');
        expect(owner.classList.contains('seat-just-seated')).toBe(false);
    });
});
