<?php

declare(strict_types=1);

require_once dirname(__DIR__, 3) . '/system/bootstrap.php';

$currentUser = myronRequireAdministrationAccess();
$auth = myronAuthRepository();
$csrfToken = myronCsrfToken();
$caller = myronActionCallerContextForUser($currentUser);
$roles = MyronAuthRepository::roleCatalog();
$allScopes = MyronAuthRepository::allKnownScopes();
$selectedUserId = trim((string) ($_GET['user'] ?? ''));
$selectedUser = $selectedUserId !== '' ? $auth->findUserById($selectedUserId) : null;
$activeTab = trim((string) ($_GET['tab'] ?? 'users'));
$activeTab = $activeTab === 'roles' ? 'roles' : 'users';

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
    $redirectUserId = trim((string) ($_POST['redirect_user_id'] ?? ''));
    try {
        myronRequireCsrf($_POST['csrf_token'] ?? null);
        $action = trim((string) ($_POST['action'] ?? ''));
        $userId = trim((string) ($_POST['user_id'] ?? ''));
        $redirectUserId = $userId !== '' ? $userId : $redirectUserId;

        if ($action === 'save-role') {
            $result = (new MyronUpdateUserRoleAction(myronIdentityActionService()))->execute([
                'userId' => $userId,
                'role_key' => trim((string) ($_POST['role_key'] ?? '')),
            ], $caller);
            if (!$result->ok) {
                throw new RuntimeException((string) ($result->error['message'] ?? 'Role update failed.'));
            }
            myronRedirectWithFlash(myronBuildAdminUrl('administration.rolesUsers', ['user' => $userId]), 'User role updated.', 'success');
        }

        if ($action === 'save-scopes') {
            $postedScopes = is_array($_POST['granted_scopes'] ?? null) ? array_map('strval', $_POST['granted_scopes']) : [];
            $result = (new MyronUpdateUserScopesAction(myronIdentityActionService()))->execute([
                'userId' => $userId,
                'granted_scopes' => $postedScopes,
            ], $caller);
            if (!$result->ok) {
                throw new RuntimeException((string) ($result->error['message'] ?? 'Scope update failed.'));
            }
            myronRedirectWithFlash(myronBuildAdminUrl('administration.rolesUsers', ['user' => $userId]), 'User scopes updated.', 'success');
        }

        if ($action === 'save-registration-settings') {
            $domains = $_POST['allowed_domains'] ?? [];
            $auth->saveRegistrationSettings(is_array($domains) ? $domains : []);
            myronRedirectWithFlash(myronBuildAdminUrl('administration.rolesUsers'), 'Registration settings saved.', 'success');
        }

        throw new RuntimeException('Unknown roles/users action.');
    } catch (Throwable $exception) {
        $query = $redirectUserId !== '' ? ['user' => $redirectUserId] : [];
        myronRedirectWithFlash(myronBuildAdminUrl('administration.rolesUsers', $query), $exception->getMessage(), 'error');
    }
}

$users = $auth->listUsers();
$registrationSettings = $auth->getRegistrationSettings();
$allowedDomains = is_array($registrationSettings['allowed_domains'] ?? null) ? $registrationSettings['allowed_domains'] : [];

function myronRolesUsersScopeLabel(string $scope): string
{
    return ucwords(str_replace('.', ' ', $scope));
}

function myronRolesUsersScopeSetData(array $scopes): string
{
    return myronEscape(json_encode(MyronAuthRepository::normalizeGrantedScopes($scopes), JSON_UNESCAPED_SLASHES));
}

myronRenderAdminShellStart($currentUser, [
    'title' => 'Roles & Users',
    'titleContext' => 'Administration',
    'activeItem' => 'roles-users',
]);
?>
<div class="mc-workspace__header">
  <?php myronRenderAdminBreadcrumbs([
      ['label' => 'Administration', 'href' => myronBuildAdminUrl('administration.rolesUsers')],
      ['label' => 'Roles & Users'],
  ]); ?>
  <div class="mc-workspace__title-row">
    <h1 class="mc-workspace__title">Roles & Users</h1>
  </div>
</div>

<div class="mc-page-canvas mc-page-canvas--site">
  <div class="sg-main">
    <div class="mc-workspace__tabs" role="tablist" aria-label="Roles and users views">
      <a class="mc-workspace__tab<?= $activeTab === 'users' ? ' mc-workspace__tab--active' : '' ?>" href="<?= myronEscape(myronBuildAdminUrl('administration.rolesUsers')) ?>">Users</a>
      <a class="mc-workspace__tab<?= $activeTab === 'roles' ? ' mc-workspace__tab--active' : '' ?>" href="<?= myronEscape(myronBuildAdminUrl('administration.rolesUsers', ['tab' => 'roles'])) ?>">Roles</a>
    </div>

    <?php if ($activeTab === 'roles'): ?>
      <section class="sg-section">
        <div class="mc-page-grid mc-page-grid--role-templates" role="table" aria-label="Role templates">
          <div class="mc-page-grid__row mc-page-grid__row--head" role="row">
            <span role="columnheader">Role</span>
            <span role="columnheader">Description</span>
            <span role="columnheader">Scopes</span>
          </div>
          <?php foreach ($roles as $role): ?>
          <div class="mc-page-grid__row" role="row">
            <span class="mc-page-grid__cell" role="cell"><?= myronEscape((string) $role['name']) ?></span>
            <span class="mc-page-grid__cell" role="cell"><?= myronEscape((string) $role['description']) ?></span>
            <span class="mc-page-grid__cell" role="cell"><?= myronEscape(implode(', ', array_map('myronRolesUsersScopeLabel', $role['granted_scopes']))) ?></span>
          </div>
          <?php endforeach; ?>
        </div>
        <p class="mc-page-grid__subtle">Custom roles coming in a future release.</p>
      </section>
    <?php else: ?>
      <div class="mc-users-layout<?= $selectedUser !== null ? ' mc-users-layout--sheet-open' : '' ?>">
        <div class="mc-users-layout__main">
          <section class="sg-section">
            <div class="mc-page-grid mc-page-grid--users" role="table" aria-label="Users list" data-mc-sortable-grid>
              <div class="mc-page-grid__row mc-page-grid__row--head" role="row">
                <span role="columnheader">Display Name</span>
                <span role="columnheader">Email</span>
                <span role="columnheader">Role</span>
                <span role="columnheader">Last Active</span>
                <span role="columnheader">Actions</span>
              </div>
              <?php foreach ($users as $user): ?>
              <div class="mc-page-grid__row mc-page-grid__row--user" role="row">
                <span class="mc-page-grid__cell" role="cell">
                  <a class="mc-page-grid__link" href="<?= myronEscape(myronBuildAdminUrl('administration.rolesUsers', ['user' => (string) $user['id']])) ?>">
                    <?= myronEscape((string) ($user['display_name'] ?? $user['username'] ?? 'User')) ?>
                  </a>
                  <span class="mc-page-grid__subtle">Username: @<?= myronEscape((string) ($user['username'] ?? '')) ?></span>
                </span>
                <span class="mc-page-grid__cell mc-page-grid__cell--email" role="cell"><?= myronEscape((string) ($user['email'] ?? '')) ?></span>
                <span class="mc-page-grid__cell" role="cell"><?= myronEscape((string) ($user['permission_level_label'] ?? $user['role_name'] ?? 'Custom')) ?></span>
                <span class="mc-page-grid__cell" role="cell"><?= myronEscape((string) ($user['last_login_at'] ?? 'Never')) ?></span>
                <span class="mc-page-grid__cell" role="cell">
                  <a class="sg-button sg-button--secondary" href="<?= myronEscape(myronBuildAdminUrl('administration.rolesUsers', ['user' => (string) $user['id']])) ?>">Edit</a>
                </span>
              </div>
              <?php endforeach; ?>
            </div>
          </section>

          <section class="sg-section">
            <h2 class="sg-section__title">Registration Policy</h2>
            <p class="sg-section__subtitle">Registrations are enabled only when one or more allowed email domains are configured. New registrations default to Viewer and require magic-link verification.</p>

            <form method="post" class="mc-registration-policy" data-mc-managed-form>
              <input type="hidden" name="csrf_token" value="<?= myronEscape($csrfToken) ?>">
              <input type="hidden" name="action" value="save-registration-settings">

              <div class="mc-domain-list" data-mc-domain-list>
                <?php foreach ($allowedDomains !== [] ? $allowedDomains : [''] as $domain): ?>
                <label class="sg-field mc-domain-list__item">
                  <span class="sg-field__label">Allowed Domain</span>
                  <div class="mc-domain-list__control">
                    <input class="sg-field__control" type="text" name="allowed_domains[]" value="<?= myronEscape((string) $domain) ?>" placeholder="@example.com" data-mc-form-field>
                    <div class="mc-domain-list__actions">
                      <button class="sg-button sg-button--secondary" type="button" data-mc-domain-remove>Remove</button>
                    </div>
                  </div>
                </label>
                <?php endforeach; ?>
              </div>

              <div class="mc-registration-policy__actions">
                <button class="sg-button sg-button--secondary" type="button" data-mc-domain-add>+</button>
                <button class="sg-button sg-button--primary" type="submit">Save Registration Settings</button>
              </div>
            </form>
          </section>
        </div>

        <?php if ($selectedUser !== null): ?>
        <?php
          $selectedRoleKey = (string) ($selectedUser['role_key'] ?? 'viewer');
          $selectedScopes = MyronAuthRepository::normalizeGrantedScopes($selectedUser['granted_scopes'] ?? []);
          $selectedTemplateScopes = MyronAuthRepository::scopesForRoleKey($selectedRoleKey);
          $isCustom = MyronAuthRepository::normalizeGrantedScopes($selectedTemplateScopes) !== $selectedScopes;
        ?>
        <aside class="mc-side-sheet" aria-label="Edit user role and scopes">
          <div class="mc-side-sheet__header">
            <div>
              <h2 class="mc-side-sheet__title"><?= myronEscape((string) ($selectedUser['display_name'] ?? 'User')) ?></h2>
              <div class="mc-side-sheet__meta">
                <span><?= myronEscape((string) ($selectedUser['email'] ?? '')) ?></span>
                <span><?= myronEscape((string) ($selectedUser['permission_level_label'] ?? 'Custom')) ?></span>
              </div>
            </div>
            <a class="sg-button sg-button--secondary" href="<?= myronEscape(myronBuildAdminUrl('administration.rolesUsers')) ?>">Close</a>
          </div>

          <form method="post" class="sg-form-grid" data-mc-role-scope-form>
            <input type="hidden" name="csrf_token" value="<?= myronEscape($csrfToken) ?>">
            <input type="hidden" name="action" value="save-role" data-mc-role-action>
            <input type="hidden" name="user_id" value="<?= myronEscape((string) $selectedUser['id']) ?>">
            <input type="hidden" name="redirect_user_id" value="<?= myronEscape((string) $selectedUser['id']) ?>">

            <label class="sg-field">
              <span class="sg-field__label">Role</span>
              <select class="sg-field__control" name="role_key" data-mc-role-select>
                <?php foreach ($roles as $roleKey => $role): ?>
                <option value="<?= myronEscape((string) $roleKey) ?>" data-template-scopes="<?= myronRolesUsersScopeSetData($role['granted_scopes']) ?>" <?= $selectedRoleKey === $roleKey ? 'selected' : '' ?>><?= myronEscape((string) $role['name']) ?></option>
                <?php endforeach; ?>
              </select>
            </label>

            <div class="mc-page-grid__subtle" data-mc-scope-deviation><?= $isCustom ? 'Different from role template.' : 'Matches role template.' ?></div>
            <button class="sg-button sg-button--secondary" type="button" data-mc-apply-role-template>Apply Role Template</button>

            <details class="mc-side-sheet__section" <?= $isCustom ? 'open' : '' ?>>
              <summary>Customize scopes</summary>
              <div class="mc-context-form__checkboxes">
                <?php foreach ($allScopes as $scope): ?>
                <label class="mc-checkbox mc-checkbox--compact">
                  <input type="checkbox" name="granted_scopes[]" value="<?= myronEscape($scope) ?>" <?= in_array($scope, $selectedScopes, true) ? 'checked' : '' ?> data-mc-scope-checkbox>
                  <span><?= myronEscape(myronRolesUsersScopeLabel($scope)) ?></span>
                </label>
                <?php endforeach; ?>
              </div>
            </details>

            <div class="mc-page-grid__actions">
              <button class="sg-button sg-button--secondary" type="button" data-mc-reset-role-defaults>Reset to role defaults</button>
              <button class="sg-button sg-button--primary" type="submit" data-mc-save-role>Save</button>
            </div>
          </form>
        </aside>
        <?php endif; ?>
      </div>
    <?php endif; ?>
  </div>
</div>

<script>
(function () {
  document.querySelectorAll('[data-mc-domain-list]').forEach(function (list) {
    var form = list.closest('form');
    var add = form ? form.querySelector('[data-mc-domain-add]') : null;
    function wire(item) {
      var remove = item.querySelector('[data-mc-domain-remove]');
      if (remove) {
        remove.addEventListener('click', function () {
          var items = list.querySelectorAll('.mc-domain-list__item');
          if (items.length <= 1) {
            var input = item.querySelector('input');
            if (input) input.value = '';
            return;
          }
          item.remove();
        });
      }
    }
    Array.prototype.slice.call(list.querySelectorAll('.mc-domain-list__item')).forEach(wire);
    if (add) {
      add.addEventListener('click', function () {
        var first = list.querySelector('.mc-domain-list__item');
        if (!first) return;
        var clone = first.cloneNode(true);
        var input = clone.querySelector('input');
        if (input) input.value = '';
        list.appendChild(clone);
        wire(clone);
      });
    }
  });

  var form = document.querySelector('[data-mc-role-scope-form]');
  if (!form) return;
  var roleSelect = form.querySelector('[data-mc-role-select]');
  var actionInput = form.querySelector('[data-mc-role-action]');
  var checkboxes = Array.prototype.slice.call(form.querySelectorAll('[data-mc-scope-checkbox]'));
  var deviation = form.querySelector('[data-mc-scope-deviation]');
  function selectedTemplate() {
    var option = roleSelect && roleSelect.options ? roleSelect.options[roleSelect.selectedIndex] : null;
    if (!option) return [];
    try { return JSON.parse(option.getAttribute('data-template-scopes') || '[]'); } catch (e) { return []; }
  }
  function checkedScopes() {
    return checkboxes.filter(function (box) { return box.checked; }).map(function (box) { return box.value; }).sort();
  }
  function setScopes(scopes) {
    checkboxes.forEach(function (box) { box.checked = scopes.indexOf(box.value) !== -1; });
    sync();
  }
  function sync() {
    var template = selectedTemplate().slice().sort();
    var checked = checkedScopes();
    var custom = template.join('|') !== checked.join('|');
    if (deviation) deviation.textContent = custom ? 'Different from role template.' : 'Matches role template.';
    if (actionInput) actionInput.value = custom ? 'save-scopes' : 'save-role';
  }
  var applyButton = form.querySelector('[data-mc-apply-role-template]');
  var resetButton = form.querySelector('[data-mc-reset-role-defaults]');
  if (applyButton) applyButton.addEventListener('click', function () { setScopes(selectedTemplate()); });
  if (resetButton) resetButton.addEventListener('click', function () { setScopes(selectedTemplate()); });
  if (roleSelect) roleSelect.addEventListener('change', sync);
  checkboxes.forEach(function (box) { box.addEventListener('change', sync); });
  sync();
})();
</script>
<?php myronRenderAdminShellEnd(); ?>
