<script>
import { ref, computed } from 'vue';

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


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

    const resources = ref([]);
    const resourceErrors = computed(() => {
      const notDeletedItems = resources.value.filter(x => !x.deleted);
      const ret = [];
      ret.push(...notDeletedItems.filter(x => !x.label).map(x => ({
        item: x, code: 'novalue', property: 'label'
      })));
      return ret;
    });

    const load = handleError(async () => {
      await resourceStore.load();
      resources.value = resourceStore.resources.value.filter(
        x => x.type === 'classroom'
      ).map(x => ({
        id: x.id, disabled: x.disabled, label: x.label, deleted: false,
      }));
    });
    load();

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

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

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

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

      if(toRemoveItems.length) {
        if(!confirm('いくつかの教室が削除されます。削除する教室が指定されたイベントがある場合、それらのイベントにアクセスする手段は無くなります。本当に削除しますか？')) {
          return;
        }
      }

      await resourceStore.mutate(toAddItems.map(x => ({
        opcode: 'add_resource', param: {
          multiplicity: -1, disabled: x.disabled, type: 'classroom',
          label: x.label,
        },
      })).concat(toUpdateItems.map(x => ({
        opcode: 'update_resource', param: {
          id: x.id, multiplicity: 1, disabled: x.disabled, type: 'classroom',
          label: x.label,
        },
      })), toRemoveItems.map(x => ({
        opcode: 'remove_resource', param: { id: x.id },
      }))));

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

      await load();
    });

    return {
      resources, resourceErrors, load, add, sort, save,
    };
  }
}
</script>

<template>
  <h1>教室登録</h1>
  <p>「チェックして保存」ボタンを押さない限り変更は保存されません！</p>
  <table>
    <thead>
      <tr>
        <th>ID</th><th>名前</th><th>非表示</th><th>操作</th>
      </tr>
    </thead>
    <tbody>
      <template v-for="x of resources" :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>
            <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 resourceErrors" :key="idx">
      {{
        `${resources.filter(x => !x.deleted).indexOf(error.item) + 1}番目の${{
          label: '名前',
        }[error.property]}が指定されていません`
      }}
    </li>
  </ul>

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