var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { h } from '@stencil/core';
import { MapToComponentField, MapToComponentMethod, VegaSlimmer } from 'vega-slimmer/core';
import { LogUtility } from '../../../../../utils/log';
import { getSystemTimezone } from '../../../../../helpers/calendar/utils';
/**
 * Render a red line that representing the current time
 */
export class VegaCalendarTimeMarkerRenderer extends VegaSlimmer {
  /**
   * takes an array of `CalendarDate` objects as input and returns an HTML element
   *
   * @param {CalendarDate[]} source
   * @returns {HTMLElement} the html element
   */
  render(source) {
    const isVisible = source.findIndex((calendarDate) => calendarDate.isToday(this.timezone)) >= 0;
    return (h("div", { class: {
        'time-marker-container': true,
        'hidden': !isVisible,
      } },
      h("div", { class: "time-marker", style: { top: this.getTimeMarkerPosition() }, ref: (div) => (this.timeMarkerRef = div) }, source.map((item) => {
        return h("div", { key: item.date, class: { active: item.isToday(this.timezone) } });
      }))));
  }
  /**
   * scroll to current time line block if change view mode to week or day
   *
   * @param {VegaCalendarViewModeType} viewMode the view mode
   */
  updateTimeLine(viewMode) {
    this.scrollToTargetTimeBlock(viewMode);
    this.syncTimeMarkerPosition(viewMode);
  }
  /**
   * remove setInterval when component destroy
   */
  clearTimer() {
    clearInterval(this.timeMarkerPositionTimer);
  }
  /**
   * Add the time mark position update logic if the component add back to page
   */
  updateTimeLineIfComponentAddBack() {
    this.syncTimeMarkerPosition(this.viewMode);
  }
  /**
   * Should display the current time block in the view if the default view mode is not month
   */
  displayCurrentTimeBlockByDefault() {
    this.scrollToTargetTimeBlock(this.viewMode);
  }
  /**
   * The function `getTimeMarkerPosition` calculates the position of the current time marker as a percentage of the day.
   *
   * @returns {string} a string representing the current time marker position as a percentage of the day.
   */
  getTimeMarkerPosition() {
    const now = new Date();
    const minutesOneDay = 24 * 60;
    if (this.timezone && this.timezone !== getSystemTimezone()) {
      try {
        const formatter = new Intl.DateTimeFormat([], {
          timeZone: this.timezone,
          hour: '2-digit',
          minute: '2-digit',
          hour12: false,
        });
        const parts = formatter.formatToParts(now);
        const hourPart = parts.find((part) => part.type === 'hour');
        const minutePart = parts.find((part) => part.type === 'minute');
        if (hourPart !== undefined && minutePart !== undefined) {
          const hours = parseInt(hourPart.value, 10);
          const minutes = parseInt(minutePart.value, 10);
          return ((hours * 60 + minutes) / minutesOneDay) * 100 + '%';
        }
      }
      catch (_a) {
        LogUtility.warn('Invalid timezone:', this.timezone);
      }
    }
    return ((now.getHours() * 60 + now.getMinutes()) / minutesOneDay) * 100 + '%';
  }
  /*
   * The below method is e2e-test covered in
   * @see{module:vega-calendar-scroll-to-current-time}
   */
  /* istanbul ignore next */
  /**
   * Update the time marker position with the time
   *
   * @param {VegaCalendarViewModeType} viewMode view mode value
   */
  syncTimeMarkerPosition(viewMode) {
    clearInterval(this.timeMarkerPositionTimer);
    if (viewMode !== 'month') {
      this.timeMarkerPositionTimer = setInterval(() => {
        if (this.timeMarkerRef) {
          this.timeMarkerRef.style.top = this.getTimeMarkerPosition();
        }
      }, 60 * 1000);
    }
  }
  /*
   * The below method is e2e-test covered in
   * @see{module:vega-calendar-scroll-to-current-time}
   * @see{module:vega-calendar-scroll-to-center-position}
   */
  /* istanbul ignore next */
  /**
   * scroll the time line in to current view
   *
   * @param {VegaCalendarViewModeType} viewMode view mode value
   */
  scrollToTargetTimeBlock(viewMode) {
    if (viewMode !== 'month') {
      // add setTimeout here to make sure call the scroll into view after time line rendered.
      const oneFrame = 16;
      setTimeout(() => {
        const calendarViewElement = this.viewRenderer.getCalendarViewElementRef();
        const top = Math.max(0, this.getViewCenterPosition());
        if (calendarViewElement && top) {
          calendarViewElement.scrollTo({ top });
        }
      }, oneFrame);
    }
  }
  /*
   * The below method is e2e-test covered in
   * @see{module:vega-calendar-scroll-to-current-time}
   * @see{module:vega-calendar-scroll-to-center-position}
   */
  /* istanbul ignore next */
  /**
   * Get the center position of the display area.
   * <div class='calendar-view'>
   *   <div class='calendar-view-title-container'></div>
   *   <div class='display-view'>
   *   <div class='empty-space'></div>
   * 		<div class='time-marker'></div>
   *   </div>
   * </div>
   *
   * @returns {number}
   */
  getViewCenterPosition() {
    const calendarViewElement = this.viewRenderer.getCalendarViewElementRef();
    if (calendarViewElement) {
      const fixedWeekHeader = calendarViewElement.querySelector('.calendar-view-title-container');
      const weekHeaderHeight = fixedWeekHeader ? fixedWeekHeader.offsetHeight : 0;
      const viewHeight = typeof calendarViewElement.offsetHeight === 'number' ? calendarViewElement.offsetHeight : 0;
      const displayViewHeight = Math.max(viewHeight - weekHeaderHeight, 0);
      const halfDisplayViewHeight = displayViewHeight / 2;
      const viewScrollHeight = typeof calendarViewElement.scrollHeight === 'number' ? calendarViewElement.scrollHeight : 0;
      const emptySpace = 16;
      const timeMarkerTop = (Number(this.getTimeMarkerPosition().replace('%', '')) / 100) *
        Math.max(viewScrollHeight - emptySpace - weekHeaderHeight, 0);
      if (!isNaN(halfDisplayViewHeight) && timeMarkerTop && timeMarkerTop > halfDisplayViewHeight) {
        return timeMarkerTop - halfDisplayViewHeight + emptySpace;
      }
    }
    return 0;
  }
}
__decorate([
  MapToComponentField()
], VegaCalendarTimeMarkerRenderer.prototype, "viewMode", void 0);
__decorate([
  MapToComponentField()
], VegaCalendarTimeMarkerRenderer.prototype, "viewRenderer", void 0);
__decorate([
  MapToComponentField()
], VegaCalendarTimeMarkerRenderer.prototype, "timezone", void 0);
__decorate([
  MapToComponentMethod('watchViewModeChange')
], VegaCalendarTimeMarkerRenderer.prototype, "updateTimeLine", null);
__decorate([
  MapToComponentMethod('disconnectedCallback')
], VegaCalendarTimeMarkerRenderer.prototype, "clearTimer", null);
__decorate([
  MapToComponentMethod('connectedCallback')
], VegaCalendarTimeMarkerRenderer.prototype, "updateTimeLineIfComponentAddBack", null);
__decorate([
  MapToComponentMethod('componentDidLoad')
], VegaCalendarTimeMarkerRenderer.prototype, "displayCurrentTimeBlockByDefault", null);
