import { normalizePermissionQuery, permissionMatches } from '../services/permission-filter.js';

export class PermissionMatrix {
    constructor(root) {
        this.root = root;
        this.groups = [...root.querySelectorAll('[data-perm-group]')];
        this.bind();
        this.updateCounts();
    }

    bind() {
        this.root.querySelector('[data-perm-search]')?.addEventListener('input', (event) => {
            this.filter(normalizePermissionQuery(event.target.value));
        });
        this.root.querySelector('[data-perm-expand-all]')?.addEventListener('click', () => this.expandAll(true));
        this.root.querySelector('[data-perm-collapse-all]')?.addEventListener('click', () => this.expandAll(false));
        this.root.querySelector('[data-perm-select-visible]')?.addEventListener('click', () => this.setVisible(true));
        this.root.querySelector('[data-perm-clear-visible]')?.addEventListener('click', () => this.setVisible(false));
        this.root.addEventListener('change', (event) => {
            if (event.target.matches('[data-perm-checkbox]')) {
                this.updateCounts();
            }
        });
        this.groups.forEach((group) => this.bindGroup(group));
    }

    bindGroup(group) {
        group.querySelector('[data-perm-group-select]')?.addEventListener('click', () => {
            this.setGroup(group, true);
        });
        group.querySelector('[data-perm-group-clear]')?.addEventListener('click', () => {
            this.setGroup(group, false);
        });
    }

    filter(query) {
        this.groups.forEach((group) => {
            const rows = [...group.querySelectorAll('[data-perm-row]')];
            rows.forEach((row) => {
                row.hidden = !permissionMatches(row, query);
            });
            const visible = rows.some((row) => !row.hidden);
            group.hidden = !visible;
            if (query !== '' && visible) {
                this.setExpanded(group, true);
            }
        });
    }

    expandAll(expanded) {
        this.groups.filter((group) => !group.hidden).forEach((group) => {
            this.setExpanded(group, expanded);
        });
    }

    setExpanded(group, expanded) {
        group.querySelector('[data-perm-collapse]')?.classList.toggle('show', expanded);
        group.querySelector('[data-bs-toggle="collapse"]')?.setAttribute('aria-expanded', String(expanded));
    }

    setVisible(checked) {
        this.groups.filter((group) => !group.hidden).forEach((group) => {
            this.setGroup(group, checked, true);
        });
        this.updateCounts();
    }

    setGroup(group, checked, visibleOnly = false) {
        group.querySelectorAll('[data-perm-row]').forEach((row) => {
            if (!visibleOnly || !row.hidden) {
                row.querySelector('[data-perm-checkbox]').checked = checked;
            }
        });
        this.updateCounts();
    }

    updateCounts() {
        const all = [...this.root.querySelectorAll('[data-perm-checkbox]')];
        const selected = all.filter((checkbox) => checkbox.checked).length;
        const total = this.root.querySelector('[data-perm-total-count]');
        if (total) {
            total.textContent = `${selected} / ${all.length}`;
        }
        this.groups.forEach((group) => {
            const boxes = [...group.querySelectorAll('[data-perm-checkbox]')];
            const count = group.querySelector('[data-perm-group-count]');
            if (count) {
                count.textContent = `${boxes.filter((box) => box.checked).length} / ${boxes.length}`;
            }
        });
    }
}
