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