<template lang="pug">
  .schedule.mx-2.pb-22px(
    ref="schedule",
    :style="scheduleWidth"
  )
    calendar-header(
      :current-date="currentDate",
      :is-current-date="isCurrentDate",
      @previous-date="previousDate",
      @next-date="nextDate",
      @selected-layout="selectedLayout"
    )
    .schedule-body(
      @scroll="changeScrollingState",
      ref="scheduleBody"
    )
      .hiding-container.fixed(v-if="isScrolling")
      .column-wrapper.flex.ml-20(:style="columnWrapperWidth")
        calendar-column(
          v-for="(owner, index) in filteredOwners",
          :key="owner.id",
          :owner-data="owner",
          :url="url",
          :day-events="filterEventsByOwner(owner)",
          :day-start-time="validateStartTime",
          :day-end-time="validateEndTime",
          :style="columnSize",
          :event-statuses="eventStatuses",
          @selected-event="transmitEventData",
          @delete-event="transmitDeleteEvent",
          :schedule-body-ref="$refs.scheduleBody",
          :open-form-create-event="openFormCreateEvent",
          :current-date="currentDate"
        )
      .flex.w-full.relative
        .time-coil-wrapper.left-0.-mt-12.pt-9
          calendar-clock-column(
            :timeCoil="timeCoil",
            :current-time="currentTime",
            :is-current-date="isCurrentDate",
            :day-end-time="validateEndTime"
          )
          .time-circle-indicator.left-74px(
            v-if="isShownIndicator",
            :style="circleIndicatorLocation"
          )  
        span.time-line-indicator.block.left-20(
          v-if="isShownIndicator",
          :style="lineIndicatorLocation"
        )
        .flex(:class="calendarBackgroundWidth")
          calendar-background(
            :time-coil="timeCoil",
            :owners-count="ownersCount"
          )
</template>

<script>
import * as moment from "moment/moment";
import CalendarHeader from "./CalendarHeader.vue";
import CalendarBackground from "./CalendarBackground.vue";
import CalendarClockColumn from "./CalendarClockColumn.vue";
import CalendarColumn from "./CalendarColumn.vue";
export default {
  name: "CalendarSchedule",
  components: {
    CalendarHeader,
    CalendarBackground,
    CalendarClockColumn,
    CalendarColumn,
  },
  props: {
    openFormCreateEvent: Function,
    url: String,
    //changeFormWasClosed: Boolean,
    currentDate: {
      type: Object,
      default() {
        return {};
      },
    },
    timeInformation: {
      type: Object,
      default() {
        return {};
      },
    },
    eventsData: {
      type: Array,
      default() {
        return [];
      },
    },
    sidebarWidth: String,
    schedulesData: {
      type: Array,
      default() {
        return [];
      },
    },
    eventStatuses: {
      type: Array,
      default() {
        return [];
      },
    },
  },
  data() {
    return {
      currentTime: "",
      timeCoil: [],
      timer: null,
      isCurrentDate: true,
      isShownIndicator: true,
      pixelsPerHour: 62,
      columnHeaderHeight: 48,
      defaultColumnWidth: 470,
      isScrolling: false,
    };
  },
  computed: {
    hours() {
      return this.convertTime(this.currentTime, 0, -6);
    },
    minutes() {
      return this.convertTime(this.currentTime, 3, -3);
    },
    hoursMinutes() {
      return this.currentTime.slice(0, -3);
    },
    validateStartTime() {
      return this.verifyTime(this.timeInformation.dayStartTime);
    },
    validateEndTime() {
      return this.verifyTime(this.timeInformation.dayEndTime);
    },
    lineIndicatorLocation() {
      if (this.ownersCount > 3) {
        return {
          width: `${this.defaultColumnWidth * this.ownersCount}px`,
          top: `${this.calculateIndicatorLocation()}px`,
        };
      }
      return {
        width: "calc(100% - 80px)",
        top: `${this.calculateIndicatorLocation()}px`,
      };
    },
    circleIndicatorLocation() {
      return {
        top: `${this.calculateIndicatorLocation() + 42}px`,
      };
    },
    pixelsPerMinute() {
      return this.pixelsPerHour / 60;
    },
    scheduleHeight() {
      return (
        (this.validateEndTime - this.validateStartTime) * this.pixelsPerHour
      );
    },
    scheduleWidth() {
      return {
        "--sidebar-width": this.sidebarWidth,
      };
    },
    filteredOwners() {
      let filteredArray = [];
      this.schedulesData.forEach((elem) => {
        filteredArray.push({
          id: elem.employee?.id,
          last_name: elem.employee?.last_name,
          first_name: elem.employee?.first_name,
          patronymic: elem.employee?.patronymic,
          color: elem.employee?.color,
          photo: elem.employee?.photo,
          end_time: elem.end_time?.slice(0, elem.end_time.length - 3),
          start_time: elem.start_time?.slice(0, elem.start_time.length - 3),
        });
      });
      return filteredArray;
    },
    ownersCount() {
      return this.filteredOwners.length;
    },
    columnHeight() {
      return (
        (this.timeCoil.length - 1) * this.pixelsPerHour +
        this.columnHeaderHeight
      );
    },
    columnSize() {
      if (this.ownersCount > 3) {
        return {
          height: `${this.columnHeight}px`,
          width: `${this.defaultColumnWidth}px`,
        };
      }
      return {
        height: `${this.columnHeight}px`,
        width: `calc(100% / ${this.ownersCount})`,
      };
    },
    columnWrapperWidth() {
      if (this.ownersCount > 3) {
        return {
          width: `${this.defaultColumnWidth * this.ownersCount}px`,
        };
      }
      return {
        width: "calc(100% - 80px)",
      };
    },
    calendarBackgroundWidth() {
      return {
        "w-full": this.ownersCount <= 3,
      };
    },
  },
  methods: {
    previousDate() {
      this.$emit("previous-date");
    },
    nextDate() {
      this.$emit("next-date");
    },
    selectedLayout(option) {
      this.$emit("selected-layout", option);
    },
    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;
    },
    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.isCurrentDate
        ) {
          this.timeCoil.push(this.hoursMinutes);
        } else this.timeCoil.push(`${i}:00`);
      }
    },
    changeTimeCoil() {
      this.timeCoil = this.timeCoil.map((elem) => {
        if (this.convertTime(elem, 0, -3) === this.hours) {
          return this.hoursMinutes;
        }
        return elem.slice(0, -3) + ":00";
      });
    },
    verifyTime(dayTime) {
      let timeArray = dayTime.split(":").map((elem) => parseInt(elem, 10));
      let newTime = timeArray[1] > 30 ? timeArray[0] + 1 : timeArray[0];
      return newTime;
    },
    convertTime(str, startIndex, endIndex) {
      return parseInt(str.slice(startIndex, endIndex), 10);
    },
    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.scheduleHeight || result < 0) {
        this.isShownIndicator = false;
        return 0;
      }
      return result;
    },
    findObjectInArray(array, object) {
      return array.find(
        (item) => JSON.stringify(item) === JSON.stringify(object)
      );
    },
    filterEventsByOwner(owner) {
      let filteredArray = [];
      this.eventsData.forEach((item) => {
        let foundEvent = item.employees.find(
          (elem) => elem.employee.id === owner.id && elem.role === "owner"
        );
        if (foundEvent) filteredArray.push(item);
      });
      return filteredArray;
    },
    changeScrollingState(e) {
      this.isScrolling = e.target.scrollTop !== 0;
    },
    showCuttentTime() {
      this.$nextTick(() =>
        this.$refs["scheduleBody"].scrollTo({
          top: `${this.lineIndicatorLocation.top.slice(0, -2) - 240}`,
          behavior: "smooth",
        })
      );
    },
    /*transmitResetChangeForm() {
      this.$emit("reset-change-form");
    },*/
    transmitEventData(eventData) {
      this.$emit("selected-event", eventData);
    },
    transmitDeleteEvent(eventData) {
      this.$emit("delete-event", eventData);
    },
    bodyScroll() {
      this.$nextTick(() => {
        let presenceScroll =
          this.$refs["scheduleBody"].scrollHeight !==
          this.$refs["scheduleBody"].clientHeight;
        if (presenceScroll) {
          this.$refs["scheduleBody"].classList.add("pr-10px");
          this.$refs["schedule"].classList.add("pr-10px");
        }
      });
    },
  },
  watch: {
    currentTime() {
      if (
        this.hours === this.validateEndTime &&
        this.minutes > 0 &&
        this.timer
      ) {
        this.stopTimer();
        this.timeCoilInitialization();
      }
    },
    currentDate: function () {
      this.isCurrentDate =
        this.currentDate.format("DD.MM.YYYY") === moment().format("DD.MM.YYYY");
      this.isShownIndicator = this.isCurrentDate;
      if (this.timer) {
        this.stopTimer();
        this.timeCoilInitialization();
      }
      if (this.isCurrentDate) {
        this.changeCurrentTime();
        this.timeCoilInitialization();
        this.startTimer();
        this.showCuttentTime();
      }
    },
  },
  mounted() {
    this.changeCurrentTime();
    this.timeCoilInitialization();
    this.startTimer();
    this.showCuttentTime();
    this.bodyScroll();
  },
  beforeUnmount() {
    this.stopTimer();
  },
};
</script>

<style lang="sass" scoped>
.schedule
  border-top-left-radius: 4px
  border-top-right-radius: 4px
  position: relative
  background-color: var(--default-white)
  width: calc(100% - (var(--sidebar-width) + 16px))
  height: calc(100vh - 56px - 8px)

.time-line-indicator
  border-top: 1px solid var(--bg-event-red-color)
  position: absolute
  z-index: 4

.time-circle-indicator
  width: 12px
  height: 12px
  background-color: var(--bg-event-red-color)
  border-radius: 50%
  position: absolute
  z-index: 5

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

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

.schedule-body
  width: 100%
  height: calc(100vh - 56px * 2 - 8px - 22px)
  overflow-y: auto
  overflow-x: auto
  &::-webkit-scrollbar-track:horizontal
    margin: 0 24px 0 104px
  &::-webkit-scrollbar-track:vertical
    margin: 48px 0 24px 0

.hiding-container
  width: 80px
  height: 48px
  top: calc(56px * 2 + 8px)
  background-color: var(--default-white)
  z-index: 6
</style>
