<template>
  <div>
    <q-card class="col-12">
      <q-form @submit="save" @reset="reset">
        <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"
            @clear="removeRole"
            clearable
          />
        </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-input
              filled
              v-model="newRoleName"
              label="neuer Name"
              v-if="role.id != -1"
            />
            <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>
  </div>
</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 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
        };
      })
    );

    const newRoleName = ref<string>('');

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

    function removeRole(): void {
      role.value = null;
    }

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

    function updateRole(rl: FG.Role | string | null) {
      if (typeof rl === 'string' || rl === null) 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 {
          if (newRoleName.value !== '') role.value.name = newRoleName.value;
          console.log(role.value);
          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,
      permissions,
      createRole,
      updateRole,
      updatePermissions,
      save,
      reset,
      removeRole,
      remove,
      newRoleName
    };
  }
});
</script>