<template>
  <div>
    <h2 class="chill-red">{{ $t('edit_your_calendar_range') }}</h2>

    <div class="form-check">
      <input type="checkbox" id="myCalendar" class="form-check-input" v-model="showMyCalendarWidget" />
      <label class="form-check-label" for="myCalendar">{{ $t('show_my_calendar') }}</label>
    </div>
    <div class="form-check">
      <input type="checkbox" id="weekends" class="form-check-input" @click="toggleWeekends" />
      <label class="form-check-label" for="weekends">{{ $t('show_weekends') }}</label>
    </div>

    <FullCalendar ref="fullCalendar" :options="calendarOptions">
      <template v-slot:eventContent='arg' >
        <span class='calendarRangeItems'>
          <b v-if="arg.event.extendedProps.myCalendar" style="text-decoration: underline" >{{ arg.timeText }}</b>
          <b v-else-if="!arg.event.extendedProps.myCalendar && arg.event.extendedProps.toDelete" style="text-decoration: line-through red" >{{ arg.timeText }}</b>
          <b v-else >{{ arg.timeText }}</b>
          <i>&nbsp;{{ arg.event.title }}</i>
          <a v-if=!arg.event.extendedProps.myCalendar class="fa fa-fw fa-times"
            @click.prevent="onClickDelete(arg.event)">
          </a>
        </span>
      </template>
    </FullCalendar>
    <div>
      <ul class="record_actions">
        <!-- <li>
          <button class="btn btn-save" :disabled="!dirty"
            @click.prevent="onClickSave">
            {{ $t('action.save')}}
          </button>
          <span v-if="flag.loading" class="loading">
            <i class="fa fa-circle-o-notch fa-spin fa-fw"></i>
            <span class="sr-only">{{ $t('loading') }}</span>
          </span>
        </li> -->
        <li>
          <button v-if="disableCopyDayButton" class="btn btn-action" disabled>
            {{ $t('copy_range_to_next_day')}}
          </button>
          <button v-else class="btn btn-action"
            @click.prevent="copyDay">
            {{ $t('copy_range_from_day')}} {{this.lastNewDate.toLocaleDateString()}} {{ $t('to_the_next_day')}}
          </button>
        </li>
      </ul>
    </div>
    <div>
      <div v-if="newCalendarRanges.length > 0">
        <h4>{{ $t('new_range_to_save') }}</h4>
        <ul>
          <li v-for="i in newCalendarRanges" :key="i.start">
            {{ i.start.toLocaleString() }} - {{ i.end.toLocaleString() }}
          </li>
        </ul>
      </div>
      <div v-if="updateCalendarRanges.length > 0">
        <h4>{{ $t('update_range_to_save') }}</h4>
        <ul>
          <li v-for="i in updateCalendarRanges" :key="i.start">
            {{ i.start.toLocaleString() }} - {{ i.end.toLocaleString() }}
          </li>
        </ul>
      </div>
      <div v-if="deleteCalendarRanges.length > 0">
        <h4>{{ $t('delete_range_to_save') }}</h4>
        <ul>
          <li v-for="i in deleteCalendarRanges" :key="i.start">
            {{ i.start.toLocaleString() }} - {{ i.end.toLocaleString() }}
          </li>
        </ul>
      </div>
    </div>
  </div>

  <teleport to="body">
    <modal v-if="modal.showModal"
      :modalDialogClass="modal.modalDialogClass"
      @close="modal.showModal = false">

        <template v-slot:header>
          <h2 class="modal-title">{{ this.renderEventDate() }}</h2>
        </template>

        <template v-slot:body>
          <p>{{ $t('by')}} {{this.myCalendarClickedEvent.user.username }}</p>
          <p>{{ $t('main_user_concerned') }} : {{ this.myCalendarClickedEvent.mainUser.username }}</p>
          <p v-if="myCalendarClickedEvent.comment.length > 0" >{{ this.myCalendarClickedEvent.comment }}</p>
        </template>

        <template v-slot:footer>
          <ul class="record_actions">
            <li>
              <a
                class="btn btn-show"
                :href=myCalendarEventShowLink() >
              </a>
            </li>
            <li>
              <a
                class="btn btn-update"
                :href=myCalendarEventUpdateLink() >
              </a>
            </li>
            <li>
              <a
                class="btn btn-delete"
                :href=myCalendarEventDeleteLink() >
              </a>
            </li>
          </ul>
        </template>

      </modal>
  </teleport>
</template>

<script>
import '@fullcalendar/core/vdom'; // solves problem with Vite
import frLocale from '@fullcalendar/core/locales/fr';
import FullCalendar from '@fullcalendar/vue3';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
import timeGridPlugin from '@fullcalendar/timegrid';
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
import { deleteCalendarRange, fetchCalendar, fetchCalendarRangesByUser, patchCalendarRange, postCalendarRange } from '../_api/api';
import { mapState } from 'vuex';

export default {
  name: "App",
  components: {
    FullCalendar,
    Modal
  },
  data() {
    return {
      errorMsg: [],
      modal: {
        showModal: false,
        modalDialogClass: "modal-dialog-scrollable modal-m"
      },
      flag: {
        loading: false
      },
      userId: window.userId,
      showMyCalendar: true,
      myCalendarClickedEvent: null,
      calendarEvents: {
        userCalendar: null,
        userCalendarRange: null,
        new: {
          events: [],
          color: "#3788d8"
        }
      },
      lastNewDate: null,
      disableCopyDayButton: true,
      calendarOptions: {
        locale: frLocale,
        plugins: [ dayGridPlugin, interactionPlugin, timeGridPlugin ],
        initialView: 'timeGridWeek',
        initialDate: window.startDate !== undefined ? window.startDate : new Date(),
        eventSource: [],
        selectable: true,
        select: this.onDateSelect,
        eventChange: this.onEventChange,
        eventDrop: this.onEventDropOrResize,
        eventResize: this.onEventDropOrResize,
        eventClick: this.onEventClick,
        selectMirror: false,
        editable: true,
        weekends: false,
        slotDuration: '00:15:00',
        slotMinutes: 15,
        slotMinTime: "08:00:00",
        slotMaxTime: "18:00:00",
        headerToolbar: {
          left: 'prev,next today',
          center: 'title',
          right: 'dayGridMonth,timeGridWeek,timeGridDay'
        },
      },
    }
  },
  computed: {
    ...mapState({
      newCalendarRanges: state => state.newCalendarRanges,
      updateCalendarRanges: state => state.updateCalendarRanges,
      deleteCalendarRanges: state => state.deleteCalendarRanges,
      dirty: state => state.newCalendarRanges.length > 0 || state.updateCalendarRanges.length > 0 || state.deleteCalendarRanges.length > 0
    }),
    showMyCalendarWidget: {
      set(value) {
        this.toggleMyCalendar(value);
        this.updateEventsSource();
      },
      get() {
        return this.showMyCalendar;
      }
    },
  },
  methods: {
    init() {
      console.log('init')
      this.fetchData();
    },
    openModal() {
      this.modal.showModal = true;
    },
    myCalendarEventShowLink() {
      return `/fr/calendar/calendar/${this.myCalendarClickedEvent.id}/show?user_id=${ this.userId }`
    },
    myCalendarEventUpdateLink() {
      return `/fr/calendar/calendar/${this.myCalendarClickedEvent.id}/edit?user_id=${ this.userId }`
    },
    myCalendarEventDeleteLink() {
      return `/fr/calendar/calendar/${this.myCalendarClickedEvent.id}/delete?user_id=${ this.userId }`
    },
    resetCalendar() {
      this.fetchData();
      this.calendarEvents.new = {
        events: [],
        color: "#3788d8"
      };
      this.updateEventsSource();
    },
    fetchData() {
      this.flag.loading = true;
      fetchCalendarRangesByUser(this.userId).then(calendarRanges => new Promise((resolve, reject) => {
        // console.log('calendar ranges', calendarRanges.results)
        let events = calendarRanges.results.map(i =>
          ({
            start: i.startDate.datetime,
            end: i.endDate.datetime,
            calendarRangeId: i.id,
            toDelete: false
          })
        );
        let calendarRangeEvents = {
          events: events,
          borderColor: "#3788d8",
          backgroundColor: '#ffffff',
          textColor: '#444444',
        };
        this.calendarEvents.userCalendarRange = calendarRangeEvents;

        fetchCalendar(this.userId).then(calendar => new Promise((resolve, reject) => {
          let events = calendar.results.map(i =>
            ({
              myCalendar: true,
              calendarId: i.id,
              start: i.startDate.datetime,
              end: i.endDate.datetime,
              user: i.user,
              mainUser: i.mainUser,
              persons: i.persons,
              professionals: i.professionals,
              comment: i.comment
            })
          );
          let calendarEventsCurrentUser = {
              events: events,
              color: 'darkblue',
              id: 1000,
              editable: false
          };
          this.calendarEvents.userCalendar = calendarEventsCurrentUser;
          this.updateEventsSource();
          this.flag.loading = false;
          resolve();
        }));

      resolve();
      }));
    },
    updateEventsSource() {
      this.calendarOptions.eventSources = [];
      this.calendarOptions.eventSources.push(this.calendarEvents.new);
      this.calendarOptions.eventSources.push(this.calendarEvents.userCalendarRange);
      if (this.showMyCalendar) {
          this.calendarOptions.eventSources.push(this.calendarEvents.userCalendar);
      }
      // console.log(this.calendarOptions.eventSources);
    },
    toggleMyCalendar(value) {
      this.showMyCalendar = value;
    },
    toggleWeekends: function() {
      this.calendarOptions.weekends = !this.calendarOptions.weekends;
    },
    onDateSelect(payload) {
      // console.log('payload', payload);
      let events = this.calendarEvents.new.events;
      // events.push({
      //     start: payload.startStr,
      //     end: payload.endStr
      // });
      // this.calendarEvents.new = {
      //   events: events,
      //   borderColor: "#3788d8",
      //   backgroundColor: '#fffadf',
      //   textColor: '#444444',
      // };
      this.disableCopyDayButton = false;
      this.lastNewDate = new Date(payload.startStr);
      this.updateEventsSource();
      // this.$store.dispatch('createRange', payload);
      postCalendarRange({
        user: {
            type: 'user',
            id: window.userId,
        },
        startDate: {
            datetime: `${payload.start.toISOString().split('.')[0]}+0000`, //should be like "2021-08-20T15:00:00+0200",
        },
        endDate: {
            datetime: `${payload.end.toISOString().split('.')[0]}+0000`, // TODO check if OK with time zone
        },
      }).then(() => {
        this.init();
      })
    },
    onEventChange(payload) {
    },
    onEventDropOrResize(payload) {
      payload.event.setProp('borderColor', '#3788d8');
      payload.event.setProp('backgroundColor', '#fffadf');
      payload.event.setProp('textColor', '#444444');
      this.$store.dispatch('updateRange', payload);
    },
    onEventClick(payload) {
      if (payload.event.extendedProps.myCalendar) {
        this.myCalendarClickedEvent = {
          id: payload.event.extendedProps.calendarId,
          start: payload.event.start,
          end: payload.event.end,
          user: payload.event.extendedProps.user,
          mainUser: payload.event.extendedProps.mainUser,
          persons: payload.event.extendedProps.persons,
          professionals: payload.event.extendedProps.professionals,
          comment: payload.event.extendedProps.comment
        };
        // console.log(this.myCalendarClickedEvent)
        this.openModal();
      }
    },
    // onClickSave(payload) {
    //   this.flag.loading = true;
    //   if (this.$store.state.newCalendarRanges.length > 0){
    //     Promise.all(this.$store.state.newCalendarRanges.map(cr => {
    //         postCalendarRange({
    //           user: {
    //               type: 'user',
    //               id: window.userId,
    //           },
    //           startDate: {
    //               datetime: `${cr.start.toISOString().split('.')[0]}+0000`, //should be like "2021-08-20T15:00:00+0200",
    //           },
    //           endDate: {
    //               datetime: `${cr.end.toISOString().split('.')[0]}+0000`, // TODO check if OK with time zone
    //           },
    //         })
    //       })
    //     ).then((_r) => this.resetCalendar());

    //     this.$store.dispatch('clearNewCalendarRanges', payload);
    //   }
    //   if (this.$store.state.updateCalendarRanges.length > 0){
    //     Promise.all(this.$store.state.updateCalendarRanges.map(cr => {
    //         patchCalendarRange(cr.id,
    //           {
    //           startDate: {
    //               datetime: `${cr.start.toISOString().split('.')[0]}+0000`, //should be like "2021-08-20T15:00:00+0200",
    //           },
    //           endDate: {
    //               datetime: `${cr.end.toISOString().split('.')[0]}+0000`, // TODO check if OK with time zone
    //           },
    //         })
    //       })
    //     ).then((_r) => this.resetCalendar());
    //     this.$store.dispatch('clearUpdateCalendarRanges', payload);
    //   }
    //   if (this.$store.state.deleteCalendarRanges.length > 0){
    //     Promise.all(this.$store.state.deleteCalendarRanges.map(cr => {
    //         deleteCalendarRange(cr.id)
    //       })
    //     ).then((_r) => this.resetCalendar());
    //     this.$store.dispatch('clearDeleteCalendarRanges', payload);
    //   }

    // },
    onClickDelete(payload) {
      if (payload.extendedProps.hasOwnProperty("calendarRangeId")) {
        deleteCalendarRange(payload.extendedProps.calendarRangeId).then(() => {
          this.init();
        })
        // if (payload.extendedProps.toDelete) {
        //   payload.setExtendedProp('toDelete', false)
        //   payload.setProp('borderColor', '#79bafc');
        //   this.$store.dispatch('removeFromDeleteRange', payload);
        // } else {
        //   payload.setExtendedProp('toDelete', true)
        //   payload.setProp('borderColor', '#dddddd');
        //   this.$store.dispatch('deleteRange', payload);
        // }
      } else {
        let newEvents = this.calendarEvents.new.events;
        let filterEvents = newEvents.filter((e) => 
          e.start !== payload.startStr && e.end !== payload.endStr
        );
        this.calendarEvents.new = {
          events: filterEvents,
          color: "#3788d8"
        };

        this.$store.dispatch('removeNewCalendarRanges', payload);

        this.updateEventsSource();
      }

    },
    isSameDay(date1, date2) {
      return date1.getFullYear() === date2.getFullYear() &&
          date1.getMonth() === date2.getMonth() &&
          date1.getDate() === date2.getDate();
    },
    isFriday(date) {
      return date.getDay() === 5
    },
    copyDay(_payload) {
      // console.log(this.calendarEvents.new);
      if (this.calendarEvents.new.events.length > 0) {
        // Create the copied events
        let increment = !this.calendarOptions.weekends && this.isFriday(this.lastNewDate) ? 24*60*60*1000*3 : 24*60*60*1000;
        let events = this.calendarEvents.new.events.filter(
          i => this.isSameDay(new Date(i.start), this.lastNewDate)).map(
            i => {
              let startDate = new Date(new Date(i.start).getTime() + increment);
              let endDate = new Date(new Date(i.end).getTime() + increment);
              return ({
                start: startDate.toISOString(),
                end: endDate.toISOString()
              })
            }
        );
        let copiedEvents = {
          events: events,
          color: "#3788d8"
        };
        // console.log(copiedEvents);
 
        // Add to the calendar
        let newEvents = this.calendarEvents.new.events;
        newEvents.push(...copiedEvents.events);
        this.calendarEvents.new = {
          events: newEvents,
          color: "#3788d8"
        };
        this.updateEventsSource();
        
        // Set the last new date
        this.lastNewDate = new Date(copiedEvents.events[copiedEvents.events.length - 1].start);

        // Dispatch in store for saving
        for (let i = 0; i < copiedEvents.events.length; i++) {
          let eventObj = {
            start: new Date(copiedEvents.events[i].start),
            end: new Date(copiedEvents.events[i].end)
          }
          this.$store.dispatch('createRange', eventObj);
        }

      } else {
        console.log('no new events to copy-paste!')
      }
    },
    renderEventDate() {
      let start = this.myCalendarClickedEvent.start;
      let end = this.myCalendarClickedEvent.end;
      return start.getDate() === end.getDate() ?
          `${start.toLocaleDateString()}, ${start.toLocaleTimeString()} - ${end.toLocaleTimeString()}` :
          `${start.toLocaleString()} - ${end.toLocaleString()}`;
    }
  },
  mounted() {
    this.init();
  }
}
</script>
