/**
 * ThemeToggle Component
 *
 * Switches the site color theme (light/dark) and persists the choice in
 * localStorage. Multiple instances of the toggle can exist on the page
 * (header + footer) — all are kept in sync.
 *
 * The theme is also written to a `theme` cookie so the server can render the right
 * themed image (`components/_themed_img.html.twig`) on first paint; `img[data-src-dark]`
 * elements are swapped here when the theme changes without a reload.
 */
const STORAGE_KEY = 'theme';
const COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
type Theme = 'light' | 'dark';

/** Fired on <document> whenever the theme changes, so scroll-driven effects
 *  that cache computed colors (e.g. GSAP tweens) can recompute them. */
export const THEME_CHANGE_EVENT = 'galta:theme-change';

export class ThemeToggle {
    private buttons: NodeListOf<HTMLElement>;

    constructor() {
        this.buttons = document.querySelectorAll('.theme-toggle__btn[data-theme]');

        this.init();
    }

    private init(): void {
        if (this.buttons.length === 0) {
            return;
        }

        this.buttons.forEach((btn: HTMLElement) => {
            btn.addEventListener('click', () => {
                const theme = btn.dataset.theme as Theme | undefined;
                if (theme) {
                    this.applyTheme(theme);
                }
            });
        });

        // Existing visitors have the theme in localStorage but no cookie yet: the server
        // rendered the Été images, so catch up once here.
        this.syncThemedImages(this.getCurrentTheme());
        this.updateActiveState(this.getCurrentTheme());
    }

    private getCurrentTheme(): Theme {
        return document.documentElement.dataset.theme === 'dark' ? 'dark' : 'light';
    }

    private applyTheme(theme: Theme): void {
        document.documentElement.dataset.theme = theme;
        localStorage.setItem(STORAGE_KEY, theme);
        this.syncThemedImages(theme);
        this.updateActiveState(theme);
        document.dispatchEvent(new CustomEvent<Theme>(THEME_CHANGE_EVENT, { detail: theme }));
    }

    private updateActiveState(theme: Theme): void {
        this.buttons.forEach((btn: HTMLElement) => {
            const isActive = btn.dataset.theme === theme;
            btn.classList.toggle('theme-toggle__btn--active', isActive);
            btn.setAttribute('aria-pressed', String(isActive));
        });
    }

    private syncThemedImages(theme: Theme): void {
        document.cookie = `${STORAGE_KEY}=${theme}; path=/; max-age=${COOKIE_MAX_AGE_SECONDS}; SameSite=Lax`;

        document.querySelectorAll<HTMLImageElement>('img[data-src-dark]').forEach((img: HTMLImageElement) => {
            const src = theme === 'dark' ? img.dataset.srcDark : img.dataset.srcLight;
            if (src && img.getAttribute('src') !== src) {
                img.src = src;
            }
        });
    }
}
