<script lang="ts">
import { Date, DateTime, time, timedelta } from '@silane/datetime';
import { computed, ref, shallowRef, watch } from 'vue';

import EventList from './index/_EventList.vue';
import { inject, keys as injectionKeys } from '../../../../../injection';
import {
  comparerByKey, datetimeRange, groupBy,
} from '../../../../../common/utils.js';
import { getResourceDisplayText } from '../../../../../common/zkan-utils.js';
import { resourceOrdering } from '../../../../../composables/resourcestore';
import type { Event } from '../../../../../composables/eventstore';

export default {
  name: 'PageMasterTimetableResourcesIdIndex',
  components: { EventList },
  props: {
    id: { type: String, required: true },
  },
  setup(props) {
    const handleError = inject(injectionKeys.errorHandler).handleErrorAsync;
    const resourceStore = inject(injectionKeys.resourceStore);
    const eventStore = inject(injectionKeys.eventStore);
    const generalTimetableScope = inject(injectionKeys.generalTimetableScope);

    const resource = computed(() => resourceStore.resources.value.find(
      x => x.id === props.id
    ) ?? null);
    const dates = computed(() => [...datetimeRange(
      ...generalTimetableScope.dateRange.value, timedelta({ days: 1 })
    )]);

    const eventView = ref<'date' | 'course'>('date');

    const downloadedEvents = shallowRef<Event[]>([]);
    watch(generalTimetableScope.dateRange, handleError(async () => {
      downloadedEvents.value = await eventStore.query({
        startTime: DateTime.combine(
          generalTimetableScope.dateRange.value[0], time()
        ), endTime: DateTime.combine(
          generalTimetableScope.dateRange.value[1], time()
        ),
      });
    }), { immediate: true });

    const events = computed(
      () => resource.value ? downloadedEvents.value.filter(x => [
        generalTimetableScope.classroom.value, resource.value!.id
      ].every(r => x.resources.some(x => x.id === r))) : []
    );

    return {
      comparerByKey, groupBy, getResourceDisplayText, resourceOrdering,
      today: Date.today(), classroom: generalTimetableScope.classroom,
      resource, dates, eventView, events,
    };
  },
}
</script>

<template>
<template v-if="resource">
<h1>{{ getResourceDisplayText(resource) }}</h1>
<nav>
  <ul>
    <li v-if="['teacher', 'student'].includes(resource.type)">
      <router-link :to="`./timeline`">時間割表</router-link>
    </li>
    <li><router-link :to="`./resourcehours`">可能時間入力</router-link></li>
    <li v-if="resource.type === 'teacher'">
      <router-link :to="`./lessons`">授業入力</router-link>
    </li>
    <li v-if="['teacher', 'student'].includes(resource.type)">
      <router-link to="./timelineeventinput">時間割表イベント入力</router-link>
    </li>
  </ul>
</nav>
<p v-if="events.length === 0">イベントはありません</p>
<template v-else>
  <p>
    このリソースが原因となる取消または振替の数: {{ events.filter(e => (
      e.eventChangeTo?.causeResources.some(r => r.id === resource!.id) ?? false
    )).length }}
  </p>
  <label>
    <input type="radio" name="eventView" v-model="eventView" value="date" />
    日付別イベント
  </label>
  <label v-if="['teacher', 'student'].includes(resource.type)">
    <input type="radio" name="eventView" v-model="eventView" value="course" />
    {{ resource.type === 'teacher' ? '生徒・教科別イベント' : '教科別イベント' }}
  </label>
  <section v-show="eventView === 'date'">
    <h1>日付別イベント</h1>
    <table>
      <thead><tr><th>日付</th><th>イベント</th></tr></thead>
      <tbody>
        <tr v-for="date of dates" :key="date.isoFormat()">
          <th>
            <date-time :value="date" :class="{
              'date-saturday': date.weekday() === 5,
              'date-sunday': date.weekday() === 6,
              'date-today': date.isoFormat() === today.isoFormat(),
            }" />
          </th>
          <td>
            <ol style="display: flex; flex-wrap: wrap; gap: 1em; list-style: none; margin: 0;">
              <li v-for="e of events.filter(
                x => x.startTime.date().isoFormat() === date.isoFormat()
              )">
                <event-link :event="e" class="eventchip" :style="{
                  textDecoration: e.eventChangeTo ? 'line-through' : undefined,
                  backgroundColor: e.color,
                }">
                  {{ e.type === 'standard' ? 'イベント' : undefined }}
                  {{ e.timeLabel?.label ?? '' }}
                  {{ e.type === 'lesson' ? e.subject : '' }}
                  {{ e.resources.filter(
                    x => ![classroom, resource?.id].includes(x.id)
                  ).map(getResourceDisplayText).join(',') }}
                  {{ e.type === 'lesson' ? e.frame : '' }} {{ e.memo }}
                </event-link>
              </li>
            </ol>
          </td>
        </tr>
      </tbody>
    </table>
  </section>
  <section v-if="resource.type === 'teacher'" v-show="eventView === 'course'">
    <h1>生徒・教科別イベント</h1>
    <section v-if="events.some(x => x.type !== 'lesson')">
      <h1>[授業以外のイベント]</h1>
      <event-list
        :events="events.filter(x => x.type !== 'lesson')"
        :excludeResourceIDs="[
          classroom, resource.id,
        ].filter((x): x is string => x != null)"
      />
    </section>
    <section v-for="{ key: student, items: itemsByStudent } of groupBy(
      events.filter(
        (e): e is Extract<Event, { type: 'lesson' }> => e.type === 'lesson'
      ), e => e.resources.find(x => x.type === 'student') ?? null
    ).sort(comparerByKey(
      x => x.key == null ? [false] : [true, resourceOrdering(x.key)]
    ))">
      <h1>{{ student ? getResourceDisplayText(student) : '[生徒無し]' }}</h1>
      <section v-for="{ key: subject, items } of groupBy(
        itemsByStudent, e => e.subject
      ).sort(comparerByKey(x => x.key))">
        <h1>{{ subject }}</h1>
        <event-list :events="items" :excludeResourceIDs="[
          classroom, resource.id, student?.id,
        ].filter((x): x is string => x != null)" />
      </section>
    </section>
  </section>
  <section v-if="resource.type === 'student'" v-show="eventView === 'course'">
    <h1>教科別イベント</h1>
    <section v-for="{ key, items } of groupBy(
      events, e => e.type === 'lesson' ? e.subject : null
    ).sort(comparerByKey(
      x => x.key == null ? [false] : [true, x.key]
    ))" :key="key ?? 0">
      <h1>{{ key ?? '[授業以外のイベント]' }}</h1>
      <event-list :events="items" :excludeResourceIDs="[
        classroom, resource.id,
      ].filter((x): x is string => x != null)" />
    </section>
  </section>
</template>
</template>
<p v-else>リソースが見つかりません。</p>
</template>

<style scoped>
.date-saturday {
  color: darkblue;
}
.date-sunday {
  color: tomato;
}
.date-today {
  border-radius: .5em;
  padding: .2em;
  background-color: deepskyblue;
}

.eventchip {
  padding: 0 .5em;
  border-radius: .5em;
}
.eventchip::v-deep(a) {
  all: inherit;
}
</style>
