import { resolveTimeFrameBlockSize as D, downsizeTimeFrame as F } from "../common/utils.js";
import b, { UNBOUNDED_SLICE as d } from "../../timeslice/index.js";
import { computeTimestampOffset as x } from "../../utils.js";
import { FIRST_WEEK_DAYS as L, DAY_MS as k, SHIFT_FRAME as g, SHIFT_PERIOD as U, SHIFT_BLOCK as N, CURSOR_NEXT_BLOCK as w, CURSOR_PREV_BLOCK as z, CURSOR_LINE_END as W, CURSOR_LINE_START as M, CURSOR_BLOCK_END as H, CURSOR_BLOCK_START as K, CURSOR_DOWNWARD as v, CURSOR_UPWARD as Y, CURSOR_FORWARD as V, CURSOR_BACKWARD as X, SELECTION_COLLAPSE as j, SELECTION_NEAREST as T, SELECTION_FARTHEST as I, SELECTION_TO as B, SELECTION_FROM as S } from "../../constants.js";
import q from "../common/flags.js";
import { BASE_LOCALE as G } from "../../../../../../core/Localization/datetime/restamper/constants.js";
import E from "../../../../../../primitives/time/today/main.js";
import { createIndexed as c } from "../../../../../../primitives/auxiliary/indexed/main.js";
import { isUndefined as l, isNullish as m, isBoolean as C, isFunction as J } from "../../../../../../utils/value/is.js";
import { isInfinity as p, clamp as O, mid as P, isBitSafeInteger as R, mod as Q } from "../../../../../../utils/value/number.js";
import { enumerable as a } from "../../../../../../utils/struct/property.js";
import { struct as Z } from "../../../../../../utils/struct/main.js";
class u {
  static #O = G;
  #e = 0;
  #S;
  #E;
  #C = -1;
  #R = -1;
  #n;
  #h;
  #m;
  #F = !1;
  #k;
  #T = 0;
  #d = [];
  #o = u.#O;
  #y = 12;
  #i;
  #t;
  #s = 1;
  #I;
  #f;
  #g;
  #B = E();
  #a;
  #A = -1 / 0;
  #_ = 1 / 0;
  #l = -1 / 0;
  #c = 1 / 0;
  #D = 1 / 0;
  #b = 0;
  daysInWeek = 0;
  origin;
  originTimestamp;
  #L = c(() => this.daysInWeek, this.getDayOfWeekAtIndex.bind(this));
  #U = c(() => this.#s, this.#z.bind(this));
  get fromTimestamp() {
    return this.#A;
  }
  get toTimestamp() {
    return this.#_;
  }
  get numberOfBlocks() {
    return this.#D;
  }
  get blankSelection() {
    return this.#i === this.#t && l(this.#t);
  }
  get cursor() {
    return this.#n ?? -1;
  }
  get daysOfWeek() {
    return this.#L;
  }
  get dynamicBlockHeight() {
    return this.#F;
  }
  set dynamicBlockHeight(t) {
    m(t) ? this.#F = !!t : C(t) && (this.#F = t);
  }
  set effect(t) {
    m(t) ? this.#k = void 0 : J(t) && (this.#k = t);
  }
  get firstWeekDay() {
    return this.#T;
  }
  set firstWeekDay(t) {
    if (m(t))
      this.firstWeekDay = 0;
    else if (!L.includes(t) || this.#T === (this.#T = t)) return;
  }
  get frameBlocks() {
    return this.#U;
  }
  get isAtEnd() {
    return !p(this.#c) && this.#c === this.#s - 1;
  }
  get isAtStart() {
    return !p(this.#l) && this.#l === 0;
  }
  get locale() {
    return this.#o;
  }
  set locale(t) {
    const s = this.#o;
    if (m(t))
      this.#o = u.#O;
    else if (typeof Intl < "u")
      try {
        this.#o = new Intl.Locale(t).toString();
      } catch {
        this.#o = u.#O;
      }
    this.#o !== s && this.refreshFrame(!0);
  }
  get selectionStart() {
    return this.#i;
  }
  get selectionEnd() {
    return this.#t;
  }
  get size() {
    return this.#s;
  }
  set size(t) {
    const s = Math.min(!m(t) && D(t) || 1, this.#y);
    this.#s !== (this.#s = s) && (this.#x(), this.refreshFrame());
  }
  get timeslice() {
    return this.#f;
  }
  set timeslice(t) {
    if (t === this.#I || m(t) && this.#I === d) return;
    const { from: s, to: i, timezone: h } = this.#I = t ?? d;
    this.#f = b(s, i), this.timezone = h;
  }
  get timezone() {
    return this.#g;
  }
  set timezone(t) {
    this.#f.timezone = t, this.#g = this.#f.timezone, this.#B = E(this.#g), this.#a && (this.#a(), this.#a = this.#B.subscribe(this.refreshFrame.bind(this, !0))), this.#N();
  }
  set trackCurrentDay(t) {
    C(t) ? t && !this.#a ? this.#a = this.#B.subscribe(this.refreshFrame.bind(this, !0)) : !t && this.#a && (this.#a(), this.#a = void 0) : m(t) && (this.trackCurrentDay = !1);
  }
  get units() {
    return this.#b;
  }
  #N() {
    const { from: t, to: s, span: i, offsets: h } = this.#f;
    this.#A = t - h.from, this.#_ = s - h.to, this.#D = i;
    const e = l(this.#i) ? this.#i : Math.max(this.#i, t), r = l(this.#t) ? this.#t : Math.min(this.#t, s);
    e === this.#i || r === this.#t ? (this.#i = e, this.#t = r) : this.#i = this.#t = void 0, this.reslice(), this.#y = F(12, this.numberOfBlocks), this.#s = F(this.#s, this.numberOfBlocks), this.shiftFrameToTimestamp(this.#m);
  }
  #w(t) {
    return O(this.#l, t || 0, this.#c - this.#s + 1);
  }
  #u(t, s = !0) {
    let i = new Date(t).getTime();
    if (isNaN(i)) return this.#u(Date.now());
    const { from: h, to: e } = this.#f, r = O(h, i, e);
    r !== i && s ? (i = P(h, e), (isNaN(i) || p(i)) && (i = r)) : i = r;
    const n = x(i, this.#g);
    return [i - n, n];
  }
  #z(t) {
    if (R(t) && t >= 0 && t < this.#s) {
      if (!this.#d[t]) {
        const s = this.getFrameBlockAtIndex(t);
        if (!s) return;
        const [i, h] = this.getFormattedDataForFrameBlock(s[s.inner.from][0] + k / 2), e = s.outer.from;
        this.#d[t] = c(
          {
            datetime: a(h),
            label: a(i),
            length: a(Math.ceil(s.outer.units / this.rowspan)),
            month: a(s.month),
            year: a(s.year)
          },
          (r) => {
            const n = r * this.rowspan;
            return c(this.rowspan, (f) => {
              const [o, y] = s[f + n], [A, _] = this.getFormattedDataForBlockCell(o + k / 2);
              return Z({
                datetime: a(_),
                flags: a(q(y)),
                index: a(e + f + n),
                label: a(A),
                timestamp: a(o)
              });
            });
          }
        );
      }
      return this.#d[t];
    }
  }
  #r(t) {
    t !== 0 && (this.#h += t, this.refreshFrame());
  }
  #p(t) {
    const s = this.#w(t);
    s && (this.shiftOrigin(s), this.#l -= s, this.#c -= s, this.#e = Q(this.#e - s, this.#s), this.refreshFrame());
  }
  #x() {
    const t = this.#s - 1, s = Math.min(t - this.origin % this.#s, this.#c) - t;
    s && this.#p(s);
  }
  initialize() {
    this.timeslice = d;
  }
  refreshFrame(t = !1) {
    if (this.#d.length = 0, !(l(this.#h) || t)) {
      const s = this.getFrameBlockAtIndex(this.#e), { from: i, to: h } = s.inner, [e] = this.#u(this.getTimestampAtIndex(i + this.#h), !1);
      this.#h = this.getUnitsOffsetForTimestamp(this.getTimestampAtIndex(i), e);
      const r = i + this.#h, n = O(i, r, h);
      if (n > r)
        return this.#h = this.getUnitsForFrameBlockAtIndex(--this.#e) + r - n, this.#e >= 0 ? this.refreshFrame() : (this.#e = this.#s - 1, this.shiftFrameByOffset(-1, g));
      if (n < r)
        return this.#h = r - n - 1, ++this.#e < this.#s ? this.refreshFrame() : (this.#e = 0, this.shiftFrameByOffset(1, g));
      this.#S = i, this.#E = h, this.#m = this.#u(this.getTimestampAtIndex(r), !1)[0], this.#h = this.getCursorBlockOriginTimestampOffset(this.#m), this.#n = i + this.#h;
      const f = this.#e > 0 ? this.getFrameBlockAtIndex(0) : s, o = this.#e < this.#s - 1 ? this.getFrameBlockAtIndex(this.#s - 1) : s;
      this.#C = f.inner.from, this.#R = o.inner.to, this.#b = o.outer.to + 1;
    }
    this.withCurrentDayTimestamp(), this.#k?.();
  }
  shiftFrameByOffset(t, s) {
    if (t && R(t))
      switch (s) {
        case N:
          return this.#p(t);
        case U:
          return this.#p(t * 12);
        case g:
        default:
          return this.#p(t * this.#s);
      }
  }
  shiftFrameCursor(t) {
    switch (t) {
      case X:
        return this.#r(-1);
      case V:
        return this.#r(1);
      case Y:
        return this.#r(-this.rowspan);
      case v:
        return this.#r(this.rowspan);
      case K:
        return this.#r(this.#S - this.#n);
      case H:
        return this.#r(this.#E - this.#n);
      case M:
        return this.#r(-(this.#n % this.rowspan));
      case W:
        return this.#r(this.rowspan - (this.#n % this.rowspan + 1));
      case z:
        return this.#r(-this.getUnitsForFrameBlockAtIndex((this.#e ?? 0) - 1));
      case w:
        return this.#r(this.getUnitsForFrameBlockAtIndex(this.#e ?? 0));
    }
    if (!(t < 0) && t >= this.#C && t <= this.#R)
      return this.#r(t - this.#n);
  }
  shiftFrameToTimestamp(t) {
    this.#m = this.originTimestamp = this.#u(t, !1).reduce((s, i) => s + i), this.#h = this.getCursorBlockOriginTimestampOffset(this.#m), this.reoriginate(), [this.#l, this.#c] = this.getEdgeBlockOffsetsFromOrigin(), this.#x(), this.refreshFrame(), this.#r(this.getUnitsOffsetForTimestamp(this.getTimestampAtIndex(this.#n), this.#m));
  }
  clearSelection() {
    this.blankSelection || (this.#i = this.#t = void 0, this.refreshFrame(!0));
  }
  updateSelection(t, s) {
    const i = this.#i, h = this.#t, e = this.#u(t, !1).reduce((r, n) => r + n);
    switch (s === I && (e <= i ? s = B : e >= h && (s = S)), s) {
      case S:
        this.#i = e, this.#t = Math.max(this.#i, h ?? e);
        break;
      case B:
        this.#t = e, this.#i = Math.min(i ?? e, this.#t);
        break;
      case I:
      case T: {
        let r = Math.abs(e - (i ?? e)), n = Math.abs(e - (h ?? e));
        s === T && ([r, n] = [n, r]), r > n ? this.#i = e : this.#t = e;
        break;
      }
      case j:
      default:
        this.#i = this.#t = e;
        break;
    }
    (this.#i !== i || this.#t !== h) && this.refreshFrame(!0);
  }
}
export {
  u as default
};
