<template>
  <q-card class="col-12">
    <q-form @submit="save" @reset="reset">
      <q-linear-progress indeterminate rounded color="primary" v-if="loading" />
      <q-card-section class="fit row justify-start content-center items-center">
        <span class="col-xs-12 col-sm-6 text-center text-h6">
          Rollen und Berechtigungen
        </span>
        <q-select
          filled
          use-input
          label="Rolle"
          input-debounce="0"
          class="col-xs-12 col-sm-6 q-pa-sm"
          :value="role"
          :options="roles"
          option-label="name"
          option-value="name"
          map-options
          @new-value="createRole"
          @input="updateRole"
        />
      </q-card-section>
      <q-separator />
      <q-card-section
        v-if="role"
        class="fit row justify-start content-center items-center"
      >
        <q-scroll-area style="height: 20em; width: 100%;">
          <q-option-group
            :value="role.permissions"
            @input="updatePermissions"
            :options="permissions"
            color="primary"
            type="checkbox"
          />
        </q-scroll-area>
      </q-card-section>
      <q-card-actions v-if="role" align="right">
        <q-btn label="Löschen" color="negative" @click="remove" />
        <q-btn label="Reset" type="reset" />
        <q-btn color="primary" type="submit" label="Speichern" />
      </q-card-actions>
    </q-form>
  </q-card>
</template>

<script lang="ts">
import {
  computed,
  defineComponent,
  ref,
  onBeforeMount
} from '@vue/composition-api';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';

export default defineComponent({
  name: 'RoleSettings',
  setup(_, { root }) {
    const store = <Store<StateInterface>>root.$store;

    onBeforeMount(() => {
      store.dispatch('user/getRoles').catch(error => {
        console.warn(error);
      });
      store.dispatch('user/getPermissions').catch(error => {
        console.warn(error);
      });
    });

    const loading = computed(() => store.state.user.loading > 0);
    const role = ref<FG.Role | null>(null);
    const roles = computed(() => store.state.user.roles);
    const permissions = computed(() =>
      store.state.user.permissions.map(perm => {
        return {
          value: perm,
          label: perm
        };
      })
    );

    function createRole(
      name: string,
      done: (arg0: string, arg1: string) => void
    ): void {
      role.value = { name: name, permissions: [], id: -1 };
      done(name, 'add-unique');
    }

    function updatePermissions(permissions: string[]) {
      if (role.value) {
        role.value.permissions = permissions;
      }
    }

    function updateRole(rl: FG.Role | string) {
      if (typeof rl === 'string') return;
      role.value = {
        id: rl.id,
        name: rl.name,
        permissions: Array.from(rl.permissions)
      };
    }

    function save() {
      if (role.value) {
        if (role.value.id === -1)
          void store.dispatch('user/newRole', role.value);
        else void store.dispatch('user/updateRole', role.value);
      }
    }

    function reset() {
      if (role.value && role.value.id !== -1) {
        const original = roles.value.find(
          value => value.name === role.value?.name
        );
        if (original) updateRole(original);
      } else {
        role.value = null;
      }
    }

    function remove() {
      if (role.value) {
        if (role.value.id === -1) {
          role.value = null;
        } else {
          store
            .dispatch('user/deleteRole', role.value)
            .then(() => (role.value = null))
            .catch(error => console.warn(error));
        }
      }
    }

    return {
      roles,
      role,
      createRole,
      permissions,
      updateRole,
      updatePermissions,
      save,
      reset,
      remove,
      loading
    };
  }
});
</script>
