<template>
  <q-page padding>
    <q-card>
      <q-form @submit="save()" @reset="reset">
        <q-card-section class="fit row justify-start content-center items-center">
          <div class="text-h6 col-xs-12 col-sm-6 q-pa-sm">Veranstaltung erstellen</div>
          <q-select
            :model-value="template"
            filled
            label="Vorlage"
            class="col-xs-12 col-sm-6 q-pa-sm"
            :options="templates"
            option-label="name"
            map-options
            clearable
            :disable="templates.length == 0"
            @update:modelValue="fromTemplate"
            @clear="reset()"
          />
          <q-input
            v-model="event.name"
            class="col-xs-12 col-sm-6 q-pa-sm"
            label="Name"
            type="text"
            filled
          />
          <q-select
            v-model="event.type"
            filled
            use-input
            label="Veranstaltungstyp"
            input-debounce="0"
            class="col-xs-12 col-sm-6 q-pa-sm"
            :options="eventtypes"
            option-label="name"
            option-value="id"
            emit-value
            map-options
            clearable
            :rules="[notEmpty]"
          />
          <IsoDateInput
            v-model="event.start"
            class="col-xs-12 col-sm-6 q-pa-sm"
            label="Veranstaltungsbeginn"
            :rules="[notEmpty]"
          />
          <IsoDateInput
            v-model="event.end"
            class="col-xs-12 col-sm-6 q-pa-sm"
            label="Veranstaltungsende"
          />
          <q-input
            v-model="event.description"
            class="col-12 q-pa-sm"
            label="Beschreibung"
            type="textarea"
            filled
          />
        </q-card-section>
        <q-card-section v-if="event.template_id === undefined">
          <q-btn-toggle
            v-model="recurrent"
            spread
            no-caps
            :options="[
              { label: 'Einmalig', value: false },
              { label: 'Wiederkehrend', value: true },
            ]"
          />
          <RecurrenceRule v-if="!!recurrent" v-model="recurrenceRule" />
        </q-card-section>
        <q-separator />
        <q-card-section>
          <q-btn color="primary" label="Schicht hinzufügen" @click="addJob()" />
        </q-card-section>
        <q-card-section v-for="(job, index) in event.jobs" :key="index">
          <q-card class="q-my-auto">
            <job
              v-model="event.jobs[index]"
              :job-can-delete="jobDeleteDisabled"
              @remove-job="removeJob(index)"
            />
          </q-card>
        </q-card-section>
        <q-card-actions align="right">
          <q-btn label="Reset" type="reset" />
          <q-btn color="secondary" label="Neue Vorlage" @click="save(true)" />
          <q-btn color="primary" type="submit" label="Erstellen" />
        </q-card-actions>
      </q-form>
    </q-card>
  </q-page>
</template>

<script lang="ts">
import { defineComponent, ref, onBeforeMount, computed } from 'vue';
import IsoDateInput from 'src/components/utils/IsoDateInput.vue';
import Job from './Job.vue';
import RecurrenceRule from './RecurrenceRule.vue';
import { date, ModifyDateOptions } from 'quasar';
import { useScheduleStore } from '../../store';
import { notEmpty } from 'src/utils/validators';

export default defineComponent({
  name: 'CreateEvent',
  components: { IsoDateInput, Job, RecurrenceRule },
  setup() {
    const store = useScheduleStore();

    const emptyJob = {
      id: NaN,
      start: new Date(),
      end: date.addToDate(new Date(), { hours: 1 }),
      services: [],
      required_services: 2,
      type: store.jobTypes[0],
    };

    const emptyEvent = {
      id: NaN,
      start: new Date(),
      jobs: [Object.assign({}, emptyJob)],
      type: store.eventTypes[0],
      is_template: false,
    };

    const templates = computed(() => store.templates);
    const template = ref<FG.Event | undefined>(undefined);
    const event = ref<FG.Event>(Object.assign({}, emptyEvent));
    const eventtypes = computed(() => store.eventTypes);
    const jobDeleteDisabled = computed(() => event.value.jobs.length < 2);
    const recurrent = ref(false);
    const recurrenceRule = ref<FG.RecurrenceRule>({ frequency: 'daily', interval: 1 });

    onBeforeMount(() => {
      void store.getEventTypes();
      void store.getJobTypes();
      void store.getTemplates();
    });

    function addJob() {
      event.value.jobs.push(Object.assign({}, emptyJob));
    }

    function removeJob(index: number) {
      event.value.jobs.splice(index, 1);
    }

    function fromTemplate(tpl: FG.Event) {
      template.value = tpl;
      event.value = Object.assign({}, tpl);
    }

    async function save(template = false) {
      console.log(template);
      event.value.is_template = template;
      try {
        await store.addEvent(event.value);
        if (recurrent.value && !event.value.is_template) {
          let count = 0;
          const options: ModifyDateOptions = {};
          switch (recurrenceRule.value.frequency) {
            case 'daily':
              options['days'] = 1 * recurrenceRule.value.interval;
              break;
            case 'weekly':
              options['days'] = 7 * recurrenceRule.value.interval;
              break;
            case 'monthly':
              options['months'] = 1 * recurrenceRule.value.interval;
              break;
          }
          while (true) {
            event.value.start = date.addToDate(event.value.start, options);
            if (event.value.end) event.value.end = date.addToDate(event.value.end, options);
            event.value.jobs.forEach((job) => {
              job.start = date.addToDate(job.start, options);
              if (job.end) job.end = date.addToDate(job.end, options);
            });
            count++;
            if (
              count <= 120 &&
              (!recurrenceRule.value.count || count <= recurrenceRule.value.count) &&
              (!recurrenceRule.value.until || event.value.start < recurrenceRule.value.until)
            )
              await store.addEvent(event.value);
            else break;
          }
        }
        reset();
      } catch (error) {
        console.error(error);
      }
    }

    function reset() {
      event.value = Object.assign({}, emptyEvent);
      template.value = undefined;
    }

    return {
      jobDeleteDisabled,
      addJob,
      eventtypes,
      templates,
      removeJob,
      notEmpty,
      save,
      reset,
      recurrent,
      fromTemplate,
      template,
      recurrenceRule,
      event,
    };
  },
});
</script>

<style></style>