/**
 * Tests for components/checkbox_handler.js
 *
 * Tests the checkbox-hidden input fallback pattern that ensures
 * both checked and unchecked states are submitted in HTML forms.
 */

let handler;

beforeAll(async () => {
    await import('@js/components/checkbox_handler.js');
    handler = window.checkboxHandler;
});

describe('CheckboxHandler', () => {
    let form;

    beforeEach(() => {
        form = document.createElement('form');
        document.body.appendChild(form);
    });

    afterEach(() => {
        form.remove();
    });

    describe('setupCheckbox', () => {
        it('disables hidden input when checkbox is checked', () => {
            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.checked = true;
            checkbox.setAttribute('data-hidden-fallback', 'hidden-1');

            const hidden = document.createElement('input');
            hidden.type = 'hidden';
            hidden.id = 'hidden-1';
            hidden.value = 'false';

            form.appendChild(checkbox);
            form.appendChild(hidden);

            handler.setupCheckbox(checkbox);
            expect(hidden.disabled).toBe(true);
        });

        it('enables hidden input when checkbox is unchecked', () => {
            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.checked = false;
            checkbox.setAttribute('data-hidden-fallback', 'hidden-2');

            const hidden = document.createElement('input');
            hidden.type = 'hidden';
            hidden.id = 'hidden-2';
            hidden.value = 'false';

            form.appendChild(checkbox);
            form.appendChild(hidden);

            handler.setupCheckbox(checkbox);
            expect(hidden.disabled).toBe(false);
        });

        it('toggles hidden input on change event', () => {
            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.checked = false;
            checkbox.setAttribute('data-hidden-fallback', 'hidden-3');

            const hidden = document.createElement('input');
            hidden.type = 'hidden';
            hidden.id = 'hidden-3';

            form.appendChild(checkbox);
            form.appendChild(hidden);

            handler.setupCheckbox(checkbox);
            expect(hidden.disabled).toBe(false);

            checkbox.checked = true;
            checkbox.dispatchEvent(new Event('change'));
            expect(hidden.disabled).toBe(true);

            checkbox.checked = false;
            checkbox.dispatchEvent(new Event('change'));
            expect(hidden.disabled).toBe(false);
        });
    });

    describe('cleanup', () => {
        it('removes event listener from checkbox', () => {
            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.setAttribute('data-hidden-fallback', 'hidden-4');

            const hidden = document.createElement('input');
            hidden.type = 'hidden';
            hidden.id = 'hidden-4';

            form.appendChild(checkbox);
            form.appendChild(hidden);

            handler.setupCheckbox(checkbox);
            expect(checkbox._checkboxHandlerCleanup).toBeTypeOf('function');

            handler.cleanup(checkbox);
            expect(checkbox._checkboxHandlerCleanup).toBeUndefined();
        });
    });

    describe('prepareFormSubmission', () => {
        it('syncs all checkbox-hidden pairs before submit', () => {
            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.checked = true;
            checkbox.setAttribute('data-hidden-fallback', 'hidden-5');

            const hidden = document.createElement('input');
            hidden.type = 'hidden';
            hidden.id = 'hidden-5';
            hidden.disabled = false;

            form.appendChild(checkbox);
            form.appendChild(hidden);

            handler.prepareFormSubmission(form);
            expect(hidden.disabled).toBe(true);
        });
    });
});
