export function initCockpit({ storage, toast }) {
const $ = s => document.querySelector(s), audio = $('#audio');
const dedicated = new URLSearchParams(location.search).get('display') === 'drive';
let collapsed = dedicated || storage.get('railCollapsed') === 'true';
function rail() {
document.body.classList.toggle('rail-collapsed', collapsed);
$('#rail-toggle').setAttribute('aria-expanded', String(!collapsed));
$('#rail-toggle').setAttribute('aria-label', collapsed ? 'Afficher les favoris' : 'Masquer les favoris');
document.dispatchEvent(new Event('caria-layout'));
}
$('#rail-toggle').onclick = () => { collapsed = !collapsed; storage.set('railCollapsed', String(collapsed)); rail(); };
document.querySelectorAll('.screen-links a').forEach(link => link.onclick = () => $('#settings').close());
rail();
if (dedicated && !location.hash) location.hash = 'drive';
const time = seconds => Number.isFinite(seconds) ? `${Math.floor(seconds / 60)}:${String(Math.floor(seconds % 60)).padStart(2,'0')}` : '0:00';
function updatePlayer() {
const duration = Number.isFinite(audio.duration) ? audio.duration : 0, progress = duration ? audio.currentTime / duration : 0;
$('#track-arc').style.strokeDashoffset = String(100 * (1 - progress));
$('#immersive-current').textContent = time(audio.currentTime); $('#immersive-duration').textContent = time(duration);
$('#immersive-title').textContent = $('#track-title').textContent;
$('#immersive-subtitle').textContent = $('#track-subtitle').textContent;
$('#immersive-play').innerHTML = audio.paused ? '' : '';
$('#immersive-play').setAttribute('aria-label', audio.paused ? 'Lire la musique' : 'Mettre en pause');
$('#now-playing').classList.toggle('playing', !audio.paused);
$('#immersive-volume').value = audio.muted ? '0' : String(audio.volume);
const silent = audio.muted || audio.volume === 0;
$('#immersive-mute').innerHTML = silent ? '' : '';
$('#immersive-mute').setAttribute('aria-label', silent ? 'Activer le son' : 'Couper le son');
$('#immersive-mute').title = silent ? 'Activer le son' : 'Couper le son';
$('#immersive-mute').setAttribute('aria-pressed', String(silent));
$('#immersive-volume-value').textContent = Math.round((silent ? 0 : audio.volume) * 100) + ' %';
document.querySelectorAll('[data-audio-control]').forEach(button => button.disabled = !audio.getAttribute('src'));
}
$('#immersive-play').onclick = () => $('#play').click();
$('#immersive-previous').onclick = () => $('#previous').click();
$('#immersive-next').onclick = () => $('#next').click();
$('#immersive-volume').oninput = e => { audio.volume = Number(e.target.value); audio.muted = false; };
$('#immersive-mute').onclick = () => { if (audio.volume === 0) { audio.volume = .5; audio.muted = false; } else audio.muted = !audio.muted; };
$('#immersive-repeat').onclick = () => { audio.loop = !audio.loop; $('#immersive-repeat').setAttribute('aria-pressed', String(audio.loop)); toast(audio.loop ? 'Répétition du morceau activée' : 'Répétition désactivée'); };
for (const event of ['timeupdate','loadedmetadata','durationchange','play','pause','volumechange','emptied','ended']) audio.addEventListener(event,updatePlayer);
new MutationObserver(updatePlayer).observe($('#track-title'),{childList:true,subtree:true});
audio.addEventListener('error', () => $('#immersive-subtitle').textContent = 'Lecture impossible. Choisissez un autre morceau dans la bibliothèque.');
updatePlayer();
// Keep lengthy setup panels reachable with large page buttons.
for (const panel of document.querySelectorAll('.journey-panel')) {
const content = document.createElement('div'), nav = document.createElement('nav');
content.className = 'panel-content'; nav.className = 'collection-pages panel-pages';
content.append(...panel.childNodes); panel.append(content,nav);
const back = document.createElement('button'), next = document.createElement('button'), label = document.createElement('span');
back.type = next.type = 'button'; back.textContent = '‹'; next.textContent = '›';
back.setAttribute('aria-label','Page précédente du panneau'); next.setAttribute('aria-label','Page suivante du panneau');
nav.append(back,label,next);
function refresh() {
if (!panel.getClientRects().length) return;
const max = content.scrollHeight - content.clientHeight;
nav.hidden = max <= 2;
back.disabled = content.scrollTop < 2; next.disabled = content.scrollTop >= max - 2;
label.textContent = max <= 2 ? '' : `${Math.floor(content.scrollTop / Math.max(1,content.clientHeight - 60)) + 1} / ${Math.ceil(max / Math.max(1,content.clientHeight - 60)) + 1}`;
}
back.onclick = () => { content.scrollTop -= Math.max(44,content.clientHeight - 60); refresh(); };
next.onclick = () => { content.scrollTop += Math.max(44,content.clientHeight - 60); refresh(); };
new ResizeObserver(refresh).observe(content);
new MutationObserver(refresh).observe(content,{childList:true,subtree:true,attributes:true,attributeFilter:['open','hidden']});
new MutationObserver(refresh).observe(panel,{attributes:true,attributeFilter:['open']});
content.addEventListener('scroll',refresh); document.addEventListener('caria-view',refresh);
}
// Paginate collections rather than shrinking touch targets or scrolling the screen.
for (const selector of ['#playlist', '.detail-grid', '.home-grid']) {
const container = $(selector), pager = document.createElement('nav');
pager.className = 'collection-pages'; pager.setAttribute('aria-label', 'Pages de contenu');
const back = document.createElement('button'), next = document.createElement('button'), label = document.createElement('span');
back.textContent = '‹'; next.textContent = '›';
back.setAttribute('aria-label', 'Page précédente'); next.setAttribute('aria-label', 'Page suivante');
pager.append(back,label,next); container.after(pager);
let page = 0;
function layout() {
if (!container.getClientRects().length) return;
const items = [...container.children], small = innerWidth < 760;
let count = items.length || 1;
if (selector === '#playlist') count = Math.max(1, Math.floor(container.clientHeight / 58));
if (selector === '.detail-grid') count = small || innerHeight < 750 ? 4 : 8;
if (selector === '.home-grid') count = small ? 2 : 4;
const pages = Math.max(1,Math.ceil(items.length / count)); page = Math.min(page,pages - 1);
items.forEach((item,i) => item.hidden = i < page * count || i >= (page + 1) * count);
pager.hidden = pages === 1; label.textContent = `${page + 1} / ${pages}`;
back.disabled = page === 0; next.disabled = page === pages - 1;
}
back.onclick = () => { page--; layout(); }; next.onclick = () => { page++; layout(); };
new ResizeObserver(layout).observe(container);
new MutationObserver(() => { page = 0; layout(); }).observe(container,{childList:true});
document.addEventListener('caria-view',layout); layout();
}
}