<script>
    let { roles = [], permissions = {}, adminPath = 'loom', status = null, errors = [] } = $props();

    let displayRoles = $state([]);
    $effect(() => {
        displayRoles = roles;
    });
    let savingPermission = $state(false);

    let newRoleName = $state('');
    let newRoleSlug = $state('');
    let newRoleDescription = $state('');

    let editingRole = $state(null);
    let editRoleName = $state('');
    let editRoleSlug = $state('');
    let editRoleDescription = $state('');

    // Convert grouped permissions to a flat list for easier processing
    let allPermissions = $derived(Object.values(permissions).flat());
    let groupedPermissions = $derived(permissions);

    async function togglePermission(roleId, permId, isActive) {
        savingPermission = true;
        try {
            const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
            const baseUrl = window.location.origin.endsWith('/') ? window.location.origin : `${window.location.origin}/`;
            const path = adminPath.startsWith('/') ? adminPath.substring(1) : adminPath;
            const url = `${baseUrl}${path}/roles/${roleId}/permissions`;

            const formData = new FormData();
            formData.append('_token', csrfToken);
            formData.append('permission_id', permId);
            if (isActive) {
                formData.append('active', 'on');
            }

            const response = await fetch(url, {
                method: 'POST',
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    'Accept': 'application/json'
                },
                body: formData
            });

            const data = await response.json();
            if (data.success && data.role) {
                // Update local state
                const index = displayRoles.findIndex(r => r.id === roleId);
                if (index !== -1) {
                    displayRoles[index] = data.role;
                }
            } else if (data.errors) {
                alert(data.errors.join('\n'));
            }
        } catch (error) {
            console.error('Failed to update permission:', error);
            alert('Failed to update permission. Please try again.');
        } finally {
            savingPermission = false;
        }
    }

    function handleNameInput(e) {
        newRoleSlug = e.target.value.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '');
    }

    function handleEditNameInput(e) {
        editRoleSlug = e.target.value.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '');
    }

    function startEditing(role) {
        editingRole = role;
        editRoleName = role.name;
        editRoleSlug = role.slug;
        editRoleDescription = role.description || '';
    }

    function cancelEditing() {
        editingRole = null;
    }

    function deleteRole(id, name) {
        if (confirm(`Are you sure you want to delete the role "${name}"? This cannot be undone.`)) {
            const form = document.createElement('form');
            form.method = 'POST';
            const baseUrl = window.location.origin.endsWith('/') ? window.location.origin : `${window.location.origin}/`;
            const path = adminPath.startsWith('/') ? adminPath.substring(1) : adminPath;
            const url = `${baseUrl}${path}/roles/${id}`;
            form.action = url;

            const methodInput = document.createElement('input');
            methodInput.type = 'hidden';
            methodInput.name = '_method';
            methodInput.value = 'DELETE';

            const tokenInput = document.createElement('input');
            tokenInput.type = 'hidden';
            tokenInput.name = '_token';
            tokenInput.value = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

            form.appendChild(methodInput);
            form.appendChild(tokenInput);
            document.body.appendChild(form);
            form.submit();
        }
    }

    function updatePermissions(roleId) {
        const form = document.getElementById(`perms-form-${roleId}`);
        form.submit();
    }

    function checkboxAction(node) {
        if (typeof jQuery !== 'undefined') {
            jQuery(node).checkbox({
                onChange: function() {
                    const input = node.querySelector('input');
                    const [_, roleId, permId] = input.id.split('-');
                    togglePermission(parseInt(roleId), parseInt(permId), input.checked);
                }
            });
        }
    }
</script>

<div class="ui container">
    <div class="ui grid">
        <div class="sixteen wide column">
            <h1 class="ui header">
                <i class="shield alternate icon"></i>
                <div class="content">
                    Roles & Permissions
                    <div class="sub header">Define roles and assign granular authorizations to them</div>
                </div>
                {#if savingPermission}
                    <div class="ui active mini inline loader" style="margin-left: 10px;"></div>
                {/if}
            </h1>
        </div>

        <div class="sixteen wide column">
            {#if status}
                <div class="ui positive message">
                    <i class="close icon"></i>
                    <p>{status}</p>
                </div>
            {/if}

            {#if errors && errors.length > 0}
                <div class="ui negative message">
                    <i class="close icon"></i>
                    <ul class="list">
                        {#each errors as error}
                            <li>{error}</li>
                        {/each}
                    </ul>
                </div>
            {/if}
        </div>

        <div class="six wide column">
            {#if editingRole}
                <div class="ui blue segment">
                    <h3 class="ui header">Edit Role: {editingRole.name}</h3>
                    <form class="ui form" method="POST" action="{window.location.origin.endsWith('/') ? window.location.origin : window.location.origin + '/'}{adminPath.startsWith('/') ? adminPath.substring(1) : adminPath}/roles/{editingRole.id}">
                        <input type="hidden" name="_token" value={document.querySelector('meta[name="csrf-token"]').getAttribute('content')}>
                        <input type="hidden" name="_method" value="PUT">
                        <div class="field required">
                            <label for="edit_name">Role Name</label>
                            <input id="edit_name" type="text" name="name" bind:value={editRoleName} oninput={handleEditNameInput} placeholder="Editor" required>
                        </div>
                        <div class="field required">
                            <label for="edit_slug">Slug</label>
                            <input id="edit_slug" type="text" name="slug" bind:value={editRoleSlug} placeholder="editor" required>
                        </div>
                        <div class="field">
                            <label for="edit_description">Description</label>
                            <textarea id="edit_description" name="description" bind:value={editRoleDescription} rows="2" placeholder="Briefly describe what this role can do"></textarea>
                        </div>
                        <div class="two fields">
                            <div class="field">
                                <button type="button" class="ui fluid button" onclick={cancelEditing}>
                                    Cancel
                                </button>
                            </div>
                            <div class="field">
                                <button type="submit" class="ui primary fluid button">
                                    Update Role
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            {:else}
                <div class="ui segment">
                    <h3 class="ui header">Create New Role</h3>
                    <form class="ui form" method="POST" action="{window.location.origin.endsWith('/') ? window.location.origin : window.location.origin + '/'}{adminPath.startsWith('/') ? adminPath.substring(1) : adminPath}/roles">
                        <input type="hidden" name="_token" value={document.querySelector('meta[name="csrf-token"]').getAttribute('content')}>
                        <div class="field required">
                            <label for="new_name">Role Name</label>
                            <input id="new_name" type="text" name="name" bind:value={newRoleName} oninput={handleNameInput} placeholder="Editor" required>
                        </div>
                        <div class="field required">
                            <label for="new_slug">Slug</label>
                            <input id="new_slug" type="text" name="slug" bind:value={newRoleSlug} placeholder="editor" required>
                        </div>
                        <div class="field">
                            <label for="new_description">Description</label>
                            <textarea id="new_description" name="description" bind:value={newRoleDescription} rows="2" placeholder="Briefly describe what this role can do"></textarea>
                        </div>
                        <button type="submit" class="ui primary fluid button">
                            <i class="plus icon"></i> Create Role
                        </button>
                    </form>
                </div>
            {/if}
        </div>

        <div class="ten wide column">
            <div class="ui segment">
                <h3 class="ui header">Existing Roles</h3>
                <div class="ui divided list">
                    {#each displayRoles as role}
                        <div class="item" style="padding: 1em 0;">
                            <div class="right floated content">
                                {#if !role.is_protected}
                                    <button class="ui mini blue icon button" onclick={() => startEditing(role)} title="Edit Role">
                                        <i class="edit icon"></i>
                                    </button>
                                    <button class="ui mini red icon button" onclick={() => deleteRole(role.id, role.name)} title="Delete Role">
                                        <i class="trash icon"></i>
                                    </button>
                                {:else}
                                    <div class="ui mini basic label"><i class="lock icon"></i> Protected</div>
                                {/if}
                            </div>
                            <div class="content">
                                <div class="header">{role.name} <code style="font-weight: normal; font-size: 0.8em; margin-left: 0.5em;">({role.slug})</code></div>
                                <div class="description">{role.description || 'No description provided.'}</div>
                            </div>
                        </div>
                    {/each}
                </div>
            </div>
        </div>

        <div class="sixteen wide column">
            <div class="ui segment">
                <h2 class="ui dividing header">Authorization Assignment Grid</h2>
                <div style="overflow-x: auto;">
                    <table class="ui celled definition table">
                        <thead>
                            <tr>
                                <th></th>
                                {#each displayRoles as role}
                                    <th class="center aligned">{role.name}</th>
                                {/each}
                            </tr>
                        </thead>
                        <tbody>
                            {#each Object.entries(groupedPermissions) as [resource, perms]}
                                <tr class="active">
                                    <td colspan={displayRoles.length + 1}>
                                        <strong>{resource.charAt(0).toUpperCase() + resource.slice(1)} Management</strong>
                                    </td>
                                </tr>
                                {#each perms as perm}
                                    <tr>
                                        <td>{perm.name}</td>
                                        {#each displayRoles as role}
                                            <td class="center aligned">
                                                {#if role.is_protected && role.slug === 'admin'}
                                                    <i class="green check circle icon" title="Admin has all permissions"></i>
                                                {:else}
                                                    <div class="ui fitted toggle checkbox {savingPermission ? 'disabled' : ''}" use:checkboxAction>
                                                        <input
                                                            id="perm-{role.id}-{perm.id}"
                                                            type="checkbox"
                                                            name="active"
                                                            checked={role.permissions.some(p => p.id === perm.id)}
                                                            disabled={role.is_protected || savingPermission}
                                                        >
                                                        <label for="perm-{role.id}-{perm.id}"></label>
                                                    </div>
                                                {/if}
                                            </td>
                                        {/each}
                                    </tr>
                                {/each}
                            {/each}
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
