<script>
import { ref, computed } from 'vue';
import { cmp } from '@silane/datetime';

import { comparerByKey, deleteUndefinedProperties } from '../../../common/utils.js';
import { inject, keys as injectionKeys } from '../../../injection';


export default {
  name: 'PageMasterConfigTimelabel',
  setup() {
    const notification = inject(injectionKeys.notification);
    const handleError = inject(injectionKeys.errorHandler).handleErrorAsync;
    const timeLabelStore = inject(injectionKeys.timeLabelStore);

    const timeLabels = ref([]);
    const timeLabelErrors = computed(() => {
      const notDeletedItems = timeLabels.value.filter(x => !x.deleted);
      const ret = [];
      ret.push(...notDeletedItems.filter(x => !x.label).map(x => ({
        item: x, code: 'novalue', property: 'label'
      })));
      ret.push(...notDeletedItems.filter(x => !x.startTime).map(x => ({
        item: x, code: 'novalue', property: 'startTime'
      })));
      ret.push(...notDeletedItems.filter(x => !x.endTime).map(x => ({
        item: x, code: 'novalue', property: 'endTime'
      })));
      ret.push(...notDeletedItems.filter(
        x => x.startTime && x.endTime && cmp(x.startTime, x.endTime) >= 0
      ).map(x => ({
          item: x, code: 'negativeduration',
      })));
      return ret;
    });

    const load = handleError(async () => {
      await timeLabelStore.load();
      timeLabels.value = timeLabelStore.timeLabels.value.map(x => ({
        id: x.id, startTime: x.startTime, endTime: x.endTime,
        label: x.label, disabled: x.disabled, deleted: false,
      }));
      sort();
    });
    load();

    function add() {
      timeLabels.value.push({
        id: null, startTime: null, endTime: null, label: '', disabled: false,
        deleted: false,
      });
    }

    function sort() {
      timeLabels.value.sort(comparerByKey(x => x.label));
    }

    const save = handleError(async () => {
      if(timeLabelErrors.value.length) {
        notification.add('error', '入力欄にエラーがあります。修正してください。');
        return;
      }

      const toAddItems = timeLabels.value.filter(
        x => x.id == null && !x.deleted
      );
      const toUpdateItems = timeLabels.value.filter(
        x => x.id != null && !x.deleted
      );
      const toRemoveItems = timeLabels.value.filter(
        x => x.id != null && x.deleted
      );

      if(toRemoveItems.length) {
        if(!confirm('いくつかの時間帯が削除されます。それらの時間帯が指定されたイベントは時間帯指定なしの任意時刻入力として扱われるようになります。本当に削除しますか？')) {
          return;
        }
      }

      await timeLabelStore.mutate(toAddItems.map(x => ({
        opcode: 'add', param: deleteUndefinedProperties(
          { ...x, deleted: undefined }
        ),
      })).concat(toUpdateItems.map(x => ({
        opcode: 'update', param: deleteUndefinedProperties(
          { ...x, deleted: undefined }
        ),
      })), toRemoveItems.map(x => ({
        opcode: 'remove', param: { id: x.id },
      }))));

      notification.add('info', '保存しました。');

      await load();
    });

    return { timeLabels, timeLabelErrors, load, add, sort, save };
  }
}
</script>

<template>
  <h1>時間帯登録</h1>
  <p>「チェックして保存」ボタンを押さない限り変更は保存されません！</p>
  <table>
    <thead>
      <tr>
        <th>ID</th><th>ラベル</th><th>開始時刻</th><th>終了時刻</th>
        <th>非表示</th><th>操作</th>
      </tr>
    </thead>
    <tbody>
      <template v-for="x of timeLabels" :key="x.id">
        <tr v-if="!x.deleted">
          <th :title="x.id">
            {{ x.id ? `...${x.id.slice(-4)}` : '[未割当]' }}
          </th>
          <td>
            <input v-model="x.label" />
          </td>
          <td>
            <template v-if="x.id == null">
              <input-time v-model="x.startTime" />
            </template>
            <date-time v-else :value="x.startTime" />
          </td>
          <td>
            <template v-if="x.id == null">
              <input-time v-model="x.endTime" />
            </template>
            <date-time v-else :value="x.endTime" />
          </td>
          <td>
            <input type="checkbox" v-model="x.disabled" />
          </td>
          <td>
            <button type="button" @click="x.deleted = true;">
              削除
            </button>
          </td>
        </tr>
      </template>
    </tbody>
  </table>

  <button type="button" @click="add()">追加</button>
  <button type="button" @click="sort()">ソート</button>

  <ul>
    <li v-for="error, idx of timeLabelErrors" :key="idx">
      {{
        error.code === 'novalue'
        ? `${timeLabels.filter(x => !x.deleted).indexOf(error.item) + 1}番目の${
          {
            label: 'ラベル', startTime: '開始時刻', endTime: '終了時刻',
          }[error.property]
        }が指定されていません`
        : `${
          timeLabels.filter(x => !x.deleted).indexOf(error.item) + 1
        }番目の終了時刻が開始時刻よりも前か同じです`
      }}
    </li>
  </ul>

  <p><button type="button" @click="save()">チェックして保存</button></p>
  <p><button type="button" @click="load()">リセット</button></p>
</template>
