<template lang="pug">
  .wrapper.flex.w-full.relative.mx-2
    transition(name="schedule", mode="out-in")
      .flex.justify-center.items-center.w-full(v-if="schedulesDataPresence")
          base-loader(
            :width="60",
            :height="60"
          )
      .relative.flex.flex-col.px-6.py-6.h-full.w-full.gap-y-5(v-else)
        schedule-header(
          :start-month="startMonth",
          :change-show-time="changeShowTime",
          :show-time="showTime",
          @switch-previous-month="switchPreviousMonth",
          @switch-next-month="switchNextMonth"
        )
        schedule-table(
          :schedules-employee="fetchSchedulesEmployee",
          :schedule-list="scheduleList",
          :serialized="serialized",
          :buttons="buttons",
          :start-month="startMonth",
          :employees="employees",
          :show-time="showTime",
          :clear-select="clearSelect",
          :select-employee="selectEmployee",
          :replacement-sheet="replacementSheet",
          :template="template",
          :trim-owner-name="trimOwnerName",
          :open-form="openForm",
          :active-cell="activeCell",
          :set-active-cell="setActiveCell",
          :change-shift="postUpdateSchedule",
          @schedule-employee="createScheduleEmployee",
          @schedules="distributeRequest"
        )
        schedule-bar(
          :buttons="buttons",
          :times="times",
          :create-schedules="postCreateSchedules",
          :delete-schedule="deleteSchedule",
          :template="template"
        )
</template>

<script>
import * as moment from "moment";
import BaseLoader from "@/components/Loader/BaseLoader.vue";
import { fetchWrapper } from "@/shared/fetchWrapper.js";
import ScheduleHeader from "@/pages/schedule/components/ScheduleHeader.vue";
import ScheduleBar from "@/pages/schedule/components/ScheduleBar.vue";
import ScheduleTable from "@/pages/schedule/components/ScheduleTable.vue";

export default {
  name: "TheSchedule",
  components: {
    ScheduleHeader,
    ScheduleBar,
    ScheduleTable,
    BaseLoader,
  },
  data() {
    return {
      employeeList: [
        {
          initialization: true,
        },
      ],
      scheduleList: [],
      employees: [],
      serialized: [],
      selectEmployee: {
        label: "",
        id: null,
      },
      times: { start_time: "", end_time: "" },
      replacementSheet: {
        currentEmployee: "",
        replacementEmployee: "",
        date: null,
        start_time: "",
        end_time: "",
        schedules: [],
      },
      buttons: [
        {
          class: "button-work",
          name: "Работает",
          work: "WORKS",
          active: false,
          color: "#55CD76",
          text: "'Р'",
        },
        {
          class: "button-vacation",
          name: "Отпуск/больничный",
          work: "VACATION",
          active: false,
          color: "var(--btn-blue-color-2)",
          text: "'О'",
        },
        {
          class: "button-free",
          name: "Выходной",
          work: "DAY_OFF",
          active: false,
          color: "#9294A7",
          text: "'В'",
        },
      ],
      template: { item: {} },
      startMonth: moment().startOf("month"),
      showTime: false,
      schedulesDate: {},
      currenSchedule: null,
      activeCell: true,
    };
  },
  computed: {
    endMonth() {
      return this.startMonth.clone().endOf("month");
    },
    schedulesDataPresence() {
      return this.employeeList[0]?.initialization;
    },
  },
  methods: {
    openForm(e) {
      this.currenSchedule = e;
      this.replacementSheet.currentEmployee = this.trimOwnerName(
        e.last_name,
        e.first_name,
        e.patronymic
      );
      this.replacementSheet.schedules = e.schedules;
    },
    changeShowTime() {
      this.showTime = !this.showTime;
    },
    trimOwnerName(lastName, firstName, patronymic) {
      let checkedFirstName = firstName !== null ? firstName[0] + "." : "";
      let checkedPatronymic = patronymic !== null ? patronymic[0] + "." : "";
      return `${lastName} ${checkedFirstName}${checkedPatronymic}`;
    },
    setActiveCell() {
      this.activeCell = true;
    },
    clearSelect(employee) {
      if (employee) {
        employee.label = "";
        employee.id = null;
      } else {
        this.selectEmployee.label = "";
        this.selectEmployeeid = null;
      }
      if (this.buttons.find((e) => e.active))
        this.buttons.find((e) => e.active).active = false;
    },
    fetchSchedules() {
      fetchWrapper
        .get("general/employee/")
        .then((res) => {
          this.employeeList = res.results;
        })
        .then(() => this.fetchSchedulesEmployee());
    },
    fetchSchedulesEmployee() {
      this.scheduleList = [];
      this.clearSelect();
      fetchWrapper
        .get(
          `accounts/schedules/?date_after=${this.startMonth.format(
            "YYYY-MM-DD"
          )}&date_before=${this.endMonth.format("YYYY-MM-DD")}`
        )
        .then((data) => {
          this.scheduleList.push(...data.results);
        })
        .then(() => this.filterScheduleEmployee());
    },
    filterScheduleEmployee() {
      let serialized = [];
      this.template.item = {};
      this.scheduleList.forEach((e) => {
        let foundedElem = serialized.find((elem) => elem.id === e.employee.id);
        if (!foundedElem) {
          serialized.push({
            first_name: e.employee.first_name,
            id: e.employee.id,
            last_name: e.employee.last_name,
            patronymic: e.employee.patronymic,
            schedules: [
              {
                date: e.date,
                end_time: e.end_time ? e.end_time.slice(0, -3) : "",
                start_time: e.start_time ? e.start_time.slice(0, -3) : "",
                status: e.status,
                id: e.id,
                title: e.title,
                name: e.name,
              },
            ],
          });
        } else {
          foundedElem.schedules.push({
            date: e.date,
            end_time: e.end_time ? e.end_time.slice(0, -3) : "",
            start_time: e.start_time ? e.start_time.slice(0, -3) : "",
            status: e.status,
            id: e.id,
            title: e.title,
            name: e.name,
          });
        }
      });
      this.serialized = serialized;
      this.filterEmployee();
    },
    filterEmployee() {
      this.employees = [];
      this.employees = this.employeeList.filter((item) =>
        this.serialized.every((el) => el.id !== item.id)
      );
    },
    distributeRequest(inside, outside) {
      this.insideSchedules = inside;
      this.outsideSchedules = outside;
    },
    postCreateSchedules() {
      this.activeCell = false;
      let data = {
        employee: this.schedulesDate.id,
        active_flg: true,
        start_time: this.times.start_time,
        end_time: this.times.end_time,
        status: this.buttons.find((e) => e.active)?.work,
      };
      if (this.template.item.label)
        data.kind_template = this.template.item.name;
      if (this.insideSchedules?.length > 0) {
        this.postUpdateSchedule();
        if (this.outsideSchedules) {
          this.outsideSchedules.forEach((el) => {
            fetchWrapper.post("accounts/schedules/create/", {
              ...data,
              start_date: el.start_date,
              end_date: el.end_date,
            });
          });
        }
      } else {
        fetchWrapper
          .post("accounts/schedules/create/", {
            ...data,
            start_date: this.schedulesDate.start_date,
            end_date: this.schedulesDate.end_date,
          })
          .then(() => this.fetchSchedules());
      }
    },
    postUpdateSchedule() {
      if (this.replacementSheet.date) {
        let scheduleList = this.currenSchedule.schedules.find(
          (el) =>
            el.date === moment(this.replacementSheet.date).format("YYYY-MM-DD")
        );
        fetchWrapper
          .post(`accounts/schedules/${scheduleList.id}/update/`, {
            employee: this.replacementSheet.replacementEmployee.id,
            active_flg: true,
            start_time: this.replacementSheet.start_time,
            end_time: this.replacementSheet.end_time,
            status: scheduleList.status,
          })
          .then(() => this.fetchSchedules());
      } else {
        let ids = "";
        this.insideSchedules.forEach((e) => (ids += e.id + ","));
        ids = ids.slice(0, -1);
        fetchWrapper
          .post(`accounts/schedules/${ids}/update/`, {
            employee: this.insideSchedules[0].employeeId,
            active_flg: true,
            start_time: this.times.start_time,
            end_time: this.times.end_time,
            status: this.buttons.find((e) => e.active).work,
          })
          .then(() => this.fetchSchedules());
      }
    },
    createScheduleEmployee(e, id) {
      this.schedulesDate = {
        start_date: e.start,
        end_date: e.end ? e.end : e.start,
        id: id,
      };
    },
    deleteSchedule() {
      this.activeCell = false;
      let ids = "";
      if (this.insideSchedules?.length > 0) {
        this.insideSchedules.forEach((e) => (ids += e.id + ","));
        ids = ids.slice(0, -1);
        fetchWrapper
          .del(`accounts/schedules/${ids}/delete/`)
          .then(() => this.fetchSchedules());
      }
    },
    switchPreviousMonth() {
      this.startMonth = this.startMonth.clone().subtract(1, "M");
    },
    switchNextMonth() {
      this.startMonth = this.startMonth.clone().add(1, "M");
    },
    setTime() {
      let now = new Date();
      let hour = now.getHours();
      let minute = now.getMinutes();
      let localDatetime =
        (hour < 10 ? "0" + hour.toString() : hour) +
        ":" +
        (minute < 10 ? "0" + minute.toString() : minute);
      this.times.start_time = localDatetime;
      this.times.end_time = localDatetime;
      this.replacementSheet.start_time = localDatetime;
      this.replacementSheet.end_time = localDatetime;
    },
    setShiftTime() {
      let dateSchedule = this.replacementSheet.schedules.find(
        (e) =>
          e.date === moment(this.replacementSheet.date).format("YYYY-MM-DD")
      );
      this.replacementSheet.start_time = dateSchedule?.start_time;
      this.replacementSheet.end_time = dateSchedule?.end_time;
    },
  },
  watch: {
    startMonth() {
      this.fetchSchedulesEmployee();
    },
    replacementSheet: {
      immediate: true,
      handler(newVal) {
        if (newVal) this.setShiftTime();
      },
      deep: true,
    },
  },
  mounted() {
    this.fetchSchedules();
    this.setTime();
  },
};
</script>

<style lang="sass" scoped>
.wrapper
  overflow: auto
  border-top-left-radius: 4px
  border-top-right-radius: 4px
  background-color: var(--default-white)

.schedule-enter-from
  opacity: 0
  transform: translateY(0px)
  pointer-events: none

.schedule-enter-active
  transition: 0.3s ease

.schedule-leave-to
  opacity: 0
  transform: translateY(0px)
  pointer-events: none

.schedule-leave-active
  transition: 0.3s ease

.schedule-move
  transition: 0.3s ease
</style>
