<template>
  <q-card bordered>
    <q-dialog :model-value="dialog">
      <q-card style="min-width: 320px">
        <q-card-section class="row items-center q-pb-none">
          <div class="text-h6">
            {{ userDisplay(service.userid) }} {{ asDate(modelValue.start) }}
          </div>
          <q-space />
          <q-btn icon="mdi-close" flat round dense @click="dialog = false" />
        </q-card-section>
        <q-card-section>
          {{ modelValue.type.name }} {{ asHour(modelValue.start)
          }}{{ modelValue.end ? ` - ${asHour(modelValue.end)}` : '' }}
          Uhr
        </q-card-section>
        <q-card-actions align="around">
          <q-btn style="width: 47.5%" color="primary" label="Eintragen" @click="enroll()" />
          <q-toggle
            v-model="service.is_backup"
            style="width: 47.5%"
            color="primary"
            label="Als Backup"
          />
        </q-card-actions>
        <q-card-actions v-if="!enrolled(service.userid)" align="around">
          <q-btn
            v-if="isEnrolled"
            style="width: 47.5%"
            color="negative"
            label="Übertragen"
            @click="enroll(true)"
          />
          <q-btn
            v-if="!iam(service.userid)"
            style="width: 47.5%"
            color="secondary"
            label="Einladen"
            @click="enroll(false, true)"
          />
        </q-card-actions>
      </q-card>
    </q-dialog>
    <div class="text-weight-medium q-px-xs">
      {{ asHour(modelValue.start) }}
      <template v-if="modelValue.end">- {{ asHour(modelValue.end) }}</template>
    </div>
    <div class="q-px-xs">
      {{ modelValue.type.name }}
    </div>
    <div class="col-auto q-px-xs" style="font-size: 10px">
      {{ modelValue.comment }}
    </div>
    <div>
      <q-select
        :model-value="modelValue.services"
        :options="options"
        :option-label="(v) => userDisplay(v.userid)"
        filled
        multiple
        stack-label
        label="Dienste"
        class="col-auto q-px-xs"
        style="font-size: 6px"
        counter
        :max-values="modelValue.required_services"
        @add="enrollDialog"
      >
        <template #selected-item="scope">
          <q-chip
            :removable="canEdit(scope.opt.userid)"
            dense
            :tabindex="scope.tabindex"
            color="white"
            :text-color="scope.opt.is_backup ? 'primary' : 'secondary'"
            class="q-ma-none"
            @remove="remove(scope.opt, scope.removeAtIndex, scope.index)"
          >
            <q-avatar :color="scope.opt.is_backup ? 'primary' : 'secondary'" text-color="white">
              <img
                :src="userAvatar(scope.opt.userid)"
                onerror="this.src=' data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==';"
              />
            </q-avatar>
            {{ userDisplay(scope.opt.userid) }}
          </q-chip>
        </template>
      </q-select>
    </div>
  </q-card>
</template>

<script lang="ts">
import { defineComponent, onBeforeMount, computed, ref, PropType } from 'vue';
import { Notify } from 'quasar';
import { asHour, asDate } from 'src/utils/datetime';
import { useUserStore } from 'src/plugins/user/store';
import { useMainStore } from 'src/stores';
import { useScheduleStore } from 'src/plugins/events/store';
import { PERMISSIONS } from 'src/plugins/events/permissions';
import { hasPermission } from 'src/utils/permission';

export default defineComponent({
  name: 'JobSlot',
  props: {
    modelValue: {
      required: true,
      type: Object as PropType<FG.Job>,
    },
    eventId: {
      required: true,
      type: Number,
    },
  },
  emits: { 'update:modelValue': (v: FG.Job) => !!v },
  setup(props, { emit }) {
    const store = useScheduleStore();
    const mainStore = useMainStore();
    const userStore = useUserStore();
    const availableUsers = null;
    const dialog = ref(false);
    const service = ref<FG.Service>();
    onBeforeMount(async () => userStore.getUsers());

    function userDisplay(uid: string) {
      return userStore.findUser(uid)?.display_name || uid;
    }

    function userAvatar(uid: string) {
      return userStore.findUser(uid)?.avatar_url;
    }

    function enrollDialog(details: { index: number; value: FG.User }) {
      service.value = {
        userid: details.value.userid,
        is_backup: false,
        value: 1,
      };
      dialog.value = true;
    }
    function iam(uid: string) {
      return uid === mainStore.currentUser.userid;
    }

    async function enroll(transfer = false, invite = false) {
      try {
        dialog.value = false;
        if (transfer)
          service.value = Object.assign({}, service.value, {
            replace: mainStore.currentUser.userid,
          });
        // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
        else if (invite) delete (<any>service.value).value;
        const job = await store.updateJob(props.eventId, props.modelValue.id, {
          user: <FG.Service>service.value,
        });
        emit('update:modelValue', job);
      } catch (error) {
        console.warn(error);
        Notify.create({
          group: false,
          type: 'negative',
          message: 'Fehler beim Eintragen als Dienst',
          timeout: 10000,
          progress: true,
          actions: [{ icon: 'mdi-close', color: 'white' }],
        });
      }
    }

    async function remove(service: FG.Service, rem: (i: number) => void, index: number) {
      if (
        service.userid === mainStore.currentUser.userid ||
        hasPermission(PERMISSIONS.ASSIGN_OTHER)
      ) {
        rem(index);
        try {
          const job = await store.updateJob(props.eventId, props.modelValue.id, {
            user: Object.assign({}, service, { value: -service.value }),
          });
          emit('update:modelValue', job);
        } catch (error) {
          console.warn(error);
          Notify.create({
            group: false,
            type: 'negative',
            message: 'Fehler beim Austragen als Dienst',
            timeout: 10000,
            progress: true,
            actions: [{ icon: 'mdi-close', color: 'white' }],
          });
        }
      }
    }

    const options = computed(() =>
      hasPermission(PERMISSIONS.ASSIGN_OTHER)
        ? userStore.users.filter((v) => !enrolled(v.userid))
        : !isEnrolled.value
        ? [mainStore.currentUser]
        : []
    );

    function canEdit(uid: string) {
      return uid === mainStore.currentUser.userid || hasPermission(PERMISSIONS.ASSIGN_OTHER);
    }

    function enrolled(userid: string) {
      return props.modelValue.services.findIndex((service) => service.userid == userid) !== -1;
    }
    const isEnrolled = computed(() => enrolled(mainStore.currentUser.userid));

    const canEnroll = computed(() => {
      const is = isEnrolled.value;
      let sum = 0;
      props.modelValue.services.forEach((s) => (sum += s.value));
      return sum < props.modelValue.required_services && !is;
    });

    return {
      enroll,
      availableUsers,
      canEdit,
      isEnrolled,
      enrolled,
      enrollDialog,
      canEnroll,
      remove,
      userAvatar,
      userDisplay,
      options,
      iam,
      dialog,
      service,
      asHour,
      asDate,
    };
  },
});
</script>

<style scoped></style>
