<template>
  <div class="q-pa-xs row q-gutter-xs">
    <q-card
      flat
      class="col-lg-4 col-md-6 col-sm-8 col-xs-12">
      <q-card-section>
        <div class="text-h5 q-mt-none q-mb-xs">
          {{ reservation ? 'Modify Booking' : 'New Booking' }}
        </div>
        <div class="text-caption text-grey-8">for: {{ bookingName }}</div>
      </q-card-section>
      <q-list class="q-px-xs">
        <q-item
          class="q-pa-none"
          clickable
          @click="boatSelect = true">
          <q-card
            v-if="boat"
            class="col-12">
            <q-card-section>
              <q-img
                :src="boat.imgSrc"
                :fit="'scale-down'">
                <div class="row absolute-top">
                  <div class="col text-h7 text-left">
                    {{ boat.name }}
                  </div>
                  <div class="col text-right text-caption">
                    {{ boat.class }}
                  </div>
                </div>
              </q-img>
            </q-card-section>
            <q-separator />
            <q-card-section horizontal>
              <q-card-section class="col-9">
                <q-list
                  dense
                  class="row">
                  <q-item class="q-ma-none col-12">
                    <q-item-section avatar>
                      <q-badge
                        color="primary"
                        label="Start" />
                    </q-item-section>
                    <q-item-section class="text-body2">
                      {{ formatDate(bookingForm.interval?.start) }}
                    </q-item-section>
                  </q-item>
                  <q-item class="q-ma-none col-12">
                    <q-item-section avatar>
                      <q-badge
                        color="primary"
                        label="End" />
                    </q-item-section>
                    <q-item-section
                      class="text-body2"
                      style="min-width: 150px">
                      {{ formatDate(bookingForm.interval?.end) }}
                    </q-item-section>
                  </q-item>
                </q-list>
              </q-card-section>
              <q-separator vertical />
              <q-card-section class="col-3 flex flex-center bg-grey-4">
                {{ bookingDuration.hours }} hours
                <div v-if="bookingDuration.minutes">
                  <q-separator />
                  {{ bookingDuration.minutes }} mins
                </div>
              </q-card-section>
            </q-card-section>
          </q-card>
          <div
            v-else
            class="col-12">
            <q-field filled>Tap to Select a Boat / Time</q-field>
          </div>
        </q-item>
        <q-item class="q-px-none">
          <q-item-section>
            <q-select
              filled
              v-model="bookingForm.reason"
              :options="reason_options"
              label="Reason for sail" />
          </q-item-section>
        </q-item>
        <q-item class="q-px-none">
          <q-item-section>
            <q-input
              v-model="bookingForm.comment"
              clearable
              autogrow
              filled
              label="Additional Comments (optional)" />
          </q-item-section>
        </q-item>
      </q-list>
      <q-card-actions align="right">
        <q-btn
          label="Delete"
          color="negative"
          size="lg"
          v-if="reservation?.$id"
          @click="onDelete" />
        <q-btn
          label="Reset"
          @click="onReset"
          size="lg"
          color="secondary" />
        <q-btn
          label="Submit"
          @click="onSubmit"
          size="lg"
          color="primary" />
      </q-card-actions>
    </q-card>
    <q-dialog
      v-model="boatSelect"
      full-width>
      <BoatScheduleTableComponent
        :model-value="bookingForm.interval"
        @update:model-value="updateInterval" />
    </q-dialog>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { useAuthStore } from 'src/stores/auth';
import { Boat, useBoatStore } from 'src/stores/boat';
import { Interval, Reservation } from 'src/stores/schedule.types';
import BoatScheduleTableComponent from 'src/components/scheduling/boat/BoatScheduleTableComponent.vue';
import { formatDate } from 'src/utils/schedule';
import { useReservationStore } from 'src/stores/reservation';
import { useQuasar } from 'quasar';
import { useRouter } from 'vue-router';

interface BookingForm {
  $id?: string;
  user?: string;
  interval?: Interval | null;
  reason?: string;
  members?: string[];
  guests?: string[];
  comment?: string;
}

const reason_options = ['Open Sail', 'Private Sail', 'Racing', 'Other'];

const boatStore = useBoatStore();
const auth = useAuthStore();
const newForm = {
  user: auth.currentUser?.$id,
  interval: {} as Interval,
  reason: 'Open Sail',
  members: [],
  guests: [],
  comment: '',
};
const reservation = defineModel<Reservation>();
const reservationStore = useReservationStore();
const boatSelect = ref(false);
const bookingForm = ref<BookingForm>({ ...newForm });
const $q = useQuasar();
const $router = useRouter();

watch(reservation, (newReservation) => {
  if (!newReservation) {
    bookingForm.value = newForm;
  } else {
    const updatedReservation = {
      ...newReservation,
      user: auth.currentUser?.$id,
      interval: {
        start: newReservation.start,
        end: newReservation.end,
        resource: newReservation.resource,
      },
    };
    bookingForm.value = updatedReservation;
  }
});

const updateInterval = (interval: Interval | null) => {
  bookingForm.value.interval = interval;
  boatSelect.value = false;
};

const bookingDuration = computed((): { hours: number; minutes: number } => {
  if (bookingForm.value.interval?.start && bookingForm.value.interval?.end) {
    const start = new Date(bookingForm.value.interval.start).getTime();
    const end = new Date(bookingForm.value.interval.end).getTime();
    const delta = Math.abs(end - start) / 1000;
    const hours = Math.floor(delta / 3600) % 24;
    const minutes = Math.floor(delta - hours * 3600) % 60;
    return { hours: hours, minutes: minutes };
  }
  return { hours: 0, minutes: 0 };
});

const bookingName = computed(() =>
  auth.getUserNameById(bookingForm.value?.user)
);

const boat = computed((): Boat | null => {
  const boatId = bookingForm.value.interval?.resource;
  return boatStore.getBoatById(boatId);
});

const onDelete = () => {
  reservationStore.deleteReservation(reservation.value?.$id);
  $router.go(-1);
};

const onReset = () => {
  bookingForm.value.interval = null;
  bookingForm.value = reservation.value
    ? {
        ...reservation.value,
        interval: {
          start: reservation.value.start,
          end: reservation.value.end,
          resource: reservation.value.resource,
        },
      }
    : { ...newForm };
};

const onSubmit = async () => {
  const booking = bookingForm.value;
  if (
    !(
      booking.interval &&
      booking.interval.resource &&
      booking.interval.start &&
      booking.interval.end &&
      auth.currentUser
    )
  ) {
    // TODO: Make a proper validator
    return false;
  }
  const newReservation = <Reservation>{
    resource: booking.interval.resource,
    start: booking.interval.start,
    end: booking.interval.end,
    user: auth.currentUser.$id,
    status: 'confirmed',
    reason: booking.reason,
    comment: booking.comment,
    $id: reservation.value?.$id,
  };
  const status = $q.notify({
    color: 'secondary',
    textColor: 'white',
    message: 'Submitting Reservation',
    spinner: true,
    closeBtn: 'Dismiss',
    position: 'top',
    timeout: 0,
    group: false,
  });
  try {
    const r = await reservationStore.createOrUpdateReservation(newReservation);
    status({
      color: 'positive',
      icon: 'cloud_done',
      message: `Booking ${newReservation.$id ? 'updated' : 'created'}: ${
        boatStore.getBoatById(r.resource)?.name
      } at ${formatDate(r.start)}`,
      spinner: false,
    });
  } catch (e) {
    status({
      color: 'negative',
      icon: 'error',
      spinner: false,
      message: 'Failed to book!' + e,
    });
  }
  $router.go(-1);
};
</script>
