const CALL_SOUND_URL = '/sounds/header-sound.mp3';

let sharedAudio = null;
let unlocked = false;

function getCallAudio() {
    if (!sharedAudio) {
        sharedAudio = new Audio(CALL_SOUND_URL);
        sharedAudio.preload = 'auto';
    }
    return sharedAudio;
}

/**
 * Call once after a user gesture (click/tap) so later plays are allowed.
 */
export function unlockQueueCallSound() {
    if (unlocked) return;
    try {
        const audio = getCallAudio();
        audio.muted = true;
        const playPromise = audio.play();
        if (playPromise?.then) {
            playPromise
                .then(() => {
                    audio.pause();
                    audio.currentTime = 0;
                    audio.muted = false;
                    unlocked = true;
                })
                .catch(() => {
                    // Still mark unlocked so we keep trying on real calls.
                    audio.muted = false;
                    unlocked = true;
                });
        } else {
            audio.muted = false;
            unlocked = true;
        }
    } catch {
        unlocked = true;
    }
}

/**
 * Play the queue-call notification chime.
 * Safe to call repeatedly; restarts from the beginning each time.
 */
export function playQueueCallSound() {
    try {
        const audio = getCallAudio();
        audio.muted = false;
        audio.currentTime = 0;
        const playPromise = audio.play();
        if (playPromise?.catch) {
            playPromise.catch((error) => {
                console.warn('Could not play queue call sound:', error);
            });
        }
    } catch (error) {
        console.warn('Could not play queue call sound:', error);
    }
}

/**
 * Build a stable map of stationId -> ticket number for currently serving tickets.
 */
export function servingSnapshot(tickets) {
    const map = {};
    for (const ticket of tickets) {
        if (ticket?.station?.id != null && ticket?.number != null) {
            map[String(ticket.station.id)] = String(ticket.number);
        }
    }
    return map;
}

/**
 * Returns true if any station got a new/different ticket number vs the previous snapshot.
 */
export function hasNewServingCall(previous, next) {
    if (!previous) return false;
    for (const [stationId, number] of Object.entries(next)) {
        if (previous[stationId] !== number) {
            return true;
        }
    }
    return false;
}
