<template>
  <q-form
    @submit="save"
    @reset="reset"
  >
    <q-card-section class="fit row justify-start content-center items-center">
      <q-input
        class="col-xs-12 col-sm-6 q-pa-sm"
        label="Vorname"
        :rules="[notEmpty]"
        v-model="props.user.firstname"
        filled
      />
      <q-input
        class="col-xs-12 col-sm-6 q-pa-sm"
        label="Nachname"
        :rules="[notEmpty]"
        v-model="props.user.lastname"
        filled
      />

      <q-input
        class="col-xs-12 col-sm-6 q-pa-sm"
        label="Angezeigter Name"
        :rules="[notEmpty]"
        v-model="props.user.display_name"
        filled
      />
      <q-input
        class="col-xs-12 col-sm-6 q-pa-sm"
        label="E-Mail"
        :rules="[isEmail, notEmpty]"
        v-model="props.user.mail"
        filled
      />
      <q-input
        class="col-xs-12 col-sm-6 q-pa-sm"
        label="Benutzername"
        :readonly="!props.newUser"
        v-model="props.user.userid"
        :rules="[isUseridUsed, notEmpty]"
        filled
      />
      <q-select
        class="col-xs-12 col-sm-6 q-pa-sm"
        label="Rollen"
        filled
        multiple
        use-chips
        v-model="props.user.roles"
        :readonly="!canSetRoles"
        :options="allRoles"
        option-label="name"
        option-value="name"
      />
      <IsoDateInput
        class="col-xs-12 col-sm-6 q-pa-sm"
        v-model="props.user.birthday"
        label="Geburtstag"
      />
      <q-file
        class="col-xs-12 col-sm-6 q-pa-sm"
        v-model="avatar"
        filled
        label="Avatar"
        accept=".jpg, image/*"
        max-file-size="204800"
        hint="Bilddateien, max. 200 KiB"
        @rejected="onAvatarRejected"
      >
        <template v-slot:append>
          <q-icon
            name="mdi-file-image"
            @click.stop
          />
        </template>
      </q-file>
    </q-card-section>
    <q-separator v-if="!props.newUser" />
    <q-card-section
      class="fit row justify-start content-center items-center"
      v-if="!props.newUser"
    >
      <q-input
        v-if="isCurrentUser"
        class="col-xs-12 col-sm-6 col-md-4 q-pa-sm"
        label="Password"
        type="password"
        hint="Password muss immer eingetragen werden"
        :rules="[notEmpty]"
        v-model="password"
        filled
      />
      <q-input
        class="col-xs-12 col-sm-6 col-md-4 q-pa-sm"
        label="Neues Password"
        type="password"
        v-model="new_password"
        filled
      />
      <q-input
        class="col-xs-12 col-sm-6 col-md-4 q-pa-sm"
        label="Wiederhole neues Password"
        type="password"
        :disable="new_password.length == 0"
        :rules="[samePassword]"
        v-model="new_password2"
        filled
      />
    </q-card-section>
    <q-card-actions align="right">
      <q-btn
        label="Reset"
        type="reset"
      />
      <q-btn
        color="primary"
        type="submit"
        label="Speichern"
      />
    </q-card-actions>
  </q-form>
</template>

<script lang="ts">
import {
  computed,
  defineComponent,
  ref,
  onBeforeMount,
} from '@vue/composition-api';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';
import { hasPermission } from 'src/components/permission';
import IsoDateInput from 'src/components/utils/IsoDateInput.vue';
import { Notify } from 'quasar';

interface Props {
  user?: FG.User;
  newUser?: boolean;
}

export default defineComponent({
  name: 'MainUserSettings',
  components: { IsoDateInput: IsoDateInput },
  props: {
    user: {
      required: true,
    },
    newUser: {
      default: false,
    },
  },
  setup(props: Props, { root, emit }) {
    const store = <Store<StateInterface>>root.$store;

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

    const isCurrentUser = computed(
      () => props.user?.userid === store.state.user.currentUser?.userid
    );

    const canSetRoles = computed(() => hasPermission('users_set_roles', store));

    const oldUser = computed(() => {
      if (isCurrentUser.value) return <FG.User>store.state.user.currentUser;
      else
        return store.state.user.users.filter((user) => {
          user.userid === props.user?.userid;
        })[0];
    });

    const avatar = ref([]);
    function onAvatarRejected() {
      Notify.create({
        group: false,
        type: 'negative',
        message: 'Datei zu groß oder keine gültige Bilddatei.',
        timeout: 10000,
        progress: true,
        actions: [{ icon: 'mdi-close', color: 'white' }],
      });
      avatar.value = [];
    }

    const allRoles = computed(() =>
      store.state.user.roles.map((role) => role.name)
    );
    const password = ref('');
    const new_password = ref('');
    const new_password2 = ref('');

    function save() {
      let changed = <FG.User>props.user;
      if (typeof changed.birthday === 'string')
        changed.birthday = new Date(changed.birthday);
      changed = Object.assign(changed, {
        password: password.value,
      });
      if (new_password.value != '') {
        changed = Object.assign(changed, {
          new_password: new_password.value,
        });
      }

      emit('update:user', changed);
      if (avatar.value && avatar.value.length > 0)
        store
          .dispatch('user/uploadAvatar', {
            user: changed,
            file: avatar.value,
          })
          .catch((response: Response) => {
            if (response && response.status == 400) {
              onAvatarRejected();
            }
          });
      reset();
    }

    function reset() {
      props.user = oldUser.value;
      password.value = '';
      new_password.value = '';
      new_password2.value = '';
    }

    function samePassword(val: string) {
      return val == new_password.value || 'Passwörter sind nicht identisch!';
    }

    function notEmpty(val: string) {
      return !!val || 'Feld darf nicht leer sein!';
    }

    function isEmail(val: string | null) {
      return (
        !val ||
        /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w\w+)+$/.test(val) ||
        'E-Mail ist nicht valide.'
      );
    }

    function isUseridUsed(val: string) {
      return (
        !store.state.user.users.find((user: FG.User) => {
          return user.userid == val;
        }) ||
        !props.newUser ||
        'Benutzername ist schon vergeben'
      );
    }

    return {
      avatar,
      onAvatarRejected,
      props,
      allRoles,
      canSetRoles,
      password,
      new_password,
      new_password2,
      samePassword,
      isCurrentUser,
      isEmail,
      notEmpty,
      isUseridUsed,
      save,
      reset,
    };
  },
});
</script>
