<template>
  <q-card-section>
    <div class="text-caption text-justify">
      Use the calendar to pick a date. Tap a box in the grid for the boat and
      start time. Select the duration below.
    </div>
    <div style="width: 100%; display: flex; justify-content: center">
      <div
        style="
          width: 50%;
          max-width: 350px;
          display: flex;
          justify-content: space-between;
        "
      >
        <span
          class="q-button"
          style="cursor: pointer; user-select: none"
          @click="onPrev"
          >&lt;</span
        >
        {{ formattedMonth }}
        <span
          class="q-button"
          style="cursor: pointer; user-select: none"
          @click="onNext"
          >&gt;</span
        >
      </div>
    </div>
    <div
      style="
        display: flex;
        justify-content: center;
        align-items: center;
        flex-wrap: nowrap;
      "
    >
      <div style="display: flex; width: 100%">
        <q-calendar-month
          ref="calendar"
          v-model="selectedDate"
          :disabled-before="disabledBefore"
          animated
          bordered
          mini-mode
          date-type="rounded"
          @change="onChange"
          @moved="onMoved"
          @click-date="onClickDate"
        />
      </div></div
  ></q-card-section>
  <q-calendar-resource
    v-model="selectedDate"
    :model-resources="boatStore.boats"
    resource-key="id"
    resource-label="displayName"
    resource-width="32"
    :interval-start="12"
    :interval-count="36"
    :interval-minutes="30"
    cell-width="48"
    style="--calendar-resources-width: 48px"
    resource-min-height="40"
    animated
    bordered
    @change="onChange"
    @moved="onMoved"
    @resource-expanded="onResourceExpanded"
    @click-date="onClickDate"
    @click-time="onClickTime"
    @click-resource="onClickResource"
    @click-head-resources="onClickHeadResources"
    @click-interval="onClickInterval"
  >
    <template #resource-intervals="{ scope }">
      <template v-for="(event, index) in getEvents(scope)" :key="index">
        <q-badge outline :label="event.title" :style="getStyle(event)" />
      </template>
    </template>

    <template #resource-label="{ scope: { resource } }">
      <div class="col-12 .col-md-auto">
        {{ resource.displayName }}
        <q-icon v-if="resource.defects" name="warning" color="warning" />
      </div>
    </template>
  </q-calendar-resource>

  <q-card-section>
    <q-select
      filled
      v-model="duration"
      :options="durations"
      dense
      @update:model-value="onUpdateDuration"
      label="Duration (hours)"
      stack-label
      ><template v-slot:append><q-icon name="timelapse" /></template></q-select
  ></q-card-section>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import {
  QCalendarResource,
  TimestampOrNull,
  today,
  parseDate,
  parseTimestamp,
  addToDate,
  Timestamp,
} from '@quasar/quasar-ui-qcalendar';
import { Boat, useBoatStore } from 'src/stores/boat';
import { useScheduleStore } from 'src/stores/schedule';
import { date } from 'quasar';
import { computed } from 'vue';

const durations = [1, 1.5, 2, 2.5, 3, 3.5, 4];

type ResourceIntervalScope = {
  resource: Boat;
  intervals: [];
  timeStartPosX(start: TimestampOrNull): number;
  timeDurationWidth(duration: number): number;
};

const statusLookup = {
  confirmed: ['#14539a', 'white'],
  pending: ['#f2c037', 'white'],
  tentative: ['white', 'grey'],
};

const calendar = ref();
const boatStore = useBoatStore();
const scheduleStore = useScheduleStore();
const selectedDate = ref(today());
const duration = ref(1);

const formattedMonth = computed(() => {
  const date = new Date(selectedDate.value);

  return monthFormatter()?.format(date);
});
const disabledBefore = computed(() => {
  const todayTs = parseTimestamp(today()) as Timestamp;
  return addToDate(todayTs, { day: -1 }).date;
});

function monthFormatter() {
  try {
    return new Intl.DateTimeFormat('en-CA' || undefined, {
      month: 'long',
      timeZone: 'UTC',
    });
  } catch (e) {
    //
  }
}

function getEvents(scope: ResourceIntervalScope) {
  const resourceEvents = scheduleStore.getBoatReservations(
    scope.resource.id,
    date.extractDate(selectedDate.value, 'YYYY-MM-DD')
  );

  return resourceEvents.map((event) => {
    return {
      left: scope.timeStartPosX(parseDate(event.start)),
      width: scope.timeDurationWidth(
        date.getDateDiff(event.end, event.start, 'minutes')
      ),
      title: event.user,
      status: event.status,
    };
  });
}

function getStyle(event: {
  left: number;
  width: number;
  title: string;
  status: 'tentative' | 'confirmed' | 'pending';
}) {
  return {
    position: 'absolute',
    background: event.status ? statusLookup[event.status][0] : 'white',
    color: event.status ? statusLookup[event.status][1] : '#14539a',
    left: `${event.left}px`,
    width: `${event.width}px`,
    height: '32px',
    overflow: 'hidden',
  };
}

const emit = defineEmits(['onClickTime', 'onUpdateDuration']);

function onPrev() {
  calendar.value.prev();
}
function onNext() {
  calendar.value.next();
}
function onClickDate(data) {
  return;
}
function onClickTime(data) {
  // TODO: Add a duration picker, here.
  emit('onClickTime', data);
}
function onUpdateDuration(value) {
  emit('onUpdateDuration', value);
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
const onClickInterval = () => {};
// eslint-disable-next-line @typescript-eslint/no-empty-function
const onClickHeadResources = () => {};
// eslint-disable-next-line @typescript-eslint/no-empty-function
const onClickResource = () => {};
// eslint-disable-next-line @typescript-eslint/no-empty-function
const onResourceExpanded = () => {};
// eslint-disable-next-line @typescript-eslint/no-empty-function
const onMoved = () => {};
// eslint-disable-next-line @typescript-eslint/no-empty-function
const onChange = () => {};
</script>
