/**
 * Roles editor (F5 UI-102 + CRUD permissions 1.0.9+).
 */
(function () {
    'use strict';

    let roles = [];
    let permissionsCatalog = [];
    let editingRole = null;
    let permissionsReadonly = false;

    const GROUP_LABELS = {
        users: 'Пользователи',
        services: 'Сервисы',
        config: 'Конфигурация',
        monitoring: 'Мониторинг',
        plugins: 'Плагины',
        routing: 'Маршрутизация',
        content: 'Контент',
        market: 'Маркет',
        database: 'База данных',
        api: 'API Explorer',
        plugin_ports: 'Порты плагинов',
        mail: 'Почта',
        auth: 'Аутентификация',
        other: 'Прочее',
    };

    function escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text == null ? '' : String(text);
        return div.innerHTML;
    }

    function showAlert(message, type) {
        const alertDiv = document.createElement('div');
        alertDiv.className = 'alert alert-' + type + ' alert-dismissible fade show';
        alertDiv.innerHTML = message + '<button type="button" class="btn-close" data-bs-dismiss="alert"></button>';
        const container = document.querySelector('.container-fluid');
        if (container) container.insertBefore(alertDiv, container.firstChild);
        setTimeout(function () { alertDiv.remove(); }, 5000);
    }

    function isSystemRole(role) {
        if (!role) return false;
        if (role.is_system) return true;
        const t = (role.role_type || '').toLowerCase();
        return t === 'admin' || t === 'system' || t === 'super_admin';
    }

    async function loadPermissionsCatalog() {
        if (permissionsCatalog.length) return permissionsCatalog;
        const resp = await cascad360Fetch('/api/v1/admin/permissions');
        const data = await resp.json();
        if (!data.success) {
            throw new Error(data.error || 'Не удалось загрузить каталог разрешений');
        }
        permissionsCatalog = data.permissions || [];
        return permissionsCatalog;
    }

    function renderPermissionsMatrix(selected) {
        const container = document.getElementById('permissionsMatrix');
        const selectedSet = new Set(selected || []);
        const byGroup = {};
        permissionsCatalog.forEach(function (item) {
            const group = item.group || 'other';
            if (!byGroup[group]) byGroup[group] = [];
            byGroup[group].push(item);
        });
        const groups = Object.keys(byGroup).sort();
        if (!groups.length) {
            container.innerHTML = '<div class="text-muted">Каталог разрешений пуст</div>';
            return;
        }
        container.innerHTML = groups.map(function (group) {
            const title = GROUP_LABELS[group] || group;
            const items = byGroup[group].map(function (item) {
                const checked = selectedSet.has(item.id) ? ' checked' : '';
                const disabled = permissionsReadonly ? ' disabled' : '';
                return (
                    '<div class="col-md-6 col-lg-4">' +
                    '<div class="form-check">' +
                    '<input class="form-check-input perm-checkbox" type="checkbox" value="' +
                    escapeHtml(item.id) + '" id="perm_' + escapeHtml(item.id) + '"' + checked + disabled + '>' +
                    '<label class="form-check-label" for="perm_' + escapeHtml(item.id) + '">' +
                    escapeHtml(item.label) + '</label></div></div>'
                );
            }).join('');
            return (
                '<div class="mb-3">' +
                '<div class="fw-semibold mb-2">' + escapeHtml(title) + '</div>' +
                '<div class="row g-2">' + items + '</div></div>'
            );
        }).join('');
    }

    function collectSelectedPermissions() {
        const result = [];
        document.querySelectorAll('#permissionsMatrix .perm-checkbox:checked').forEach(function (el) {
            result.push(el.value);
        });
        return result;
    }

    async function loadRoles() {
        const tbody = document.getElementById('rolesTableBody');
        try {
            const resp = await cascad360Fetch('/api/v1/admin/roles');
            const data = await resp.json();
            if (!data.success) {
                tbody.innerHTML = '<tr><td colspan="6" class="text-danger">' + escapeHtml(data.error || 'Ошибка') + '</td></tr>';
                return;
            }
            roles = data.roles || [];
            if (!roles.length) {
                tbody.innerHTML = '<tr><td colspan="6" class="text-muted text-center">Нет ролей</td></tr>';
                return;
            }
            tbody.innerHTML = roles.map(function (r) {
                const policy = r.password_policy || {};
                const blocked = r.public_api_blocked
                    ? '<span class="badge bg-danger">Заблокирован</span>'
                    : '<span class="badge bg-success">Разрешён</span>';
                return (
                    '<tr>' +
                    '<td>' + r.id + '</td>' +
                    '<td><strong>' + escapeHtml(r.name) + '</strong></td>' +
                    '<td>' + escapeHtml(r.role_type || '—') + '</td>' +
                    '<td>' + blocked + '</td>' +
                    '<td>' + (policy.min_length || '—') + '</td>' +
                    '<td><button class="btn btn-sm btn-outline-primary edit-role-btn" data-id="' + r.id + '">' +
                    '<i class="bi bi-pencil"></i> Редактировать</button></td>' +
                    '</tr>'
                );
            }).join('');
            tbody.querySelectorAll('.edit-role-btn').forEach(function (btn) {
                btn.addEventListener('click', function () {
                    openEditModal(parseInt(btn.getAttribute('data-id'), 10));
                });
            });
        } catch (e) {
            tbody.innerHTML = '<tr><td colspan="6" class="text-danger">' + escapeHtml(e.message) + '</td></tr>';
        }
    }

    async function openEditModal(roleId) {
        const role = roles.find(function (r) { return r.id === roleId; });
        if (!role) return;
        editingRole = role;
        permissionsReadonly = isSystemRole(role);
        const policy = role.password_policy || {};
        document.getElementById('editRoleId').value = roleId;
        document.getElementById('editRoleName').textContent = role.name;
        document.getElementById('editRoleDescription').value = role.description || '';
        document.getElementById('editPolicyMinLength').value = policy.min_length || 8;
        document.getElementById('editPolicyRequireUpper').checked = !!policy.require_uppercase;
        document.getElementById('editPolicyRequireDigit').checked = !!policy.require_digit;
        document.getElementById('editPolicyRequireSpecial').checked = !!policy.require_special;
        document.getElementById('editPublicApiBlocked').checked = !!role.public_api_blocked;
        document.getElementById('permissionsReadonlyHint').style.display = permissionsReadonly ? '' : 'none';
        document.getElementById('deleteRoleBtn').style.display = permissionsReadonly ? 'none' : '';
        try {
            await loadPermissionsCatalog();
            renderPermissionsMatrix(role.permissions || []);
        } catch (e) {
            document.getElementById('permissionsMatrix').innerHTML =
                '<div class="text-danger">' + escapeHtml(e.message) + '</div>';
        }
        new bootstrap.Modal(document.getElementById('editRoleModal')).show();
    }

    async function saveRole() {
        const roleId = document.getElementById('editRoleId').value;
        const body = {
            description: document.getElementById('editRoleDescription').value.trim(),
            password_policy: {
                min_length: parseInt(document.getElementById('editPolicyMinLength').value, 10) || 8,
                require_uppercase: document.getElementById('editPolicyRequireUpper').checked,
                require_digit: document.getElementById('editPolicyRequireDigit').checked,
                require_special: document.getElementById('editPolicyRequireSpecial').checked,
            },
            public_api_blocked: document.getElementById('editPublicApiBlocked').checked,
        };
        if (!permissionsReadonly) {
            body.permissions = collectSelectedPermissions();
        }
        const resp = await cascad360Fetch('/api/v1/admin/roles/' + roleId, {
            method: 'PATCH',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(body),
        });
        const data = await resp.json();
        if (!data.success) {
            showAlert(data.error || 'Ошибка сохранения', 'danger');
            return;
        }
        bootstrap.Modal.getInstance(document.getElementById('editRoleModal')).hide();
        showAlert('Роль обновлена', 'success');
        loadRoles();
    }

    async function createRole() {
        const name = document.getElementById('createRoleName').value.trim();
        if (!name) {
            showAlert('Укажите имя роли', 'warning');
            return;
        }
        const body = {
            name: name,
            description: document.getElementById('createRoleDescription').value.trim(),
            role_type: document.getElementById('createRoleType').value,
            permissions: [],
        };
        const resp = await cascad360Fetch('/api/v1/admin/roles', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(body),
        });
        const data = await resp.json();
        if (!data.success) {
            showAlert(data.error || 'Ошибка создания роли', 'danger');
            return;
        }
        bootstrap.Modal.getInstance(document.getElementById('createRoleModal')).hide();
        showAlert('Роль создана', 'success');
        await loadRoles();
        if (data.role && data.role.id) {
            openEditModal(data.role.id);
        }
    }

    async function deleteRole() {
        if (!editingRole || isSystemRole(editingRole)) return;
        if (!confirm('Удалить роль «' + editingRole.name + '»?')) return;
        const resp = await cascad360Fetch('/api/v1/admin/roles/' + editingRole.id, {
            method: 'DELETE',
        });
        const data = await resp.json();
        if (!data.success) {
            showAlert(data.error || 'Не удалось удалить роль', 'danger');
            return;
        }
        bootstrap.Modal.getInstance(document.getElementById('editRoleModal')).hide();
        showAlert('Роль удалена', 'success');
        editingRole = null;
        loadRoles();
    }

    document.addEventListener('DOMContentLoaded', function () {
        loadRoles();
        document.getElementById('saveRoleBtn').addEventListener('click', saveRole);
        document.getElementById('createRoleBtn').addEventListener('click', function () {
            document.getElementById('createRoleName').value = '';
            document.getElementById('createRoleDescription').value = '';
            document.getElementById('createRoleType').value = 'custom';
            new bootstrap.Modal(document.getElementById('createRoleModal')).show();
        });
        document.getElementById('confirmCreateRoleBtn').addEventListener('click', createRole);
        document.getElementById('deleteRoleBtn').addEventListener('click', deleteRole);
    });
})();
