<script>
  import { _ } from "svelte-i18n";
  import {
    UserService,
    PermissionService,
    CreatePermission,
  } from "@odit/lfk-client-js";
  import PromiseError from "../base/PromiseError.svelte";
  import toast from "svelte-french-toast";
  export let params;
  let [
    grantedPermissions_initial,
    grantedPermissions,
    inheritedPermissions,
    to_add,
    to_delete,
    allpermissions,
    promises,
  ] = [[], [], [], [], [], [], []];
  $: original_data = {};
  $: save_enabled =
    JSON.stringify(grantedPermissions) ===
    JSON.stringify(grantedPermissions_initial);
  const user_promise = UserService.userControllerGetOne(params.userid);
  user_promise.then((data) => {
    original_data = Object.assign(original_data, data);
  });
  function submit() {
    toast.loading($_("updating-permissions"));
    to_delete.forEach((d) => {
      promises = promises.concat([
        PermissionService.permissionControllerRemove(d, true),
      ]);
    });
    to_add.forEach((a) => {
      promises = promises.concat([
        PermissionService.permissionControllerPost(a),
      ]);
    });
    Promise.all(promises).then((values) => {
      promises = [];
      to_delete.forEach((d) => {
        to_delete = to_delete.filter((o) => o !== d);
      });
      to_add.forEach((a) => {
        to_add = to_add.filter(
          (o) => o.target + ":" + o.action !== a.target + ":" + a.action
        );
      });
      grantedPermissions_initial = grantedPermissions;
      toast.dismiss();
      toast.success($_("permissions-updated"));
    });
  }
  Object.values(CreatePermission.target).forEach((t) => {
    Object.values(CreatePermission.action).forEach((a) => {
      allpermissions = allpermissions.concat([{ target: t, action: a }]);
    });
  });
  UserService.userControllerGetPermissions(params.userid).then((val) => {
    val.inherited.forEach((p) => {
      inheritedPermissions = inheritedPermissions.concat([p]);
    });
    val.directlyGranted.forEach((p) => {
      grantedPermissions = grantedPermissions.concat([p]);
    });
    grantedPermissions_initial = grantedPermissions;
  });
</script>

{#await user_promise}
  <!--  -->
{:then user}
  <section class="container p-5 select-none">
    <div class="flex flex-row mb-4">
      <div class="w-full">
        <nav class="w-full flex">
          <ol class="list-none flex flex-row items-center justify-start">
            <li class="flex items-center">
              <svg
                class="flex-shrink-0 w-5 h-5 mr-2"
                fill="currentColor"
                width="24"
                height="24"
                xmlns="http://www.w3.org/2000/svg"
                viewBox="0 0 24 24"
                ><path
                  fill="currentColor"
                  d="M12 14v8H4a8 8 0 018-8zm0-1a6 6 0 110-12 6 6 0 010 12zm2.6 5.81a3.51 3.51 0 010-1.62l-1-.57 1-1.74 1 .58a3.5 3.5 0 011.4-.82V13.5h2v1.15a3.5 3.5 0 011.4.8l1-.57 1 1.74-1 .57a3.51 3.51 0 010 1.62l1 .57-1 1.74-1-.58a3.5 3.5 0 01-1.4.82v1.14h-2v-1.15a3.5 3.5 0 01-1.4-.8l-1 .57-1-1.74 1-.57zM18 17a1 1 0 100 2 1 1 0 000-2z"
                /></svg
              >
            </li>
            <li class="flex items-center">
              <a class="mr-2" href="../../">{$_("users")}</a><svg
                stroke="currentColor"
                fill="none"
                stroke-width="2"
                viewBox="0 0 24 24"
                stroke-linecap="round"
                stroke-linejoin="round"
                class="h-3 w-3 mr-2 stroke-current"
                height="1em"
                width="1em"
                xmlns="http://www.w3.org/2000/svg"
                ><line x1="5" y1="12" x2="19" y2="12" />
                <polyline points="12 5 19 12 12 19" /></svg
              >
            </li>
            <li class="flex items-center">
              <span class="mr-2"
                ><a href="../"
                  >{original_data.firstname}
                  {original_data.middlename || ""}
                  {original_data.lastname}</a
                ></span
              >
            </li>
            <li class="flex items-center">
              <svg
                stroke="currentColor"
                fill="none"
                stroke-width="2"
                viewBox="0 0 24 24"
                stroke-linecap="round"
                stroke-linejoin="round"
                class="h-3 w-3 mr-2 stroke-current"
                height="1em"
                width="1em"
                xmlns="http://www.w3.org/2000/svg"
                ><line x1="5" y1="12" x2="19" y2="12" />
                <polyline points="12 5 19 12 12 19" /></svg
              >
            </li>
            <li class="flex items-center">
              <span class="mr-2">{$_("permissions")}</span>
            </li>
          </ol>
        </nav>
      </div>
    </div>
    <div class="mb-4 text-3xl font-extrabold">
      {$_("permissions")}:
      {original_data.firstname}
      {original_data.middlename || ""}
      {original_data.lastname}
      <span>
        {#if promises.length === 0}
          <button
            disabled={save_enabled}
            class:opacity-50={save_enabled}
            type="button"
            on:click={submit}
            class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mb-1 lg:mb-0"
            >{$_("save-changes")}</button
          >
        {:else}
          <button
            type="button"
            class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-yellow-600 text-base font-medium text-white hover:bg-yellow-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-yellow-500 sm:w-auto sm:text-sm"
            >{$_("applying-changes")}</button
          >
        {/if}
      </span>
    </div>
    <!--  -->
    <div class="flex flex-wrap -mx-1 overflow-hidden">
      <div class="my-1 px-1 w-full overflow-hidden sm:w-1/3">
        {$_("available-permissions")}
      </div>
      <div class="my-1 px-1 w-full overflow-hidden sm:w-1/3">
        {$_("directly-granted")}
      </div>
      <div class="my-1 px-1 w-full overflow-hidden sm:w-1/3">
        {$_("inherited-permissions")}
      </div>
    </div>
    <!--  -->
    <div class="flex flex-wrap -mx-1 overflow-hidden">
      {#if allpermissions.length > 0}
        <div class="my-1 px-1 w-full overflow-hidden sm:w-1/3">
          <div
            class="border-4 border-dashed rounded mb-4 p-5 text-lg text-center"
          >
            {#each allpermissions as p}
              {#if !(grantedPermissions.filter((o) => p.target == o.target && p.action == o.action).length > 0)}
                <p
                  class="block w-full mt-1 text-sm bg-gray-200 p-2 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple form-input"
                >
                  {p.target + ":" + p.action}
                  <button
                    on:click={() => {
                      grantedPermissions = grantedPermissions.concat([p]);
                      if (to_delete.some((o) => o === p.id)) {
                        to_delete = to_delete.filter((o) => o !== p.id);
                      } else {
                        to_add = to_add.concat([
                          {
                            action: p.action,
                            target: p.target,
                            principal: original_data.id,
                          },
                        ]);
                      }
                    }}
                    type="button"
                    class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-200 text-base font-medium text-black hover:bg-green-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:w-auto sm:text-sm"
                    >+</button
                  >
                </p>
              {/if}
            {/each}
          </div>
        </div>
        <div class="my-1 px-1 w-full overflow-hidden sm:w-1/3">
          <div
            class="border-4 border-dashed rounded mb-4 p-5 text-lg text-center"
          >
            {#each grantedPermissions as p}
              <p
                class="block w-full mt-1 text-sm bg-gray-200 p-2 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple form-input"
              >
                {p.target + ":" + p.action}
                <button
                  on:click={() => {
                    grantedPermissions = grantedPermissions.filter(
                      (o) =>
                        o.target + ":" + o.action !== p.target + ":" + p.action
                    );
                    if (
                      to_add.some(
                        (o) =>
                          o.target + ":" + o.action ===
                          p.target + ":" + p.action
                      )
                    ) {
                      to_add = to_add.filter(
                        (o) =>
                          o.target + ":" + o.action !==
                          p.target + ":" + p.action
                      );
                    } else {
                      to_delete = to_delete.concat([p.id]);
                    }
                  }}
                  type="button"
                  class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-300 text-base font-medium text-black hover:bg-red-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:w-auto sm:text-sm"
                  >-</button
                >
              </p>
            {/each}
          </div>
        </div>
        <div class="my-1 px-1 w-full overflow-hidden sm:w-1/3">
          <div
            class="border-4 border-dashed rounded mb-4 p-5 text-lg text-center"
          >
            {#each inheritedPermissions as p}
              <p
                class="block w-full mt-1 text-sm bg-gray-200 p-2 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple form-input"
              >
                {p.target + ":" + p.action}
              </p>
            {/each}
          </div>
        </div>
      {/if}
    </div>
  </section>
{:catch error}
  <PromiseError {error} />
{/await}
