<template>
  <!-- This example requires Tailwind CSS v2.0+ -->
  <div>
    <div class="grid grid-cols-1 md:grid-cols-2 md:gap-8">
      <div :class="`sticky top-0 md:block ${calendarClasses}`">
        <div
          class="relative z-20 flex items-center justify-between border-b border-gray-200 py-4 px-4 sm:px-0"
        >
          <h2 class="flex-auto font-semibold text-gray-900">
            {{ currentMonthAndYear }}
          </h2>
          <div class="flex items-center">
            <div class="flex items-center rounded-md shadow-sm">
              <button
                @click="handlePreviousMonthClick"
                type="button"
                class="flex items-center justify-center rounded-l-md border border-r-0 border-gray-300 bg-white py-2 pl-3 pr-4 text-gray-400 hover:text-gray-500 focus:relative"
                :id="id + '_button_previous_month'"
              >
                <span class="sr-only">Previous month</span>
                <!-- Heroicon name: solid/chevron-left -->
                <svg
                  class="h-5 w-5"
                  xmlns="http://www.w3.org/2000/svg"
                  viewBox="0 0 20 20"
                  fill="currentColor"
                  aria-hidden="true"
                >
                  <path
                    fill-rule="evenodd"
                    d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
                    clip-rule="evenodd"
                  />
                </svg>
              </button>
              <span class="relative -mx-px h-5 w-px bg-gray-300"></span>
              <button
                @click="handleNextMonthClick"
                type="button"
                class="flex items-center justify-center rounded-r-md border border-l-0 border-gray-300 bg-white py-2 pl-4 pr-3 text-gray-400 hover:text-gray-500 focus:relative"
                :id="id + '_button_next_month'"
              >
                <span class="sr-only">Next month</span>
                <!-- Heroicon name: solid/chevron-right -->
                <svg
                  class="h-5 w-5"
                  xmlns="http://www.w3.org/2000/svg"
                  viewBox="0 0 20 20"
                  fill="currentColor"
                  aria-hidden="true"
                >
                  <path
                    fill-rule="evenodd"
                    d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
                    clip-rule="evenodd"
                  />
                </svg>
              </button>
            </div>
          </div>
        </div>

        <div
          class="col-span-1 overflow-hidden rounded shadow ring-1 ring-gray-200"
        >
          <div
            class="grid grid-cols-7 gap-px border-b border-gray-300 bg-gray-200 text-center text-xs font-semibold leading-6 text-gray-700"
          >
            <div class="bg-white py-2">Mo<span class="sr-only">on</span></div>
            <div class="bg-white py-2">Tu<span class="sr-only">ue</span></div>
            <div class="bg-white py-2">We<span class="sr-only">ed</span></div>
            <div class="bg-white py-2">Th<span class="sr-only">hu</span></div>
            <div class="bg-white py-2">Fr<span class="sr-only">ri</span></div>
            <div class="bg-white py-2">Sa<span class="sr-only">at</span></div>
            <div class="bg-white py-2">Su<span class="sr-only">un</span></div>
          </div>
          <div class="flex bg-gray-200 text-xs leading-6 text-gray-700">
            <div class="isolate grid w-full grid-cols-7 grid-rows-6 gap-px">
              <button
                v-for="date in daysArray"
                :key="getDateKey(date)"
                type="button"
                :class="{
                  'flex h-14 flex-col py-2 px-3 hover:bg-gray-100 focus:z-10': true,
                  'bg-white': isCurrentMonth(date),
                  'bg-gray-50': !isCurrentMonth(date),
                  'font-semibold': isSelected(date) || isToday(date),
                  'text-white': isSelected(date),
                  'text-indigo-600': !isSelected(date) && isToday(date),
                  'text-gray-900':
                    !isSelected(date) && isCurrentMonth(date) && !isToday(date),
                  'text-gray-500':
                    !isSelected(date) &&
                    !isCurrentMonth(date) &&
                    !isToday(date),
                }"
                @click="handleDateClick(date)"
              >
                <time
                  :datetime="formatForDateTime(date)"
                  :class="{
                    'ml-auto': true,
                    'flex h-6 w-6 items-center justify-center rounded-full':
                      isSelected(date),
                    'bg-indigo-600': isSelected(date) && isToday(date),
                    'bg-gray-900': isSelected(date) && !isToday(date),
                  }"
                  >{{ getDayFromDate(date) }}</time
                >
                <span v-if="eventsCount" class="sr-only"
                  >{{ getEventsCountForDate(date) }} events</span
                >
                <span
                  v-if="eventsCount && getEventsCountForDate(date) > 0"
                  class="-mx-0.5 mt-auto flex flex-wrap-reverse"
                >
                  <span
                    class="mx-0.5 mb-1 h-1.5 w-1.5 rounded-full bg-gray-400"
                  ></span>
                </span>
              </button>
            </div>
          </div>
        </div>
      </div>
      <slot name="customCardsRender"></slot>
      <section
        v-if="eventsData && validSelectedDate && showDefaultCardUi"
        class="col-span-1 my-10 mx-4 md:mx-0 md:my-0"
      >
        <h2
          v-if="showSelectedDate"
          class="hidden py-4 font-semibold text-gray-900 md:block"
        >
          Schedule for
          <time :datetime="selectedDateForDateTime">{{
            formattedSelectedDate
          }}</time>
        </h2>
        <p
          v-if="getEventsForDate(value).length === 0"
          class="mt-3 text-center text-sm text-gray-400"
        >
          Sorry, no events found for this date.
        </p>
        <ol
          v-if="getEventsForDate(value).length !== 0"
          class="mt-3 divide-y divide-gray-100 overflow-hidden rounded-lg bg-white text-sm shadow ring-1 ring-indigo-700 ring-opacity-5"
        >
          <li
            class="cursor-pointer p-4 focus-within:bg-gray-50 hover:bg-gray-50"
            v-for="event in getEventsForDate(value)"
            :key="event.id"
            @click="handleEventClick(event)"
          >
            <div class="text-sm text-gray-900">
              {{ formatTimeFromDate(event.start) }} -
              {{ formatTimeFromDate(event.end) }}
            </div>
            <div
              class="mt-1 flex text-sm font-semibold"
              :style="{ color: event.color }"
              :class="event.status === 7 ? 'line-through' : ''"
            >
              <c-icon
                v-if="event.attendance"
                name="check"
                type="solid"
                class="mt-0.5 h-4 w-4 shrink-0"
                :style="`color:${event.color}`"
              ></c-icon>
              {{ event.title }}
            </div>
            <div class="-mx-1 -my-0.5 flex flex-wrap items-center">
              <div class="mx-1 my-0.5 flex items-center space-x-0.5">
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  class="h-4 w-4 flex-none text-gray-400"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  stroke-width="2"
                >
                  <path
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
                  />
                </svg>
                <span class="min-w-0 flex-1 text-sm text-gray-500"
                  >{{ event.duration }} mins</span
                >
              </div>
              <div
                v-if="event.subject && event.subject.length"
                class="mx-1 my-0.5 flex items-center space-x-0.5"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  class="h-4 w-4 flex-none text-gray-400"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  stroke-width="2"
                >
                  <path
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"
                  />
                </svg>
                <span class="min-w-0 flex-1 text-sm text-gray-500">{{
                  event.subject
                }}</span>
              </div>
              <div
                v-if="event.location && event.location.length"
                class="mx-1 my-0.5 flex items-center space-x-0.5"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  class="h-4 w-4 flex-none text-gray-400"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  stroke-width="2"
                >
                  <path
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7"
                  />
                </svg>
                <span class="min-w-0 flex-1 text-sm text-gray-500">{{
                  event.location
                }}</span>
              </div>
              <div
                v-if="
                  event.video_call_type == 1 ||
                  event.video_call_type == 2 ||
                  event.video_call_type == 3
                "
                class="mx-1 my-0.5 flex items-center space-x-0.5"
              >
                <c-icon
                  name="video-camera-outline"
                  type="outline"
                  class="h-4 w-4 flex-shrink-0 text-gray-400"
                ></c-icon>
                <p class="min-w-0 flex-1 text-sm text-gray-500">
                  {{
                    event.video_call_type == 1
                      ? "Lessonspace link"
                      : event.video_call_type == 2
                      ? "Meeting link"
                      : "Zoom link"
                  }}
                </p>
              </div>
              <div
                v-if="event.staff && event.staff.length"
                class="mx-1 my-0.5 flex items-center space-x-0.5"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  class="h-4 w-4 flex-none text-gray-400"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  stroke-width="2"
                >
                  <path
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
                  />
                </svg>
                <span class="min-w-0 flex-1 text-sm text-gray-500">{{
                  event.staff
                }}</span>
              </div>
            </div>
          </li>
        </ol>
      </section>
    </div>
  </div>
</template>

<script>
import * as dayjs from "dayjs";
import CIcon from "../CIcon/CIcon.vue";

export default {
  name: "CCalendar",
  components: { CIcon },
  props: {
    value: {
      type: [String, Date, Object],
      default: () => dayjs(),
    },
    id: {
      type: String,
    },
    eventsCount: {
      type: Array,
      default: () => null,
    },
    eventsData: {
      type: Array,
      default: () => null,
    },
    calendarClasses: {
      type: String,
      default: "",
    },
    showSelectedDate: {
      type: Boolean,
      default: true,
    },
    showDefaultCardUi: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      activeDate: dayjs(),
    };
  },
  methods: {
    handlePreviousMonthClick() {
      this.activeDate = this.activeDate.subtract(1, "month");
      this.$emit("prev-month", this.getActiveStartAndEndDates());
    },
    handleNextMonthClick() {
      this.activeDate = this.activeDate.add(1, "month");
      this.$emit("next-month", this.getActiveStartAndEndDates());
    },
    handleDateClick(date) {
      this.$emit("input", date);
    },
    getDayFromDate(date) {
      return dayjs(date).format("D");
    },
    isSelected(date) {
      return dayjs(date).isSame(this.value, "day");
    },
    isToday(date) {
      return dayjs(date).isSame(dayjs(), "day");
    },
    isCurrentMonth(date) {
      return dayjs(date).isSame(this.activeDate, "month");
    },
    getDateKey(date) {
      return dayjs(date).format();
    },
    formatForDateTime(date) {
      return dayjs(date).format("YYYY-MM-DD");
    },
    formatTimeFromDate(date) {
      return dayjs(date).format("hh:mma");
    },
    getEventsCountForDate(date) {
      let eventsCountObj = this.eventsCount.find((event) =>
        dayjs(date).isSame(dayjs(event.date), "day")
      );
      if (eventsCountObj) {
        return eventsCountObj.eventsCount;
      } else {
        return 0;
      }
    },
    getActiveStartAndEndDates() {
      return {
        startDate: this.daysArray[0],
        endDate: this.daysArray[this.daysArray.length - 1],
      };
    },
    getEventsForDate(date) {
      return this.eventsData.filter((event) =>
        dayjs(date).isSame(dayjs(event.start), "day")
      );
    },
    handleEventClick(event) {
      this.$emit("event-click", event);
    },
  },
  computed: {
    currentMonthAndYear() {
      return dayjs(this.activeDate).format("MMMM YYYY");
    },
    daysArray() {
      let dates = [];
      let firstDayOfmonth = dayjs(this.activeDate).startOf("month");
      let lastDayOfmonth = dayjs(this.activeDate).endOf("month");
      let firstDayOfMonthInWeek = firstDayOfmonth.day();
      let lastDayOfMonthInWeek = lastDayOfmonth.day();
      if (firstDayOfMonthInWeek === 0) {
        firstDayOfMonthInWeek = 7;
      }
      if (lastDayOfMonthInWeek === 0) {
        lastDayOfMonthInWeek = 7;
      }
      for (let i = 0; i < firstDayOfMonthInWeek - 1; i++) {
        dates.unshift(firstDayOfmonth.subtract(i + 1, "day"));
      }
      for (let i = 0; i < dayjs(this.activeDate).daysInMonth(); i++) {
        dates.push(firstDayOfmonth.add(i, "day"));
      }
      let cursor = 1;
      for (let i = lastDayOfMonthInWeek; i < 7; i++) {
        dates.push(lastDayOfmonth.add(cursor, "day"));
        cursor++;
      }
      if (dates.length !== 42) {
        let lastDayOfDates = dates[dates.length - 1];
        for (let i = 1; i <= 7; i++) {
          dates.push(lastDayOfDates.add(i, "day"));
        }
      }
      return dates;
    },
    formattedSelectedDate() {
      return dayjs(this.value ? this.value : dayjs()).format("MMMM D, YYYY");
    },
    selectedDateForDateTime() {
      return dayjs(this.value ? this.value : dayjs()).format("YYYY-MM-DD");
    },
    validSelectedDate() {
      return this.value && dayjs(this.value).isValid();
    },
  },
  mounted() {
    if (this.value) {
      this.activeDate = dayjs(this.value);
    }
  },
};
</script>

<style></style>
