<script setup>
import PageTitle from "@/components/global/PageTitle.vue";
import RestrictedPageWrapper from "@/components/page/wrappers/RestrictedPageWrapper.vue";
import {SessionUser} from "@/components/session/token/SessionUser.vue";
import {useRouter} from 'vue-router'
import {ref, watch} from "vue";
import {loadList, setEndpoint, setOrder} from "@/components/pagination/paginatedList.vue";
import RolesSubPageWrapper from "@/views/dashboards/superUserDashboard/roles/RolesSubPageWrapper.vue";

// Lists
const permissions = ref([]);
const permissionsList = ref([]);
const rolePermissions = ref([]);
const departments = ref([]);

// Loaded state
const isLoaded = ref(false);
// Individually loaded states
const isDepartmentsLoaded = ref(false);
const isPermissionsLoaded = ref(false);
const isRolePermissionsLoaded = ref(false);
const isPermissionsListLoaded = ref(false);

watch(() => departments.value, () => {
  console.log('Departments loaded');
  isDepartmentsLoaded.value = true;
});

watch(() => permissionsList.value, () => {
  console.log('Permissions list loaded');
  isPermissionsListLoaded.value = true;
});

watch(() => permissions.value, () => {
  console.log('Permissions loaded');
  isPermissionsLoaded.value = true;
});

watch(() => rolePermissions.value, () => {
  console.log('Role permissions loaded');
  isRolePermissionsLoaded.value = true;
});

// Get the department from the route
const router = useRouter()
const roleId = ref(parseInt(router.currentRoute.value.params.roleId));

// Set the endpoint
setEndpoint(SessionUser.objects.department_categories.meta.endpoint + `?id=${roleId.value}`);
// Set the order
setOrder("category_id", "asc");
// Load the list
loadList();

const loadPermissionsList = async () => {
  const response = await SessionUser.objects.permissions.get.all().then((response) => {
    const tmpPermissionsList = [];
    const tmpPermissions = [];
    for (const i in response) {
      const endpoint = i;
      const methods = response[i];
      for (const method in methods) {
        const permissions = methods[method];
        for (const permission in permissions) {
          tmpPermissionsList.push(permission);
          tmpPermissions[endpoint] = tmpPermissions[endpoint] || {};  // Create the endpoint if it doesn't exist
          tmpPermissions[endpoint][method] = tmpPermissions[endpoint][method] || {};  // Create the method if it doesn't exist
          tmpPermissions[endpoint][method][permission] = permissions[permission];
        }
      }
    }
    permissionsList.value = tmpPermissionsList;
    permissions.value = tmpPermissions;
  });
}
// Get all available permissions
loadPermissionsList();
const loadRolePermissions = async () => {
  await SessionUser.objects.roles.get.single(roleId.value).then((response) => {
    rolePermissions.value = response.permissions;
  });
}
// Get the permissions for the role
loadRolePermissions();

const convertRouteToHumanReadable = (route) => {
  let arrow = " -> ";
  // Replace / with space
  let humanReadable = route.replace(/\//g, arrow);
  // Replace _ with space
  humanReadable = humanReadable.replace(/_/g, " ");
  // Capitalize the first letter
  humanReadable = humanReadable.charAt(0).toUpperCase() + humanReadable.slice(1);
  // If the route ends with an arrow, remove it
  if (humanReadable.endsWith(arrow)) {
    humanReadable = humanReadable.slice(0, -arrow.length);
  }
  // If the route starts with an arrow, remove it
  if (humanReadable.startsWith(arrow)) {
    humanReadable = humanReadable.slice(arrow.length);
  }
  return humanReadable;
}

const endpointMethodColors = {
  GET: "is-success",
  POST: "is-info",
  PUT: "is-warning",
  PATCH: "is-warning",
  DELETE: "is-danger",
  OPTIONS: "is-light",
}

const hasPermission = (permission) => {
  return rolePermissions.value.includes(permission);
}

const togglePermission = (permission) => {
  if (hasPermission(permission)) {
    SessionUser.objects.roles.functions.permissions.remove(roleId.value, permission).then((response) => {
      // Remove the permission
      rolePermissions.value = rolePermissions.value.filter((value) => value !== permission);
    });
  } else {
    SessionUser.objects.roles.functions.permissions.add(roleId.value, permission).then((response) => {
      // Add the permission
      rolePermissions.value.push(permission);
    });
  }
}


const loadDepartments = async () => {
  const response = await SessionUser.objects.departments.get.all().then((response) => {
    departments.value = response;
  });
}

loadDepartments();

watch(() => isDepartmentsLoaded.value && isPermissionsListLoaded.value && isPermissionsLoaded.value && isRolePermissionsLoaded.value, () => {
  console.log('Loaded:', 'Departments:', departments.value.length, 'Permissions:', permissionsList.value.length, 'Role permissions:', rolePermissions.value.length);
  isLoaded.value = true;
});
</script>

<template>
  <RestrictedPageWrapper :hasPermission="SessionUser.canAccessSuperUser()">
    <RolesSubPageWrapper>
      <template #title>
        <PageTitle :title="`Role ${roleId}`" subtitle="Role permissions">
          <template #buttons>
          </template>
        </PageTitle>
      </template>
      <!-- Department access permissions -->
      <div class="box" v-if="isLoaded">
        <p class="is-pulled-right">
          <span class="tag is-dark is-large">
            Department access
          </span>
        </p>
        <p class="mt-2"> Department dependent permissions applies to:</p>
        <div class="columns is-multiline">
          <div v-for="department in departments" :key="department.id" class="column is-3">
            <span class="tag is-dark">
              {{ department.name }}
            </span>
            <!-- Enable switch -->
            <div class="field">
              <input
                :id="'enable_department_' + department.id + '_access'"
                type="checkbox"
                class="switch is-rounded"
                @change="togglePermission('department_access_' + department.id)"
                :checked="hasPermission('department_access_' + department.id)"
              />
              <label :for="'enable_department_' + department.id + '_access'"></label>
            </div>
          </div>
        </div>
      </div>
      <!-- Page type permissions -->
      <div class="box">
        <p class="is-pulled-right">
          <span class="tag is-dark is-large">
            Page type access
          </span>
        </p>
        <p class="mt-2"> Page type dependent permissions applies to:</p>
        <div class="columns is-multiline">
          <!-- User -->
          <div class="column is-3">
            <span class="tag is-dark">
              User
            </span>
            <!-- Enable switch -->
            <div class="field">
              <input
                id="enable_user"
                type="checkbox"
                class="switch is-rounded"
                @change="togglePermission('user')"
                :checked="hasPermission('user')"
              />
              <label for="enable_user"></label>
            </div>
          </div>
          <!-- Admin -->
          <div class="column is-3">
            <span class="tag is-dark">
              Admin
            </span>
            <!-- Enable switch -->
            <div class="field">
              <input
                id="enable_admin"
                type="checkbox"
                class="switch is-rounded"
                @change="togglePermission('admin')"
                :checked="hasPermission('admin')"
              />
              <label for="enable_admin"></label>
            </div>
          </div>
          <!-- Super user -->
          <div class="column is-3">
            <span class="tag is-dark">
              Super user
            </span>
            <!-- Enable switch -->
            <div class="field">
              <input
                id="enable_superuser"
                type="checkbox"
                class="switch is-rounded"
                @change="togglePermission('superuser')"
                :checked="hasPermission('superuser')"
              />
              <label for="enable_superuser"></label>
            </div>
        </div>
      </div>
      </div>
      <!-- Permissions -->
      <div v-for="([endpoint, permission]) of Object.entries(permissions).sort((a, b) => a[0].localeCompare(b[0]))" class="box" v-if="isLoaded">
        <p class="is-pulled-right">
          <span class="tag is-dark is-large">
          {{ endpoint }}
          </span>
        </p>
        <!-- Permissions -->
        <div class="mt-2" v-for="(permission, method) in permission" :key="method">
          <span class="tag mt-3" :class="endpointMethodColors[method]">
            <strong class="has-text-black">{{ method }}</strong>
          </span>
          <strong>&nbsp;{{ endpoint}}</strong> {{ convertRouteToHumanReadable(endpoint) }}
          <!--{{ permission }} -->
          <p class="mt-1"> Permissions </p>
          <div v-for="(permission, permission_node) in permission" :key="permission_node">
            <span class="tag is-dark">
              {{ permission_node }}
            </span>
            {{ permission }}
            <!-- Enable switch -->
            <div class="field">
              <input
                :id="'enable_' + permission_node"
                type="checkbox"
                class="switch is-rounded"
                :checked="hasPermission(permission_node)"
                @change="togglePermission(permission_node)"
              />
              <label :for="'enable_' + permission_node"></label>
            </div>
          </div>
        </div>
        <!--<pre>{{ permission }}</pre> -->
      </div>
    </RolesSubPageWrapper>
  </RestrictedPageWrapper>
</template>

<style scoped>

</style>