<template lang="pug">
  .schedule.flex-1.flex.flex-col.relative(
    :style="{width: openSidebar ? 'calc(100vw - 320px)' : 'calc(100vw - 160px)'}"
  )
    calendar-header.w-full.mb-1(v-model="displayType")
    .schedule-body.h-full.bg-white.w-full(:class="{rounded: !expandedDisplayType}")
      .column-wrapper.flex.ml-20(:style="columnWrapperWidth")
        calendar-column(
          v-for="date in dateRange",
          :key="date",
          :date="date",
          :style="columnHeight",
          :expanded-display-type="expandedDisplayType",
          :day-start-time="validateStartTime"
          :day-end-time="validateEndTime"
        )
      .flex.relative(
        :style="expandedDisplayType ? backgroundWrapperWidth : {}",
        :class="{'border-bottom': expandedDisplayType}"
      )
        .time-coil-wrapper.left-0.-mt-12
          calendar-clock-column(
            :time-coil="timeCoil",
            :current-time="currentTime",
            :is-current-week="isCurrentWeek",
            :day-end-time="validateEndTime"
          )
          .time-circle-indicator.left-74px.h-3.w-3.rounded-full.absolute(
            v-if="isShownIndicator",
            :style="circleIndicatorLocation"
          )
        span.time-line-indicator.block.left-20.absolute(
          v-if="isShownIndicator",
          :style="lineIndicatorLocation"
        )
        calendar-background.flex-1
    .w-full.h-3.bg-white.footer(v-if="expandedDisplayType")
</template>

<script>
import CalendarHeader from "@/pages/newCalendar/components/CalendarHeader";
import CalendarBackground from "@/pages/newCalendar/components/CalendarBackground.vue";
import CalendarClockColumn from "@/pages/newCalendar/components/CalendarClockColumn.vue";
import CalendarColumn from "@/pages/newCalendar/components/CalendarColumn.vue";
import {
  convertTime,
  verifyTime,
} from "@/pages/newCalendar/utils/calendarFunctions.js";
import { mapState } from "vuex";
import * as moment from "moment/moment";
export default {
  name: "CalendarWrapper",
  components: {
    CalendarHeader,
    CalendarBackground,
    CalendarClockColumn,
    CalendarColumn,
  },
  props: {
    openSidebar: Boolean,
  },
  data() {
    return {
      displayType: "expanded",
      currentTime: "",
      isCurrentWeek: true,
      isShownIndicator: true,
      timeCoil: [],
      timer: null,
      pixelsPerHour: 76,
    };
  },
  computed: {
    ...mapState({
      workingHours: (state) => state.calendar.workingHours,
      selectedDates: (state) => state.calendar.selectedDates,
    }),
    hours() {
      return convertTime(this.currentTime, 0, -6);
    },
    minutes() {
      return convertTime(this.currentTime, 3, -3);
    },
    hoursMinutes() {
      return this.currentTime.slice(0, -3);
    },
    pixelsPerMinute() {
      return this.pixelsPerHour / 60;
    },
    backgroundHeight() {
      return (
        (this.validateEndTime - this.validateStartTime) * this.pixelsPerHour
      );
    },
    expandedDisplayType() {
      return this.displayType === "expanded";
    },
    dateRange() {
      let diff = this.selectedDates?.to.diff(this.selectedDates?.from, "days");
      let range = [];
      for (let i = 0; i <= diff; i++) {
        range.push(this.selectedDates?.from.clone().add(i, "day"));
      }
      return range;
    },
    validateStartTime() {
      return verifyTime(this.workingHours.start);
    },
    validateEndTime() {
      return verifyTime(this.workingHours.end);
    },
    columnHeight() {
      return this.expandedDisplayType
        ? {
            height: `${this.timeCoil.length * this.pixelsPerHour + 60}px`,
            width: "380px",
          }
        : {
            height: `${this.timeCoil.length * this.pixelsPerHour + 96}px`,
            width: this.openSidebar
              ? `calc((100vw - 320px - 80px) / ${this.dateRange.length})`
              : `calc((100vw - 160px - 80px) / ${this.dateRange.length})`,
          };
    },
    columnWrapperWidth() {
      return this.expandedDisplayType
        ? {
            width: `${380 * this.dateRange.length}px`,
          }
        : {
            width: this.openSidebar
              ? "calc(100vw - 320px - 80px)"
              : "calc(100vw - 160px - 80px)",
          };
    },
    backgroundWrapperWidth() {
      return {
        width: `${380 * this.dateRange.length + 80}px`,
      };
    },
    lineIndicatorLocation() {
      return {
        top: `${this.calculateIndicatorLocation()}px`,
      };
    },
    circleIndicatorLocation() {
      return {
        top: `${this.calculateIndicatorLocation() + 42}px`,
      };
    },
  },
  methods: {
    changeCurrentTime() {
      this.currentTime = moment().format("HH:mm:ss");
    },
    timeCoilInitialization() {
      this.timeCoil = [];
      for (let i = this.validateStartTime; i < this.validateEndTime; i++) {
        if (
          i === this.hours &&
          this.hours !== this.validateEndTime &&
          this.isCurrentWeek
        ) {
          this.timeCoil.push(this.hoursMinutes);
        } else this.timeCoil.push(`${i}:00`);
      }
    },
    changeTimeCoil() {
      this.timeCoil = this.timeCoil.map((elem) => {
        if (convertTime(elem, 0, -3) === this.hours) {
          return this.hoursMinutes;
        }
        return elem.slice(0, -3) + ":00";
      });
    },
    startTimer() {
      if (
        this.hours >= this.validateStartTime &&
        this.hours < this.validateEndTime
      ) {
        this.timer = setInterval(() => {
          this.changeCurrentTime();
          this.changeTimeCoil();
        }, 5000);
      }
    },
    stopTimer() {
      clearInterval(this.timer);
      this.timer = null;
    },
    calculateIndicatorLocation() {
      let newTime = this.currentTime
        .split(":")
        .map((elem) => parseInt(elem, 10));
      let result =
        (newTime[0] - this.validateStartTime) * this.pixelsPerHour +
        newTime[1] * this.pixelsPerMinute;
      if (result > this.backgroundHeight || result < 0) {
        this.isShownIndicator = false;
        return 0;
      }
      return result;
    },
  },
  watch: {
    currentTime() {
      if (
        this.hours === this.validateEndTime &&
        this.minutes > 0 &&
        this.timer
      ) {
        this.stopTimer();
        this.timeCoilInitialization();
      }
    },
    selectedDates: {
      deep: true,
      handler(newValue) {
        this.isCurrentWeek =
          newValue?.from.isSame(moment().clone().startOf("week")) &&
          newValue?.to.isSame(moment().clone().endOf("week"));
        this.isShownIndicator = this.isCurrentWeek;
        if (this.timer) {
          this.stopTimer();
          this.timeCoilInitialization();
        }
        if (this.isCurrentWeek) {
          this.changeCurrentTime();
          this.timeCoilInitialization();
          this.startTimer();
        }
      },
    },
  },
  mounted() {
    this.changeCurrentTime();
    this.timeCoilInitialization();
    this.startTimer();
  },
  beforeUnmount() {
    this.stopTimer();
  },
};
</script>

<style lang="sass" scoped>
.schedule-body
  overflow-x: auto
  border-top-left-radius: 4px
  border-top-right-radius: 4px
  &::-webkit-scrollbar-track:horizontal
    margin: 0 24px 0 24px

.background
  background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%)

.time-coil-wrapper
  position: sticky
  z-index: 5
  background-color: var(--default-white)
  padding-top: 38px

.column-wrapper
  height: 60px
  position: relative
  background-color: var(--default-white)

.footer
  border-bottom-left-radius: 4px
  border-bottom-right-radius: 4px

.border-bottom
  border-bottom: 4px solid var(--bg-ligth-blue-color)

.records-count
  border-right: 1px solid var(--border-light-grey-color)
  &:last-child
    border-right: none

.border-top
  border-top: 1px solid var(--border-light-grey-color)

.time-circle-indicator
  background-color: var(--bg-event-red-color)
  z-index: 5

.time-line-indicator
  border-top: 1px solid var(--bg-event-red-color)
  z-index: 4
  width: calc(100% - 80px)
</style>
