import { ResponsiveUIHelper } from '@dvn/alaca/utils/ui';
import { takvimDailyCalendarI18nDefault } from './i18n';
import { Component, Element, Event, h, Host, Method, Prop, State } from '@stencil/core';
import CalendarUtils from "@dvn/core/util/calendar";
const horizontalPadding = 24;
const indicatorMinutes = 15;
export class TakvimDailyCalendar {
  constructor() {
    this.calendarData = [];
    this.meetings = [];
    this.everyPixelsForMinute = 5;
    this.selectedDay = new Date();
    this.currentTimeIndicatorLeftPosition = 0;
    this.isProgressing = true;
    this.strings = takvimDailyCalendarI18nDefault;
    this.onSizeChange = (size) => {
      this.size = size;
    };
    this.onDateChange = (date) => {
      this.setSelectedDay(date);
      this.fetchMeetings();
    };
    this.iterateDay = (amount) => {
      const day = new Date(this.selectedDay);
      day.setDate(this.selectedDay.getDate() + amount);
      this.setSelectedDay(day);
      this.fetchMeetings();
    };
    this.setSelectedDay = (date) => {
      const day = new Date(date);
      day.setHours(0, 0, 0, 0);
      this.selectedDay = day;
    };
    this.getCurrentTimeIndicatorLeftPosition = () => {
      const { earliestStartTime, latestEndTime, everyPixelsForMinute } = this;
      let currentTimeIndicatorLeft = 0;
      const currentSeconds = new Date().getTime() / 1000;
      if (earliestStartTime && latestEndTime && earliestStartTime < currentSeconds && currentSeconds < latestEndTime) {
        const currentSecondsDistanceInSeconds = currentSeconds - earliestStartTime;
        if (currentSecondsDistanceInSeconds > 0) {
          const currentSecondsDistanceInMinutes = currentSecondsDistanceInSeconds / 60;
          currentTimeIndicatorLeft = (currentSecondsDistanceInMinutes * everyPixelsForMinute) + horizontalPadding;
        }
      }
      return currentTimeIndicatorLeft;
    };
    this.generateTimeIntervalIndicatorPositions = () => {
      const { earliestStartTime, latestEndTime } = this;
      if (!earliestStartTime) {
        return [];
      }
      const lines = [];
      for (let i = 0; i < 24 * 60; i += indicatorMinutes) {
        if ((i - indicatorMinutes) > ((latestEndTime - earliestStartTime) / 60)) {
          break;
        }
        lines.push(i);
      }
      return lines;
    };
  }
  componentWillLoad() {
    this.uiHelper = new ResponsiveUIHelper(this.el, this.onSizeChange);
    this.size = ResponsiveUIHelper.getSize(this.el.parentElement.clientWidth);
    this.setSelectedDay(new Date());
    // update the current time indicator position ever minute
    this.currentTimePositionUpdater = setInterval(() => this.currentTimeIndicatorLeftPosition = this.getCurrentTimeIndicatorLeftPosition(), 60 * 1000);
  }
  componentDidLoad() {
    this.fetchMeetings();
  }
  disconnectedCallback() {
    clearInterval(this.currentTimePositionUpdater);
  }
  async invalidate(_event) {
    this.meetings = undefined;
    this.error = undefined;
    this.fetchMeetings();
  }
  ;
  async fetchMeetings() {
    const { calendarConfigId } = this;
    this.isProgressing = true;
    const secondsInOneDay = 24 * 60 * 60;
    const startTime = Math.floor(this.selectedDay.getTime() / 1000);
    const endTime = startTime + secondsInOneDay;
    const calendarDataResponse = await this.apiTakvim.getMeetingsForCalendar(calendarConfigId, startTime, endTime)
      .catch(e => {
      this.error = e;
    }).finally(() => this.isProgressing = false);
    if (!calendarDataResponse)
      return;
    this.meetings = calendarDataResponse.results;
    const calendarDataMap = {};
    this.meetings.forEach(meeting => {
      const guestToGroupBy = findTheGuestByMembershipConfigId(this.membershipConfigIdToGroupMeetings, meeting);
      if (calendarDataMap[guestToGroupBy._id]) {
        calendarDataMap[guestToGroupBy._id] = Object.assign(Object.assign({}, calendarDataMap[guestToGroupBy._id]), { meetings: [...calendarDataMap[guestToGroupBy._id].meetings, meeting] });
      }
      else {
        calendarDataMap[guestToGroupBy._id] = {
          user: guestToGroupBy,
          meetings: [meeting]
        };
      }
    });
    this.calendarData = Object.values(calendarDataMap)
      .sort((a, b) => a.user.name.localeCompare(b.user.name));
    if (this.meetings.length > 0) {
      this.earliestStartTime = Math.floor(new Date(this.meetings[0].startDate).getTime() / 1000);
      this.latestEndTime = Math.floor(new Date(this.meetings[this.meetings.length - 1].endDate).getTime() / 1000);
    }
    else {
      this.earliestStartTime = 0;
      this.latestEndTime = 0;
    }
  }
  render() {
    const { calendarConfigId, calendarData, meetings, earliestStartTime, isProgressing, everyPixelsForMinute, membershipConfigId, selectedUser, strings, user, userSettings, membershipConfigIdToViewOnMeetings } = this;
    const currentTimeIndicatorLeftPosition = this.getCurrentTimeIndicatorLeftPosition();
    const timeIntervalIndicatorPositions = this.generateTimeIntervalIndicatorPositions();
    const rowWidth = timeIntervalIndicatorPositions.length * indicatorMinutes * everyPixelsForMinute;
    return (h(Host, { style: { '--horizontal-spacing': `${horizontalPadding}px` } },
      h("div", { class: "left-column" },
        h("dvn-input-group", { leaned: true },
          h("dvn-icon-button", { leaned: true, disabled: isProgressing, progressing: isProgressing, "icon-name": "uil uil-angle-left-b", onClick: () => this.iterateDay(-1) }),
          h("dvn-date-picker", { leaned: true, disabled: isProgressing, value: this.selectedDay, dateFormat: "DD MMMM, dddd", onChange: (e) => this.onDateChange(e.detail) }),
          h("dvn-icon-button", { leaned: true, disabled: isProgressing, "icon-name": "uil uil-angle-right-b", onClick: () => this.iterateDay(1) })),
        !this.isProgressing && !this.error && meetings.length === 0 &&
          h("p", { class: "text-centered p-3" }, strings.noItemInList),
        h("div", { class: "user-card-list-container", ref: el => this.userListRef = el }, calendarData.map(userData => (h("div", { class: "user-card" },
          h("dvn-info-summary", { extraClass: "flex-grow-1", title: userData.user.name },
            h("dvn-image", { slot: "media", bordered: true, leaned: true, shape: "circle", src: userData.user.imageUrl, text: userData.user.initials })),
          h("dvn-icon-button", { view: "flat", tint: "primary", iconName: "uil uil-calendar-alt", onClick: () => this.selectedUser = userData.user })))))),
      h("div", { class: "right-column", ref: el => this.meetingListRef = el, onScroll: () => this.userListRef.scrollTop = this.meetingListRef.scrollTop },
        h("div", { class: "meetings-container" },
          h("div", { class: "meetings-row-container" },
            h("div", { class: "time-indicators-container" },
              currentTimeIndicatorLeftPosition !== 0 &&
                h("div", { class: "time-indicator-line current-time", style: { left: `${currentTimeIndicatorLeftPosition}px` } }),
              timeIntervalIndicatorPositions.map(indicatorPosition => {
                // indicator position is in minutes. convert it to px
                const left = (indicatorPosition * everyPixelsForMinute) + horizontalPadding;
                if (indicatorPosition % 30 !== 0) {
                  // show the time every half hour
                  return (h("div", { class: "time-indicator-line", style: { left: `${left}px` } }));
                }
                const time = earliestStartTime + (indicatorPosition * 60);
                const timeString = CalendarUtils.format(new Date((time * 1000) - 1), 'HH:mm');
                return (h("div", { class: "time-indicator-line", style: { left: `${left}px` } },
                  h("div", { class: "time" }, timeString)));
              })),
            calendarData.map(userData => {
              return (h("div", { class: "meetings-row", style: { width: `${rowWidth}px`, margin: `0 ${-horizontalPadding}px` } }, userData.meetings.map(meeting => {
                const { endDate, startDate } = meeting;
                const startDateInSeconds = new Date(startDate).getTime() / 1000;
                const endDateInSeconds = new Date(endDate).getTime() / 1000;
                const durationInMinutes = (endDateInSeconds - startDateInSeconds) / 60;
                const distanceToStartTimeInMinutes = (startDateInSeconds - earliestStartTime) / 60;
                const width = durationInMinutes * everyPixelsForMinute;
                const left = distanceToStartTimeInMinutes * everyPixelsForMinute + horizontalPadding;
                const start = new Date(startDate);
                const end = new Date(endDate);
                const startEnd = `${CalendarUtils.format(start, 'HH:mm')} - ${CalendarUtils.format(end, 'HH:mm')}`;
                const guest = findTheGuestByMembershipConfigId(membershipConfigIdToViewOnMeetings, meeting);
                return (h("div", { class: "meeting-card", style: { left: `${left}px`, width: `${width}px`, minWidth: `${width}px` }, onClick: () => this.viewMeeting.emit(meeting) },
                  h("dvn-info-summary", { title: guest.name, subTitle: startEnd },
                    h("dvn-image", { slot: "media", bordered: true, leaned: true, src: guest.imageUrl, text: guest.initials }))));
              })));
            })))),
      selectedUser &&
        h("dvn-dialog", { title: selectedUser.name, shown: true, onDismiss: () => {
            console.log('DISMISS USER');
            this.selectedUser = undefined;
          } },
          h("takvim-available-time-picker", { apiData: this.apiData, apiTakvim: this.apiTakvim, userId: user._id, membershipConfigId: membershipConfigId, userSettings: userSettings, guests: [selectedUser], guestMetadata: [{
                membershipConfigId: this.membershipConfigIdToGroupMeetings,
              }], viewedUserId: selectedUser._id, viewedUserMembershipConfigId: membershipConfigIdToViewOnMeetings, calendarConfigId: calendarConfigId, onCreateMeeting: (_e) => {
              this.selectedUser = undefined;
              this.fetchMeetings();
            }, strings: strings.availableTimePicker, weekStartDay: userSettings.weekStartDay }))));
  }
  static get is() { return "takvim-daily-calendar"; }
  static get originalStyleUrls() { return {
    "$": ["./takvim-daily-calendar.scss"]
  }; }
  static get styleUrls() { return {
    "$": ["takvim-daily-calendar.css"]
  }; }
  static get properties() { return {
    "apiData": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "DataApi",
        "resolved": "DataApi",
        "references": {
          "DataApi": {
            "location": "import",
            "path": "@dvn/core/api"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      }
    },
    "apiTakvim": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "TakvimApi",
        "resolved": "TakvimApi",
        "references": {
          "TakvimApi": {
            "location": "import",
            "path": "@dvn/takvim/api/takvimApi"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      }
    },
    "strings": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "TakvimDailyCalendarI18n",
        "resolved": "TakvimDailyCalendarI18n",
        "references": {
          "TakvimDailyCalendarI18n": {
            "location": "import",
            "path": "./i18n"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "defaultValue": "takvimDailyCalendarI18nDefault"
    },
    "user": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "User",
        "resolved": "User",
        "references": {
          "User": {
            "location": "import",
            "path": "@dvn/kimlik/api/models"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      }
    },
    "userSettings": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "UserSettings",
        "resolved": "UserSettings",
        "references": {
          "UserSettings": {
            "location": "import",
            "path": "@dvn/kimlik/api/models/UserSettings"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      }
    },
    "calendarConfigId": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "calendar-config-id",
      "reflect": false
    },
    "membershipConfigId": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "membership-config-id",
      "reflect": false
    },
    "membershipConfigIdToGroupMeetings": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "membership-config-id-to-group-meetings",
      "reflect": false
    },
    "membershipConfigIdToViewOnMeetings": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "membership-config-id-to-view-on-meetings",
      "reflect": false
    }
  }; }
  static get states() { return {
    "calendarData": {},
    "meetings": {},
    "earliestStartTime": {},
    "latestEndTime": {},
    "everyPixelsForMinute": {},
    "selectedDay": {},
    "currentTimeIndicatorLeftPosition": {},
    "isProgressing": {},
    "selectedUser": {},
    "error": {},
    "size": {}
  }; }
  static get events() { return [{
      "method": "action",
      "name": "action",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "complexType": {
        "original": "any",
        "resolved": "any",
        "references": {}
      }
    }, {
      "method": "viewMeeting",
      "name": "viewMeeting",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "complexType": {
        "original": "any",
        "resolved": "any",
        "references": {}
      }
    }]; }
  static get methods() { return {
    "invalidate": {
      "complexType": {
        "signature": "(_event: CustomEvent<InvalidationAction>) => Promise<void>",
        "parameters": [{
            "tags": [],
            "text": ""
          }],
        "references": {
          "Promise": {
            "location": "global"
          },
          "CustomEvent": {
            "location": "global"
          },
          "InvalidationAction": {
            "location": "import",
            "path": "@dvn/core/models/actions"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "",
        "tags": []
      }
    }
  }; }
  static get elementRef() { return "el"; }
}
const findTheGuestByMembershipConfigId = (membershipConfigId, meeting) => {
  const guestIndex = meeting.guestMetadata.findIndex(guestMetadata => (guestMetadata.membershipConfigId === membershipConfigId));
  return meeting.guests[guestIndex];
};
