import { longFormatters as W } from "./_lib/format/longFormatters.js";
import { isProtectedWeekYearToken as L, warnOrThrowProtectedError as b, isProtectedDayOfYearToken as j } from "./_lib/protectedTokens.js";
import { constructFrom as q } from "./constructFrom.js";
import { getDefaultOptions as v } from "./getDefaultOptions.js";
import { toDate as A } from "./toDate.js";
import { DateTimezoneSetter as z } from "./parse/_lib/Setter.js";
import { parsers as Q } from "./parse/_lib/parsers.js";
import { enUS as H } from "./locale/en-US.js";
const I = /[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g, K = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g, M = /^'([^]*?)'?$/, U = /''/g, Z = /\S/, B = /[a-zA-Z]/;
function te(a, i, f, e) {
  var w, d, T, O, y, E, R, x;
  const c = () => q((e == null ? void 0 : e.in) || f, NaN), l = v(), m = (e == null ? void 0 : e.locale) ?? l.locale ?? H, F = (e == null ? void 0 : e.firstWeekContainsDate) ?? ((d = (w = e == null ? void 0 : e.locale) == null ? void 0 : w.options) == null ? void 0 : d.firstWeekContainsDate) ?? l.firstWeekContainsDate ?? ((O = (T = l.locale) == null ? void 0 : T.options) == null ? void 0 : O.firstWeekContainsDate) ?? 1, $ = (e == null ? void 0 : e.weekStartsOn) ?? ((E = (y = e == null ? void 0 : e.locale) == null ? void 0 : y.options) == null ? void 0 : E.weekStartsOn) ?? l.weekStartsOn ?? ((x = (R = l.locale) == null ? void 0 : R.options) == null ? void 0 : x.weekStartsOn) ?? 0;
  if (!i)
    return a ? c() : A(f, e == null ? void 0 : e.in);
  const u = {
    firstWeekContainsDate: F,
    weekStartsOn: $,
    locale: m
  }, k = [new z(e == null ? void 0 : e.in, f)], Y = i.match(K).map((r) => {
    const t = r[0];
    if (t in W) {
      const n = W[t];
      return n(r, m.formatLong);
    }
    return r;
  }).join("").match(I), g = [];
  for (let r of Y) {
    !(e != null && e.useAdditionalWeekYearTokens) && L(r) && b(r, i, a), !(e != null && e.useAdditionalDayOfYearTokens) && j(r) && b(r, i, a);
    const t = r[0], n = Q[t];
    if (n) {
      const { incompatibleTokens: D } = n;
      if (Array.isArray(D)) {
        const C = g.find(
          (P) => D.includes(P.token) || P.token === t
        );
        if (C)
          throw new RangeError(
            `The format string mustn't contain \`${C.fullToken}\` and \`${r}\` at the same time`
          );
      } else if (n.incompatibleTokens === "*" && g.length > 0)
        throw new RangeError(
          `The format string mustn't contain \`${r}\` and any other token at the same time`
        );
      g.push({ token: t, fullToken: r });
      const h = n.run(
        a,
        r,
        m.match,
        u
      );
      if (!h)
        return c();
      k.push(h.setter), a = h.rest;
    } else {
      if (t.match(B))
        throw new RangeError(
          "Format string contains an unescaped latin alphabet character `" + t + "`"
        );
      if (r === "''" ? r = "'" : t === "'" && (r = G(r)), a.indexOf(r) === 0)
        a = a.slice(r.length);
      else
        return c();
    }
  }
  if (a.length > 0 && Z.test(a))
    return c();
  const N = k.map((r) => r.priority).sort((r, t) => t - r).filter((r, t, n) => n.indexOf(r) === t).map(
    (r) => k.filter((t) => t.priority === r).sort((t, n) => n.subPriority - t.subPriority)
  ).map((r) => r[0]);
  let s = A(f, e == null ? void 0 : e.in);
  if (isNaN(+s))
    return c();
  const o = {};
  for (const r of N) {
    if (!r.validate(s, u))
      return c();
    const t = r.set(s, o, u);
    Array.isArray(t) ? (s = t[0], Object.assign(o, t[1])) : s = t;
  }
  return s;
}
function G(a) {
  return a.match(M)[1].replace(U, "'");
}
export {
  te as default,
  W as longFormatters,
  te as parse,
  Q as parsers
};
