import { nothing, html } from 'lit';
import { styleMap } from 'lit/directives/style-map.js';
import { property, state } from 'lit/decorators.js';
import { tv } from 'tailwind-variants';
import { safeCustomElement } from '../../shared/safe-custom-element.js';
import '../lukso-icon/index.js';
import '../lukso-sanitize/index.js';
import '../lukso-form-label/index.js';
import '../lukso-form-description/index.js';
import '../lukso-form-error/index.js';
import '../lukso-time-picker/index.js';
import { TailwindStyledElement } from '../../shared/tailwind-element/index.js';
import style from './style.css.js';

var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result) __defProp(target, key, result);
  return result;
};
let LuksoDatePicker = class extends TailwindStyledElement(style) {
  constructor() {
    super(...arguments);
    this.locale = typeof navigator !== "undefined" ? navigator.language : "en-US";
    this.size = "large";
    this.showSummary = true;
    this.showTime = true;
    this.dateFormat = "short";
    this.timeFormat = "auto";
    this.weekStartDay = "monday";
    this.isDisabled = false;
    this.isFullWidth = false;
    this._viewYear = (/* @__PURE__ */ new Date()).getFullYear();
    this._viewMonth = (/* @__PURE__ */ new Date()).getMonth();
    this._selectedDate = null;
    this._selectedHour = (/* @__PURE__ */ new Date()).getHours();
    this._selectedMinute = (/* @__PURE__ */ new Date()).getMinutes();
    // ─── Styles ────────────────────────────────────────────────────────────────
    this.styles = tv({
      slots: {
        outer: "flex flex-col",
        wrapper: "flex flex-col w-full bg-neutral-100 rounded-12 shadow-drop-shadow-small overflow-hidden select-none",
        header: "flex items-center justify-between px-4 py-3",
        monthLabel: "text-paragraph-sm-bold text-neutral-20 capitalize",
        navBtn: "flex items-center justify-center w-8 h-8 rounded-full hover:bg-neutral-95 transition-colors cursor-pointer disabled:opacity-30 disabled:cursor-not-allowed",
        dayHeaderRow: "grid grid-cols-7 px-2 pb-1",
        dayHeaderCell: "flex items-center justify-center h-8 text-paragraph-xxs text-neutral-40",
        calendarGrid: "grid grid-cols-7 px-2 pb-2 justify-items-center",
        divider: "h-px bg-neutral-90 mx-4",
        // Row: reserve space for time picker (max-w on label); min-w avoids flex collapse to ~0.
        timeSection: "flex flex-row flex-nowrap items-center justify-between gap-3 px-4 py-3 w-full min-w-0",
        dateLabel: "flex flex-1 flex-col overflow-hidden min-w-[8rem] max-w-[calc(100%-9.5rem)]",
        dateLabelWeekday: "min-w-0 text-paragraph-xxs text-neutral-40 uppercase tracking-wider truncate",
        dateLabelDate: "min-w-0 text-paragraph-xs-bold text-neutral-20 truncate",
        timeRowWrap: "shrink-0"
      },
      variants: {
        size: {
          small: { outer: "w-[200px]" },
          medium: { outer: "w-[250px]" },
          large: { outer: "w-[300px]" },
          "x-large": { outer: "w-[420px]" }
        },
        isDisabled: {
          true: { outer: "opacity-50 pointer-events-none" }
        },
        isFullWidth: {
          true: { outer: "w-full" }
        }
      }
    });
    this.dayCellStyles = tv({
      base: "relative flex items-center justify-center h-9 w-9 rounded-full text-paragraph-sm transition-colors",
      variants: {
        isSelected: {
          true: "bg-neutral-20 text-neutral-100",
          false: ""
        },
        isToday: {
          true: "",
          false: ""
        },
        isOutOfRange: {
          true: "opacity-30 cursor-not-allowed pointer-events-none",
          false: "cursor-pointer hover:bg-neutral-95"
        },
        isEmpty: {
          true: "pointer-events-none",
          false: ""
        }
      },
      compoundVariants: [
        {
          isSelected: false,
          isToday: true,
          isOutOfRange: false,
          class: "ring-1 ring-neutral-20 ring-inset"
        }
      ]
    });
  }
  // ─── Lifecycle ─────────────────────────────────────────────────────────────
  willUpdate(changed) {
    if (changed.has("value")) {
      if (this.value) {
        const d = new Date(this.value);
        if (!isNaN(d.getTime())) {
          this._selectedDate = d;
          this._viewYear = d.getFullYear();
          this._viewMonth = d.getMonth();
          this._selectedHour = d.getHours();
          this._selectedMinute = d.getMinutes();
        }
      } else {
        this._selectedDate = null;
      }
    }
  }
  // ─── Computed helpers ───────────────────────────────────────────────────────
  get _monthYearLabel() {
    try {
      return new Intl.DateTimeFormat(this.locale, {
        month: "long",
        year: "numeric"
      }).format(new Date(this._viewYear, this._viewMonth));
    } catch {
      return `${this._viewMonth + 1}/${this._viewYear}`;
    }
  }
  get _dayNames() {
    const names = [];
    const monday = new Date(2025, 0, 6);
    const format = new Intl.DateTimeFormat(this.locale, { weekday: "narrow" });
    for (let i = 0; i < 7; i++) {
      const d = new Date(monday);
      d.setDate(monday.getDate() + i);
      names.push(format.format(d));
    }
    if (this.weekStartDay === "sunday") {
      const sun = names.pop();
      names.unshift(sun);
    }
    return names;
  }
  _getDayGrid() {
    const firstDay = new Date(this._viewYear, this._viewMonth, 1);
    const lastDay = new Date(this._viewYear, this._viewMonth + 1, 0);
    let startOffset = firstDay.getDay();
    if (this.weekStartDay === "monday") {
      startOffset = (startOffset + 6) % 7;
    }
    const grid = [];
    for (let i = 0; i < startOffset; i++) {
      grid.push({ day: null, date: null, isCurrentMonth: false });
    }
    for (let d = 1; d <= lastDay.getDate(); d++) {
      grid.push({
        day: d,
        date: new Date(this._viewYear, this._viewMonth, d),
        isCurrentMonth: true
      });
    }
    while (grid.length % 7 !== 0) {
      grid.push({ day: null, date: null, isCurrentMonth: false });
    }
    return grid;
  }
  _isSelected(date) {
    if (!date || !this._selectedDate) return false;
    return date.getFullYear() === this._selectedDate.getFullYear() && date.getMonth() === this._selectedDate.getMonth() && date.getDate() === this._selectedDate.getDate();
  }
  _isToday(date) {
    if (!date) return false;
    const today = /* @__PURE__ */ new Date();
    return date.getFullYear() === today.getFullYear() && date.getMonth() === today.getMonth() && date.getDate() === today.getDate();
  }
  _isOutOfRange(date) {
    if (!date) return false;
    if (this.min) {
      const minDate = new Date(this.min);
      minDate.setHours(0, 0, 0, 0);
      if (date < minDate) return true;
    }
    if (this.max) {
      const maxDate = new Date(this.max);
      maxDate.setHours(23, 59, 59, 999);
      if (date > maxDate) return true;
    }
    return false;
  }
  _formattedDateLabel() {
    if (!this._selectedDate) return null;
    try {
      const weekday = new Intl.DateTimeFormat(this.locale, {
        weekday: "short"
      }).format(this._selectedDate);
      const dateOpts = this.dateFormat === "long" ? { month: "long", day: "numeric", year: "numeric" } : { month: "short", day: "numeric", year: "numeric" };
      const date = new Intl.DateTimeFormat(this.locale, dateOpts).format(
        this._selectedDate
      );
      return { weekday: weekday.toUpperCase(), date };
    } catch {
      return null;
    }
  }
  get _timeValue() {
    return `${String(this._selectedHour).padStart(2, "0")}:${String(this._selectedMinute).padStart(2, "0")}`;
  }
  _buildIsoValue() {
    if (!this._selectedDate) return "";
    const date = this._selectedDate;
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    const hour = String(this._selectedHour).padStart(2, "0");
    const minute = String(this._selectedMinute).padStart(2, "0");
    return `${year}-${month}-${day}T${hour}:${minute}`;
  }
  // ─── Event handlers ─────────────────────────────────────────────────────────
  _prevMonth() {
    if (this._viewMonth === 0) {
      this._viewMonth = 11;
      this._viewYear -= 1;
    } else {
      this._viewMonth -= 1;
    }
  }
  _nextMonth() {
    if (this._viewMonth === 11) {
      this._viewMonth = 0;
      this._viewYear += 1;
    } else {
      this._viewMonth += 1;
    }
  }
  _selectDay(cell, event) {
    if (!cell.date || this._isOutOfRange(cell.date)) return;
    this._selectedDate = cell.date;
    this._emitChange(event);
  }
  _handleTimeChange(event) {
    event.stopPropagation();
    const value = event.detail.value;
    if (!value?.includes(":")) return;
    const [hStr, mStr] = value.split(":");
    const h = parseInt(hStr, 10);
    const m = parseInt(mStr, 10);
    if (isNaN(h) || isNaN(m)) return;
    this._selectedHour = h;
    this._selectedMinute = m;
    this._emitChange(event.detail.event);
  }
  _emitChange(event) {
    const value = this._buildIsoValue();
    if (!value) return;
    this.dispatchEvent(
      new CustomEvent("on-change", {
        detail: { value, event },
        bubbles: true,
        composed: true
      })
    );
  }
  // ─── Render ─────────────────────────────────────────────────────────────────
  render() {
    const {
      outer,
      wrapper,
      header,
      monthLabel,
      navBtn,
      dayHeaderRow,
      dayHeaderCell,
      calendarGrid,
      divider,
      timeSection,
      dateLabel,
      dateLabelWeekday,
      dateLabelDate,
      timeRowWrap
    } = this.styles({
      size: this.size,
      isDisabled: this.isDisabled,
      isFullWidth: this.isFullWidth
    });
    const grid = this._getDayGrid();
    const labelInfo = this._formattedDateLabel();
    const selectedStyleMap = styleMap({
      "background-color": this.selectedBgColor ?? null,
      color: this.selectedTextColor ?? null
    });
    return html`
      <div class=${outer()}>
        <lukso-form-label label=${this.label ?? nothing}></lukso-form-label>
        <lukso-form-description
          description=${this.description ?? nothing}
        ></lukso-form-description>

        <div class=${wrapper()}>
          <!-- Calendar header -->
          <div class=${header()}>
            <button
              type="button"
              class=${navBtn()}
              @click=${this._prevMonth}
              aria-label="Previous month"
            >
              <lukso-icon name="arrow-left-sm" size="small"></lukso-icon>
            </button>
            <span class=${monthLabel()}>${this._monthYearLabel}</span>
            <button
              type="button"
              class=${navBtn()}
              @click=${this._nextMonth}
              aria-label="Next month"
            >
              <lukso-icon name="arrow-right-sm" size="small"></lukso-icon>
            </button>
          </div>

          <!-- Day-of-week headers -->
          <div class=${dayHeaderRow()}>
            ${this._dayNames.map(
      (name) => html`<div class=${dayHeaderCell()}>${name}</div>`
    )}
          </div>

          <!-- Calendar grid -->
          <div class=${calendarGrid()}>
            ${grid.map((cell) => {
      const selected = this._isSelected(cell.date);
      const today = this._isToday(cell.date);
      const outOfRange = this._isOutOfRange(cell.date);
      const empty = cell.day === null;
      return html`
                <button
                  type="button"
                  class=${this.dayCellStyles({
        isSelected: selected,
        isToday: today,
        isOutOfRange: outOfRange,
        isEmpty: empty
      })}
                  style=${selected ? selectedStyleMap : nothing}
                  ?disabled=${empty || outOfRange}
                  aria-label=${cell.date ? cell.date.toDateString() : nothing}
                  aria-pressed=${selected ? "true" : "false"}
                  @click=${(e) => this._selectDay(cell, e)}
                >
                  ${cell.day !== null ? cell.day : nothing}
                </button>
              `;
    })}
          </div>

          <!-- Summary footer -->
          ${this.showSummary ? html`
                <div class=${divider()}></div>
                <div class=${timeSection()}>
                  <div class=${dateLabel()}>
                    <span class=${dateLabelWeekday()}
                      >${labelInfo?.weekday ?? "—"}</span
                    >
                    <span class=${dateLabelDate()}
                      >${labelInfo?.date ?? ""}</span
                    >
                  </div>
                  ${this.showTime ? html`
                        <div class=${timeRowWrap()}>
                          <lukso-time-picker
                            value=${this._timeValue}
                            locale=${this.locale}
                            time-format=${this.timeFormat}
                            ?is-standalone=${false}
                            ?is-disabled=${this.isDisabled}
                            @on-change=${this._handleTimeChange}
                            size="full"
                          ></lukso-time-picker>
                        </div>
                      ` : nothing}
                </div>
              ` : nothing}
        </div>

        <lukso-form-error error=${this.error ?? nothing}></lukso-form-error>
      </div>
    `;
  }
};
__decorateClass([
  property({ type: String })
], LuksoDatePicker.prototype, "value", 2);
__decorateClass([
  property({ type: String })
], LuksoDatePicker.prototype, "min", 2);
__decorateClass([
  property({ type: String })
], LuksoDatePicker.prototype, "max", 2);
__decorateClass([
  property({ type: String })
], LuksoDatePicker.prototype, "locale", 2);
__decorateClass([
  property({ type: String })
], LuksoDatePicker.prototype, "size", 2);
__decorateClass([
  property({ type: Boolean, attribute: "show-summary" })
], LuksoDatePicker.prototype, "showSummary", 2);
__decorateClass([
  property({ type: Boolean, attribute: "show-time" })
], LuksoDatePicker.prototype, "showTime", 2);
__decorateClass([
  property({ type: String, attribute: "date-format" })
], LuksoDatePicker.prototype, "dateFormat", 2);
__decorateClass([
  property({ type: String, attribute: "time-format" })
], LuksoDatePicker.prototype, "timeFormat", 2);
__decorateClass([
  property({ type: String, attribute: "week-start-day" })
], LuksoDatePicker.prototype, "weekStartDay", 2);
__decorateClass([
  property({ type: String })
], LuksoDatePicker.prototype, "label", 2);
__decorateClass([
  property({ type: String })
], LuksoDatePicker.prototype, "description", 2);
__decorateClass([
  property({ type: String })
], LuksoDatePicker.prototype, "error", 2);
__decorateClass([
  property({ type: String, attribute: "selected-bg-color" })
], LuksoDatePicker.prototype, "selectedBgColor", 2);
__decorateClass([
  property({ type: String, attribute: "selected-text-color" })
], LuksoDatePicker.prototype, "selectedTextColor", 2);
__decorateClass([
  property({ type: Boolean, attribute: "is-disabled" })
], LuksoDatePicker.prototype, "isDisabled", 2);
__decorateClass([
  property({ type: Boolean, attribute: "is-full-width" })
], LuksoDatePicker.prototype, "isFullWidth", 2);
__decorateClass([
  state()
], LuksoDatePicker.prototype, "_viewYear", 2);
__decorateClass([
  state()
], LuksoDatePicker.prototype, "_viewMonth", 2);
__decorateClass([
  state()
], LuksoDatePicker.prototype, "_selectedDate", 2);
__decorateClass([
  state()
], LuksoDatePicker.prototype, "_selectedHour", 2);
__decorateClass([
  state()
], LuksoDatePicker.prototype, "_selectedMinute", 2);
LuksoDatePicker = __decorateClass([
  safeCustomElement("lukso-date-picker")
], LuksoDatePicker);

export { LuksoDatePicker };
