/**
 * Isolated active-tag-filter state for the Actualité Hub grid.
 *
 * ENGINEERING ASSUMPTION (flagged, not PO-confirmed — see
 * spec-driven-development/2026-07-11-actualite-hub-page-template.md, "Assumption Flagged"):
 * this implements **multi-tag OR** semantics — clicking a pill toggles its membership in the
 * active set, and a card is visible if it has AT LEAST ONE active tag. If the PO overrules
 * this in favor of single-select/exclusive ("tab") behavior, this class is the ONLY piece
 * that needs to change (toggle() would replace the set instead of toggling membership) — the
 * DOM-query/render code in ActualiteHubFilter does not need to change.
 */
export class ActualiteHubFilterState {
    private readonly activeTags: Set<string> = new Set();

    /**
     * Toggles a tag's membership in the active set (multi-tag OR semantics).
     */
    public toggle(tagSlug: string): void {
        if (this.activeTags.has(tagSlug)) {
            this.activeTags.delete(tagSlug);
        } else {
            this.activeTags.add(tagSlug);
        }
    }

    /**
     * Clears the active set entirely ("Tous"/"All" reset).
     */
    public reset(): void {
        this.activeTags.clear();
    }

    public isActive(tagSlug: string): boolean {
        return this.activeTags.has(tagSlug);
    }

    public isEmpty(): boolean {
        return this.activeTags.size === 0;
    }

    /**
     * A card is visible if the filter set is empty (no filter active / "Tous"), or if the
     * card's own tags intersect the active set (OR semantics).
     */
    public matches(cardTagSlugs: readonly string[]): boolean {
        if (this.isEmpty()) {
            return true;
        }

        return cardTagSlugs.some(slug => this.activeTags.has(slug));
    }
}
