(function () {
    'use strict';

    function parseJson(id, fallback) {
        var node = document.getElementById(id);
        if (!node) return fallback;

        try {
            return JSON.parse(node.textContent || '');
        } catch (error) {
            return fallback;
        }
    }

    function isArabic() {
        return document.documentElement.lang === 'ar';
    }

    function text(en, ar) {
        return isArabic() ? ar : en;
    }

    function roleName(role) {
        if (!role) {
            return text('Existing access', 'الصلاحيات الحالية');
        }

        return String(
            role[isArabic() ? 'name_ar' : 'name_en']
            || role.role_code
            || ''
        );
    }

    function roleDescription(role) {
        if (!role) {
            return text(
                'No managed role. Existing dashboard access remains.',
                'لا يوجد دور مُدار، وتستمر صلاحيات لوحة المعلومات الحالية.'
            );
        }

        return String(
            role[isArabic() ? 'description_ar' : 'description_en']
            || (
                role.policy_mode === 'ALL_BUSINESS'
                    ? text(
                        'All business pages automatically.',
                        'جميع صفحات العمل تلقائيًا.'
                    )
                    : text(
                        'Only the selected pages are allowed.',
                        'يُسمح بالصفحات المحددة فقط.'
                    )
            )
        );
    }

    function initializeTabs(page) {
        var tabs = Array.prototype.slice.call(
            page.querySelectorAll('[data-acl142-tab]')
        );
        var sections = Array.prototype.slice.call(
            page.querySelectorAll('[data-acl142-section]')
        );

        function activate(name, updateHash) {
            tabs.forEach(function (button) {
                button.classList.toggle(
                    'is-active',
                    button.getAttribute('data-acl142-tab') === name
                );
            });

            sections.forEach(function (section) {
                section.classList.toggle(
                    'is-active',
                    section.getAttribute('data-acl142-section') === name
                );
            });

            if (updateHash && window.history && window.history.replaceState) {
                window.history.replaceState(null, '', '#access-' + name);
            }
        }

        tabs.forEach(function (button) {
            button.addEventListener('click', function () {
                activate(
                    button.getAttribute('data-acl142-tab') || 'users',
                    true
                );
            });
        });

        var requested = String(window.location.hash || '')
            .replace('#access-', '');

        activate(
            ['users', 'roles', 'audit'].indexOf(requested) !== -1
                ? requested
                : 'users',
            false
        );

        return tabs.length;
    }

    function initializeUsers(page, roleMap) {
        var assignmentMap = parseJson('acl142_assignment_map', {});
        var buttons = Array.prototype.slice.call(
            page.querySelectorAll('[data-acl142-user]')
        );
        var search = page.querySelector('[data-acl142-user-search]');
        var noUsers = page.querySelector('[data-acl142-no-users]');
        var form = page.querySelector('[data-acl142-user-form]');

        if (!form) {
            return {count: buttons.length, editorReady: false};
        }

        var currentUsername = String(
            page.getAttribute('data-current-user') || ''
        ).toUpperCase();
        var usernameInput = form.querySelector('[data-acl142-username]');
        var emptyEditor = form.querySelector('[data-acl142-empty-editor]');
        var content = form.querySelector('[data-acl142-editor-content]');
        var selectedUsername = form.querySelector('[data-acl142-selected-username]');
        var currentRole = form.querySelector('[data-acl142-current-role]');
        var roleSelect = form.querySelector('[data-acl142-user-role]');
        var roleDescriptionNode = form.querySelector(
            '[data-acl142-user-role-description]'
        );
        var branchBlock = form.querySelector('[data-acl142-branch-block]');
        var branchModes = Array.prototype.slice.call(
            form.querySelectorAll('[data-acl142-branch-mode]')
        );
        var branchChecks = form.querySelector('[data-acl142-branch-checks]');
        var branches = Array.prototype.slice.call(
            form.querySelectorAll('[data-acl142-branch]')
        );
        var previewRole = form.querySelector('[data-acl142-preview-role]');
        var previewBranches = form.querySelector('[data-acl142-preview-branches]');

        function selectedBranchMode() {
            var selected = branchModes.filter(function (input) {
                return input.checked;
            })[0];

            return selected ? String(selected.value || 'ALL') : 'ALL';
        }

        function selectedBranches() {
            return branches.filter(function (input) {
                return input.checked;
            }).map(function (input) {
                return String(input.value || '');
            });
        }

        function branchPreview(roleCode, mode, selected) {
            if (roleCode === '') {
                return text(
                    'Existing branch access remains.',
                    'يستمر نطاق الفروع الحالي.'
                );
            }

            if (roleCode === 'SITE_ADMIN' || mode === 'ALL') {
                return text(
                    'All active branches.',
                    'جميع الفروع النشطة.'
                );
            }

            if (selected.length === 0) {
                return text('No branch selected.', 'لم يتم اختيار فرع.');
            }

            return selected.map(function (code) {
                return code === 'mnh' ? 'Madina' : 'New Jeddah';
            }).join(' · ');
        }

        function refreshUserEditor() {
            var roleCode = String(roleSelect.value || '');
            var role = roleMap[roleCode] || null;
            var roleIsManaged = roleCode !== '';
            var isSiteAdmin = roleCode === 'SITE_ADMIN';
            var mode = selectedBranchMode();

            roleDescriptionNode.textContent = roleDescription(role);

            branchBlock.classList.toggle(
                'is-disabled',
                !roleIsManaged || isSiteAdmin
            );

            branchModes.forEach(function (input) {
                input.disabled = !roleIsManaged || isSiteAdmin;
            });

            if (!roleIsManaged || isSiteAdmin) {
                branchModes.forEach(function (input) {
                    input.checked = input.value === 'ALL';
                });
                mode = 'ALL';
            }

            var selectedMode = roleIsManaged
                && !isSiteAdmin
                && mode === 'SELECTED';

            branchChecks.classList.toggle('is-active', selectedMode);

            branches.forEach(function (input) {
                input.disabled = !selectedMode;
            });

            previewRole.textContent = roleName(role);
            previewBranches.textContent = branchPreview(
                roleCode,
                mode,
                selectedBranches()
            );
        }

        function selectUser(button) {
            buttons.forEach(function (item) {
                item.classList.toggle('is-active', item === button);
            });

            var username = String(
                button.getAttribute('data-username') || ''
            );
            var assignment = assignmentMap[username.toUpperCase()] || {
                role_code: '',
                branches: []
            };
            var roleCode = String(assignment.role_code || '');
            var assignedBranches = Array.isArray(assignment.branches)
                ? assignment.branches
                : [];

            usernameInput.value = username;
            selectedUsername.textContent = username;
            currentRole.textContent = roleName(roleMap[roleCode] || null);
            emptyEditor.hidden = true;
            content.hidden = false;

            roleSelect.value = roleMap[roleCode] ? roleCode : '';

            var allBranches = assignedBranches.indexOf('*') !== -1
                || assignedBranches.length === 0;

            branchModes.forEach(function (input) {
                input.checked = input.value === (
                    allBranches ? 'ALL' : 'SELECTED'
                );
            });

            branches.forEach(function (input) {
                input.checked = assignedBranches.indexOf(input.value) !== -1;
            });

            refreshUserEditor();
        }

        buttons.forEach(function (button) {
            button.addEventListener('click', function () {
                selectUser(button);
            });
        });

        roleSelect.addEventListener('change', refreshUserEditor);
        branchModes.forEach(function (input) {
            input.addEventListener('change', refreshUserEditor);
        });
        branches.forEach(function (input) {
            input.addEventListener('change', refreshUserEditor);
        });

        if (search) {
            search.addEventListener('input', function () {
                var query = String(search.value || '').toLowerCase().trim();
                var visible = 0;

                buttons.forEach(function (button) {
                    var value = String(
                        button.getAttribute('data-search') || ''
                    );
                    var match = query === '' || value.indexOf(query) !== -1;

                    button.hidden = !match;
                    if (match) visible++;
                });

                if (noUsers) {
                    noUsers.hidden = visible !== 0;
                }
            });
        }

        var preferred = buttons.filter(function (button) {
            return String(
                button.getAttribute('data-username') || ''
            ).toUpperCase() === currentUsername;
        })[0] || buttons[0];

        if (preferred) {
            selectUser(preferred);
        } else {
            emptyEditor.hidden = false;
            content.hidden = true;
        }

        return {count: buttons.length, editorReady: !!usernameInput};
    }

    function initializeRoles(page, roleMap, permissionMap) {
        var form = page.querySelector('[data-acl142-role-form]');
        var roleButtons = Array.prototype.slice.call(
            page.querySelectorAll('[data-acl142-role]')
        );
        var newRoleButton = page.querySelector('[data-acl142-new-role]');

        if (!form) {
            return {
                count: roleButtons.length,
                editorReady: false,
                permissionCount: 0
            };
        }

        var requestedRole = String(
            page.getAttribute('data-requested-role') || ''
        );
        var isNewInput = form.querySelector('[data-acl142-is-new-role]');
        var policyValue = form.querySelector('[data-acl142-policy-value]');
        var allBranchesValue = form.querySelector(
            '[data-acl142-all-branches-value]'
        );
        var activeValue = form.querySelector('[data-acl142-active-value]');
        var codeInput = form.querySelector('[data-acl142-role-code]');
        var nameEn = form.querySelector('[data-acl142-role-name-en]');
        var nameAr = form.querySelector('[data-acl142-role-name-ar]');
        var descriptionEn = form.querySelector(
            '[data-acl142-role-description-en]'
        );
        var descriptionAr = form.querySelector(
            '[data-acl142-role-description-ar]'
        );
        var policySelect = form.querySelector('[data-acl142-policy-select]');
        var allBranchesToggle = form.querySelector(
            '[data-acl142-all-branches-toggle]'
        );
        var activeToggle = form.querySelector('[data-acl142-active-toggle]');
        var editorLabel = form.querySelector(
            '[data-acl142-role-editor-label]'
        );
        var editorTitle = form.querySelector(
            '[data-acl142-role-editor-title]'
        );
        var editorMeta = form.querySelector('[data-acl142-role-editor-meta]');
        var protection = form.querySelector('[data-acl142-role-protection]');
        var permissionCards = Array.prototype.slice.call(
            form.querySelectorAll('[data-acl142-permission]')
        );
        var permissionSwitches = Array.prototype.slice.call(
            form.querySelectorAll('[data-acl142-permission-switch]')
        );
        var allowedCount = form.querySelector('[data-acl142-allowed-count]');
        var saveButton = form.querySelector('[data-acl142-save-role]');
        var cancelButton = form.querySelector('[data-acl142-cancel-new-role]');
        var currentRoleCode = '';

        function businessCategory(category) {
            return ['business', 'reporting', 'workflow']
                .indexOf(category) !== -1;
        }

        function baseAllowed(policy, category) {
            return policy === 'ALL_BUSINESS' && businessCategory(category);
        }

        function effectiveAllowed(role, permissionCode) {
            if (!role) return false;
            if (role.role_code === 'SITE_ADMIN') return true;

            var contract = permissionMap[permissionCode] || {};
            var allowed = baseAllowed(
                role.policy_mode,
                String(contract.category || 'business')
            );
            var effect = String(
                (role.overrides && role.overrides[permissionCode]) || ''
            ).toUpperCase();

            if (effect === 'ALLOW') return true;
            if (effect === 'DENY') return false;

            return allowed;
        }

        function updatePermissionCard(card) {
            var input = card.querySelector(
                '[data-acl142-permission-switch]'
            );
            var state = card.querySelector(
                '[data-acl142-permission-state]'
            );
            if (!input || !state) return;

            card.classList.toggle('is-allowed', input.checked);
            card.classList.toggle('is-blocked', !input.checked);
            state.textContent = input.checked
                ? text('Allowed', 'مسموح')
                : text('Blocked', 'ممنوع');
        }

        function refreshRoleSettings() {
            policyValue.value = String(policySelect.value || 'EXPLICIT');
            allBranchesValue.value = allBranchesToggle.checked ? '1' : '0';
            activeValue.value = activeToggle.checked ? '1' : '0';

            permissionCards.forEach(updatePermissionCard);

            allowedCount.textContent = String(
                permissionSwitches.filter(function (input) {
                    return input.checked;
                }).length
            );
        }

        function setReadOnly(readOnly) {
            [
                nameEn,
                nameAr,
                descriptionEn,
                descriptionAr,
                policySelect,
                allBranchesToggle,
                activeToggle
            ].forEach(function (field) {
                field.disabled = readOnly;
            });

            permissionSwitches.forEach(function (input) {
                input.disabled = readOnly;
            });

            saveButton.hidden = readOnly;
        }

        function fillRole(roleCode) {
            var role = roleMap[roleCode];
            if (!role) return;

            currentRoleCode = roleCode;
            isNewInput.value = '0';

            roleButtons.forEach(function (button) {
                button.classList.toggle(
                    'is-active',
                    button.getAttribute('data-role-code') === roleCode
                );
            });

            codeInput.value = role.role_code;
            codeInput.readOnly = true;
            nameEn.value = role.name_en || '';
            nameAr.value = role.name_ar || '';
            descriptionEn.value = role.description_en || '';
            descriptionAr.value = role.description_ar || '';
            policySelect.value = role.policy_mode || 'EXPLICIT';
            allBranchesToggle.checked = Number(role.all_branches || 0) === 1;
            activeToggle.checked = Number(role.is_active || 0) === 1;

            editorLabel.textContent = text('EDIT ROLE', 'تعديل الدور');
            editorTitle.textContent = roleName(role);
            editorMeta.textContent = String(role.user_count || 0)
                + ' '
                + text('assigned users', 'مستخدم مرتبط');

            var siteAdmin = roleCode === 'SITE_ADMIN';
            var generalManager = roleCode === 'GENERAL_MANAGER';

            if (siteAdmin) {
                protection.textContent = text(
                    'Protected · Full access',
                    'محمي · صلاحيات كاملة'
                );
            } else if (generalManager) {
                protection.textContent = text(
                    'Protected · Editable access',
                    'محمي · الصلاحيات قابلة للتعديل'
                );
            } else {
                protection.textContent = Number(role.is_active || 0) === 1
                    ? text('Custom role', 'دور مخصص')
                    : text('Inactive role', 'دور موقوف');
            }

            permissionSwitches.forEach(function (input) {
                input.checked = effectiveAllowed(
                    role,
                    input.closest('[data-acl142-permission]')
                        .getAttribute('data-permission-code')
                );
            });

            setReadOnly(siteAdmin);

            if (!siteAdmin) {
                nameEn.disabled = false;
                nameAr.disabled = false;
                descriptionEn.disabled = false;
                descriptionAr.disabled = false;
                allBranchesToggle.disabled = false;
                permissionSwitches.forEach(function (input) {
                    input.disabled = false;
                });
                policySelect.disabled = generalManager;
                activeToggle.disabled = generalManager;
                saveButton.hidden = false;
            }

            cancelButton.hidden = true;
            refreshRoleSettings();
        }

        function generateCode(value) {
            var code = String(value || '')
                .toUpperCase()
                .replace(/[^A-Z0-9]+/g, '_')
                .replace(/^_+|_+$/g, '');

            if (!code) code = 'CUSTOM_ROLE';
            if (!/^[A-Z]/.test(code)) code = 'ROLE_' + code;

            return code.substring(0, 50);
        }

        function startNewRole() {
            currentRoleCode = '';

            roleButtons.forEach(function (button) {
                button.classList.remove('is-active');
            });

            isNewInput.value = '1';
            codeInput.value = '';
            codeInput.readOnly = false;
            codeInput.setAttribute('data-auto-code', '1');
            nameEn.value = '';
            nameAr.value = '';
            descriptionEn.value = '';
            descriptionAr.value = '';
            policySelect.value = 'EXPLICIT';
            allBranchesToggle.checked = false;
            activeToggle.checked = true;
            protection.textContent = text(
                'New custom role',
                'دور مخصص جديد'
            );
            editorLabel.textContent = text('NEW ROLE', 'دور جديد');
            editorTitle.textContent = text('Create a role', 'إنشاء دور');
            editorMeta.textContent = text(
                'Choose the pages this role can access.',
                'حدد الصفحات التي يستطيع الدور الوصول إليها.'
            );

            setReadOnly(false);
            permissionSwitches.forEach(function (input) {
                input.checked = false;
                input.disabled = false;
            });

            cancelButton.hidden = false;
            saveButton.hidden = false;
            refreshRoleSettings();
            nameEn.focus();
        }

        roleButtons.forEach(function (button) {
            button.addEventListener('click', function () {
                fillRole(
                    String(button.getAttribute('data-role-code') || '')
                );
            });
        });

        if (newRoleButton) {
            newRoleButton.addEventListener('click', startNewRole);
        }

        if (cancelButton) {
            cancelButton.addEventListener('click', function () {
                fillRole(
                    currentRoleCode
                    || requestedRole
                    || Object.keys(roleMap)[0]
                );
            });
        }

        nameEn.addEventListener('input', function () {
            if (
                isNewInput.value === '1'
                && codeInput.getAttribute('data-auto-code') === '1'
            ) {
                codeInput.value = generateCode(nameEn.value);
            }
        });

        codeInput.addEventListener('input', function () {
            codeInput.value = generateCode(codeInput.value);
            codeInput.setAttribute('data-auto-code', '0');
        });

        policySelect.addEventListener('change', function () {
            var policy = String(policySelect.value || 'EXPLICIT');

            permissionCards.forEach(function (card) {
                var input = card.querySelector(
                    '[data-acl142-permission-switch]'
                );
                var category = String(
                    card.getAttribute('data-permission-category') || 'business'
                );

                input.checked = baseAllowed(policy, category);
            });

            refreshRoleSettings();
        });

        allBranchesToggle.addEventListener('change', refreshRoleSettings);
        activeToggle.addEventListener('change', refreshRoleSettings);

        permissionSwitches.forEach(function (input) {
            input.addEventListener('change', refreshRoleSettings);
        });

        fillRole(
            roleMap[requestedRole]
                ? requestedRole
                : Object.keys(roleMap)[0]
        );

        return {
            count: roleButtons.length,
            editorReady: !!codeInput,
            permissionCount: permissionSwitches.length
        };
    }

    function initialize() {
        var page = document.querySelector('[data-acl142-page]');
        if (!page) return;

        var roleMap = parseJson('acl142_role_map', {});
        var permissionMap = parseJson('acl142_permission_map', {});

        var tabs = initializeTabs(page);
        var users = initializeUsers(page, roleMap);
        var roles = initializeRoles(page, roleMap, permissionMap);

        var gate = {
            tabs: tabs,
            users: users.count,
            userEditorReady: users.editorReady,
            roles: roles.count,
            roleEditorReady: roles.editorReady,
            permissionSwitches: roles.permissionCount,
            status:
                tabs === 3
                && users.count > 0
                && users.editorReady
                && roles.count >= 2
                && roles.editorReady
                && roles.permissionCount > 0
                    ? 'PASS'
                    : 'FAIL'
        };

        window.__DDB_ACCESS_CONTROL_P14_2_BROWSER_GATE__ = gate;

        document.documentElement.setAttribute(
            'data-access-control-p14-2-browser-gate',
            gate.status
        );
    }

    if (document.readyState === 'loading') {
        document.addEventListener(
            'DOMContentLoaded',
            initialize,
            {once: true}
        );
    } else {
        initialize();
    }
})();
