<script lang="ts">
import { computed, shallowRef, watch, type PropType } from 'vue';
import InputEvent from '../../../../../../components/InputEvent.vue';
import { inject, keys as injectionKeys } from '../../../../../../injection';
import {
  eventToEventInput, type Event,
} from '../../../../../../composables/eventstore';
import { getResourceDisplayText } from '../../../../../../common/zkan-utils';

export default {
  name: 'PagesMasterTimetableResourcesIdTimelineeventinput_EventEditDialog',
  components: { InputEvent },
  props: {
    open: { type: Boolean, required: true },
    event: { type: [Object, null] as PropType<Event | null>, required: true },
  },
  emits: {
    run: () => true,
    'update:open': (value: boolean) => true,
    'update:event': (value: Event | null) => true,
  },
  setup(props, { emit }) {
    const handleError = inject(injectionKeys.errorHandler).handleErrorAsync;
    const eventStore = inject(injectionKeys.eventStore);

    const open = computed({
      get: () => props.open, set: value => emit('update:open', value),
    })
    const eventID = shallowRef(props.event?.id ?? null);
    const inputEvent = shallowRef(props.event);
    const inputEventInvalid = shallowRef(false);
    watch(() => props.event, () => {
      eventID.value = props.event?.id ?? null;
      inputEvent.value = props.event;
    });

    const submit = handleError(async () => {
      if(!inputEvent.value || inputEventInvalid.value) return;
      const eventParam = eventToEventInput(inputEvent.value);
      if(eventID.value) {
        await eventStore.mutate([{ opcode: 'update_event', param: {
          ...eventParam, id: eventID.value,
        }}]);
      } else {
        await eventStore.mutate([{ opcode: 'add_event', param: {
          ...eventParam,
        }}]);
      }
      emit('run');
    });

    const deleteEvent = handleError(async () => {
      if(!eventID.value) return;
      await eventStore.mutate([{ opcode: 'remove_event', param: {
        id: eventID.value,
      } }]);
      emit('run');
    });

    return {
      getResourceDisplayText, createOrUpdate: computed(
        () => eventID.value ? 'update' : 'create'
      ), open, inputEvent, inputEventInvalid, submit, deleteEvent,
    };
  },
}
</script>

<template>
<app-dialog v-model:open="open">
  <p
    v-if="event?.eventChangeTo && event.eventChangeTo.toEvent == null"
  >
    このイベントは取消済みです<br />
    原因リソース: {{
      event.eventChangeTo.causeResources.map(
        getResourceDisplayText
      ).join(', ')
    }}
  </p>
  <p
    v-if="event?.eventChangeTo && event.eventChangeTo.toEvent != null"
  >
    このイベントは<EventLink :event="event.eventChangeTo.toEvent">別のイベント</EventLink>に振替済みです<br />
    原因リソース: {{
      event.eventChangeTo.causeResources.map(
        getResourceDisplayText
      ).join(', ')
    }}
  </p>
  <p
    v-if="event?.eventChangeFrom"
  >
    このイベントは<EventLink :event="event.eventChangeFrom.fromEvent">別のイベント</EventLink>の振替先です<br />
    原因リソース: {{
      event.eventChangeFrom.causeResources.map(
        getResourceDisplayText
      ).join(', ')
    }}
  </p>
  <form @submit.prevent="submit()">
    <p>
      <button
        v-if="createOrUpdate === 'update'" type="button" @click="deleteEvent()"
      >このイベントを削除</button>
    </p>
    <input-event
      v-if="inputEvent" v-model="inputEvent" v-model:invalid="inputEventInvalid"
    />
    <div style="display: flex; gap: 1em;">
      <button :disabled="inputEventInvalid">
        {{ createOrUpdate === 'update' ? '変更' : '追加' }}
      </button>
    </div>
  </form>
</app-dialog>
</template>
