import { InteractionKeyCode as c } from "../../../../types.js";
import { SELECT_NONE as R, SHIFT_BLOCK as B, SHIFT_PERIOD as F, SHIFT_FRAME as K, CALENDAR_SELECTIONS as U, SELECT_MANY as d, FIRST_WEEK_DAYS as x, CALENDAR_CONTROLS as N, FRAME_SIZES as z, CURSOR_NEXT_BLOCK as v, CURSOR_PREV_BLOCK as Y, CURSOR_BLOCK_END as j, CURSOR_LINE_END as V, CURSOR_BLOCK_START as G, CURSOR_LINE_START as X, CURSOR_DOWNWARD as q, CURSOR_UPWARD as J, CURSOR_FORWARD as Z, CURSOR_BACKWARD as $, SELECT_ONE as C, SELECTION_FROM as n, SELECTION_TO as a, CONTROLS_NONE as Q, CONTROLS_MINIMAL as tt, CONTROLS_ALL as it, SELECTION_COLLAPSE as st } from "../constants.js";
import { withTimezone as b } from "../utils.js";
import { CalendarShiftControlsFlag as A, CalendarShiftControlFlag as S } from "../types.js";
import _ from "../../../../../primitives/time/today/main.js";
import { createIndexed as y } from "../../../../../primitives/auxiliary/indexed/main.js";
import { createWatchlist as et, isWatchlistUnsubscribeToken as ht } from "../../../../../primitives/reactive/watchlist/main.js";
import { createEffectStack as D } from "../../../../../primitives/reactive/effectStack/main.js";
import rt from "../timeframe/frames/MonthFrame.js";
import { boolify as g, boolOrTrue as I } from "../../../../../utils/value/bool.js";
import { pickFrom as E } from "../../../../../utils/collection/main.js";
import { timezoneToSystem as T, systemToTimezone as p } from "../../../../../core/Localization/datetime/restamper/utils.js";
import { EMPTY_OBJECT as O } from "../../../../../utils/value/constants.js";
import { withFreezeProxyHandlers as ot, structFrom as nt, struct as ct } from "../../../../../utils/struct/main.js";
import { isFunction as m, isNullish as k, isString as L, isUndefined as H } from "../../../../../utils/value/is.js";
import { noop as w } from "../../../../../utils/common.js";
import { isBitSafeInteger as at } from "../../../../../utils/value/number.js";
class o {
  grid;
  kill;
  #i = O;
  #n = !1;
  #t;
  #c;
  #h;
  #a = !1;
  #s = R;
  #S = !1;
  #e;
  #R = this.#e?.join(" ");
  #l;
  #u;
  #r;
  #f;
  #C;
  #F = _();
  #m = [];
  #o;
  #H = new Proxy(
    y(() => this.#o?.length ?? 0, this.#N.bind(this)),
    ot({
      get: (t, i, s) => {
        const e = this.#o?.indexOf(i) ?? -1;
        return e >= 0 ? this.#N(e)?.[1] : Reflect.get(t, i, s);
      }
    })
  );
  #d = et({
    blocks: () => this.#t?.size,
    cells: () => this.#t?.units,
    controls: () => E(N, this.#i.controls),
    cursor: () => this.#t?.cursor,
    from: () => this.#t?.selectionStart,
    highlight: () => this.#s,
    locale: () => this.#t?.locale,
    minified: () => g(this.#i.minified),
    origin: () => this.#t?.getTimestampAtIndex(0),
    timezone: () => this.#t?.timezone,
    to: () => this.#t?.selectionEnd,
    today: () => this.#F.timestamp
  });
  #T = this.#d?.snapshot;
  #g = D(() => this.#r && this.#d?.requestNotification());
  #b = D(() => this.#r?.call(this.#E));
  #w = nt(
    y(
      () => this.#t?.size ?? 0,
      (t) => this.#t?.frameBlocks[t]
    ),
    {
      config: {
        value: Object.defineProperties(
          (t) => (t && this.#V(t), this.#E),
          {
            cursorIndex: {
              get: () => this.#l,
              set: (t) => {
                this.#n || (k(t) ? this.#l = void 0 : m(t) && (this.#l = t));
              }
            },
            shiftFactor: {
              get: () => this.#u,
              set: (t) => {
                this.#n || (k(t) ? this.#u = void 0 : m(t) && (this.#u = t));
              }
            },
            watch: {
              get: () => this.#r,
              set: (t) => {
                if (!this.#n)
                  if (m(t)) {
                    if (this.#r = t, !this.#f) {
                      const i = this.#g?.bind(o.#Y.bind(this));
                      i && (this.#f = this.#g?.bind(w), this.#C = this.#d?.subscribe(this.#b?.bind(i)), this.#t && (this.#t.effect = this.#f));
                    }
                    if (!this.#S) return;
                    this.#S = !1, this.#f?.();
                  } else k(t) && (this.#r = void 0);
              }
            }
          }
        )
      },
      controls: { value: this.#H },
      cursor: {
        value: Object.defineProperties(
          (t) => o.#p.call(this, (i) => !!(i && this.#G(i)))(t),
          {
            valueOf: { value: () => this.#t?.cursor ?? -1 }
          }
        )
      },
      highlight: {
        value: (() => {
          const t = () => this.#c === this.#h && H(this.#h), i = (s) => (e) => o.#p.call(this, (h) => {
            if (!(this.#n || !this.#s || this.#s === R)) {
              if (k(h)) return this.#A();
              t() ? this.#t?.updateSelection(h, st) : (this.#t?.updateSelection(h, s), this.#s === d && this.#e && this.#k(h, s === n ? a : n, this.#e)), this.#c = this.#t?.selectionStart, this.#h = this.#t?.selectionEnd, this.#t?.shiftFrameToTimestamp(s === n ? this.#c : this.#h);
            }
          })(e);
          return ct({
            blank: { get: t },
            from: {
              get: () => this.#t?.selectionStart ?? this.#c,
              set: i(n)
            },
            to: {
              get: () => this.#t?.selectionEnd ?? this.#h,
              set: i(a)
            }
          });
        })()
      },
      rowspan: { get: () => this.#t?.rowspan ?? 0 },
      weekdays: { get: () => this.#t?.daysOfWeek ?? o.#P }
    }
  );
  static #W = /^(?:0|[1-9]\d*)(\s+(?:0|[1-9]\d*)?){0,5}?$/;
  static #M = ["click", "mouseover", "pointerover"];
  static #P = y(0, w);
  static #B = [c.ENTER, c.SPACE];
  static #K = Object.keys(A).filter((t) => isNaN(+t));
  static #U = ["PREV", "NEXT"];
  static #x(t) {
    if (!L(t) || !o.#W.test(t)) return;
    const i = t.split(/\s+/);
    return Array.from({ length: 6 }, (s, e) => parseInt(i[e] ?? "0"));
  }
  static #z(t) {
    switch (t & ~S.PREV) {
      case S.FRAME:
        return K;
      case S.PERIOD:
        return F;
      case S.BLOCK:
      default:
        return B;
    }
  }
  static #v(t) {
    return t & S.PREV ? -1 : 1;
  }
  static #Y = function(t) {
    if (ht(t)) return;
    let i = !1, s = !1, e = !1;
    const h = this.#e?.join(" ");
    for (const r of Object.keys(t))
      t[r] !== this.#T?.[r] && (r === "controls" ? i = !0 : r === "highlight" ? s = !0 : (r === "from" || r === "to") && (e = !0));
    this.#R !== h && (this.#R = h, s = !0), this.#T = t, this.#a && !e && this.#_(), i && this.#L(), s && this.#I();
  };
  static #p(t) {
    return this.#g?.bind(t) ?? t;
  }
  constructor() {
    this.grid = this.#w, this.kill = this.#X.bind(this);
  }
  get #E() {
    return { ...this.#i };
  }
  get #y() {
    return new rt();
  }
  #j(t) {
    return !!this.#t && !(t > 0 ? this.#t.isAtEnd : this.#t.isAtStart);
  }
  #V(t) {
    if (this.#n) return;
    this.#e = void 0;
    const i = t?.highlight, s = g(this.#i.minified);
    if (L(i) ? (this.#e = o.#x(i)) && (this.#s = d) : this.#s = E(U, i, this.#s), this.#i = {
      ...this.#i,
      ...t,
      blocks: E(z, t?.blocks, this.#i.blocks),
      controls: E(N, t?.controls, this.#i.controls),
      firstWeekDay: E(x, t?.firstWeekDay, this.#i.firstWeekDay),
      fixedBlockHeight: g(t?.fixedBlockHeight, this.#i.fixedBlockHeight),
      highlight: this.#s,
      minified: g(t?.minified, this.#i.minified),
      trackCurrentDay: g(t?.trackCurrentDay, this.#i.trackCurrentDay)
    }, !m(this.#r)) {
      this.#t ? this.#S = !0 : (this.#t = this.#y, this.#D(), this.#L(), this.#I());
      return;
    }
    (!this.#t || s !== this.#i.minified) && (this.#t = this.#y, this.#t.effect = this.#f), this.#D(), this.#f?.();
  }
  #G(t) {
    if (t && this.#t && m(this.#r)) {
      if (t instanceof KeyboardEvent) {
        switch (t.code) {
          case c.ARROW_LEFT:
            this.#t.shiftFrameCursor($);
            break;
          case c.ARROW_RIGHT:
            this.#t.shiftFrameCursor(Z);
            break;
          case c.ARROW_UP:
            this.#t.shiftFrameCursor(J);
            break;
          case c.ARROW_DOWN:
            this.#t.shiftFrameCursor(q);
            break;
          case c.HOME:
            this.#t.shiftFrameCursor(t.ctrlKey ? G : X);
            break;
          case c.END:
            this.#t.shiftFrameCursor(t.ctrlKey ? j : V);
            break;
          case c.PAGE_UP:
            t.shiftKey ? this.#t.shiftFrameByOffset(-1, F) : this.#t.shiftFrameCursor(Y);
            break;
          case c.PAGE_DOWN:
            t.shiftKey ? this.#t.shiftFrameByOffset(1, F) : this.#t.shiftFrameCursor(v);
            break;
          case c.SPACE:
          case c.ENTER:
            return this.#O(), !0;
          default:
            return;
        }
        return this.#a && this.#O(O), !0;
      }
      if (t instanceof MouseEvent && o.#M.includes(t.type) && m(this.#l)) {
        const i = this.#l.call(this.#E, t);
        if (!at(i)) return;
        const s = t.type === "click";
        if (!(s || this.#a)) return;
        if (this.#t.shiftFrameCursor(i), this.#t.cursor === i)
          return s ? this.#O() : this.#O(O), !0;
      }
    }
  }
  #X() {
    this.#n || (this.#C?.(), this.#g = this.#b = this.#l = this.#t = this.#s = this.#R = this.#T = this.#e = this.#u = this.#C = this.#d = this.#f = this.#r = void 0, this.#i = O, this.#a = this.#S = !1, this.#n = !0);
  }
  #N(t) {
    if (!this.#o || t < 0 || t >= this.#o.length) return;
    const i = this.#o[t];
    if (!this.#m[t]) {
      const s = A[i], e = o.#z(s), h = o.#v(s);
      this.#m[t] = (...r) => o.#p.call(this, (...f) => {
        const l = this.#j(h);
        if (!(l && f.length)) return l;
        const u = this.#q(i, f[0]);
        return H(u) ? !1 : (this.#t?.shiftFrameByOffset(h * u, e), !0);
      })(...r);
    }
    return [i, this.#m[t]];
  }
  #q(t, i) {
    if (!(this.#t && m(this.#r))) return;
    if (i instanceof MouseEvent) {
      if (i.type !== "click") return;
    } else if (i instanceof KeyboardEvent) {
      if (!o.#B.includes(i.code)) return;
    } else return;
    let s = 1;
    if (m(this.#u)) {
      const e = Number(this.#u.call(this.#E, i, t));
      s = Number.isInteger(e) && e >= 1 ? e : s;
    }
    return s;
  }
  #O(t) {
    if (this.#n || !this.#t) return;
    switch (this.#s) {
      case d:
      case C:
        break;
      case R:
      default:
        return;
    }
    const i = this.#t.cursor, s = Math.max(this.#t.getTimestampAtIndex(i), this.#t.timeslice.from), e = Math.min(this.#t.getTimestampAtIndex(i + 1) - 1, this.#t.timeslice.to), h = this.#e;
    if (this.#s === C || this.#t.blankSelection || h)
      if (this.#a = !(this.#s === C || h), this.#s === d && h) {
        const r = e >= this.#t.selectionEnd ? n : a;
        r === n ? this.#t.updateSelection(e, a) : this.#t.updateSelection(s, n), this.#k(
          r === n ? this.#t.selectionEnd : this.#t.selectionStart,
          r,
          h
        );
      } else
        this.#t.updateSelection(s, n), this.#t.updateSelection(e, a);
    else {
      const r = t === O, f = b(this.#t.timezone);
      if (r || (this.#a = !1), s <= this.#t.selectionStart) {
        const l = new Date(T(f, this.#t.selectionStart)), u = Math.min(
          p(f, l.setDate(l.getDate() + 1) - 1),
          this.#t.timeslice.to
        );
        s === this.#t.selectionStart && e <= u && this.#t.updateSelection(e, a), this.#t.updateSelection(s, n);
      } else {
        const l = new Date(T(f, this.#t.selectionEnd)), u = Math.max(
          p(f, l.setHours(0, 0, 0, 0)),
          this.#t.timeslice.from
        );
        s <= this.#t.selectionEnd && s >= u && this.#t.updateSelection(s, n), this.#t.updateSelection(e, a);
      }
      if (r) return;
    }
    this.#c = this.#t.selectionStart, this.#h = this.#t.selectionEnd;
  }
  #A() {
    this.#t?.clearSelection(), this.#a = !1, this.#c = this.#h = void 0;
  }
  #k(t, i, s) {
    if (!this.#t) return;
    const e = b(this.#t?.timezone), h = new Date(T(e, t)), r = i === n ? -1 : 1, [f = 0, l = 0, u = 0, W = 0, M = 0, P = 0] = s ?? [];
    h.setFullYear(
      h.getFullYear() + f * r,
      h.getMonth() + l * r,
      h.getDate() + u * r
    ), h.setHours(
      h.getHours() + W * r,
      h.getMinutes() + M * r,
      h.getSeconds() + P * r
    ), this.#t.updateSelection(p(e, h.getTime() - r), i);
  }
  #_() {
    this.#c && this.#t?.updateSelection(this.#c, n), this.#h && this.#t?.updateSelection(this.#h, a), this.#a = !1;
  }
  #D() {
    this.#t && (this.#t.timeslice = this.#i.timeslice, this.#t.dynamicBlockHeight = !this.#i.fixedBlockHeight, this.#t.firstWeekDay = this.#i.firstWeekDay, this.#t.locale = this.#i.locale, this.#t.size = this.#i.blocks, this.#t.timezone = this.#i.timezone, this.#t.trackCurrentDay = this.#i.trackCurrentDay, this.#F = _(this.#t.timezone), this.#_());
  }
  #I() {
    switch (this.#s) {
      case d:
        !I(this.#t?.blankSelection) && this.#e && this.#k(this.#t.selectionStart, a, this.#e);
        break;
      case C:
        if (!I(this.#t?.blankSelection)) {
          const t = b(this.#t?.timezone), i = new Date(T(t, this.#t.selectionStart));
          this.#t?.updateSelection(p(t, i.setHours(23, 59, 59, 999)), a);
        }
        break;
      case R:
      default:
        this.#A();
        return;
    }
  }
  #L() {
    switch (this.#d?.snapshot.controls) {
      case it:
        this.#o = o.#K;
        break;
      case tt:
        this.#o = o.#U;
        break;
      case Q:
      default:
        this.#o = void 0;
    }
    this.#m.length = 0, this.#m.length = this.#o?.length ?? 0;
  }
}
export {
  o as default
};
