"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const pathToRegexp = require("path-to-regexp");
function _interopNamespaceDefault(e) {
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
  if (e) {
    for (const k in e) {
      if (k !== "default") {
        const d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: () => e[k]
        });
      }
    }
  }
  n.default = e;
  return Object.freeze(n);
}
const pathToRegexp__namespace = /* @__PURE__ */ _interopNamespaceDefault(pathToRegexp);
const matchFunctionsCache = {};
const pathFunctionsCache = {};
const pathKeysCache = {};
const dimensionsIn = (dimensions) => {
  return dimensions.split("+").map((pair) => pair.split("=")).reduce((acc, [key, value]) => ({ ...acc, [key]: value.split(",") }), {});
};
const dimensionsOut = (dimensions) => {
  return Object.entries(dimensions).map(([key, value]) => `${key}=${value.join(",")}`).join("+");
};
const pageNameIn = (pageName) => {
  return pageName.replace(/-([a-z])/g, (m) => m[1].toUpperCase());
};
const pageNameOut = (pageName) => {
  return pageName.replace(/([A-Z])/g, "-$1").toLowerCase();
};
const parseQuery = (query) => {
  const searchParams = new URLSearchParams(query);
  return Object.fromEntries(
    Array.from(
      searchParams,
      ([key, val]) => [key, parseInt(val, 10).toString() === val ? parseInt(val, 10) : val]
    )
  );
};
const pathToRequestState = (routing, path, query) => {
  var _a;
  if (!path.startsWith(routing.basePath.slice(0, -1))) {
    return null;
  }
  const dimensionsSegment = path.slice(routing.basePath.length, path.indexOf("/", routing.basePath.length));
  const hasDimensions = dimensionsSegment.includes("=");
  const dimensions = hasDimensions ? dimensionsIn(dimensionsSegment) : routing.defaultDimensions;
  const pagePath = hasDimensions ? path.slice(routing.basePath.length + dimensionsSegment.length) : path.slice(routing.basePath.length - 1);
  const pagePathNormalized = pagePath.endsWith("/") ? pagePath : `${pagePath}/`;
  for (const [pageName2, config] of Object.entries(routing.routes)) {
    matchFunctionsCache[_a = config.path] ?? (matchFunctionsCache[_a] = pathToRegexp__namespace.match(config.path, { decode: decodeURIComponent }));
    const matchResult = matchFunctionsCache[config.path](pagePathNormalized);
    if (matchResult !== false) {
      const queryParameters = parseQuery(query);
      const pathParameters = config.paramsToObject ? config.paramsToObject(matchResult.params) : matchResult.params;
      const parameters2 = { ...queryParameters, ...pathParameters };
      return {
        pageName: pageName2,
        parameters: parameters2,
        dimensions: dimensions ?? {}
      };
    }
  }
  const parameters = parseQuery(query);
  let pageName;
  if (routing.pageInQuery) {
    pageName = typeof parameters.page === "string" ? parameters.page : "index";
    delete parameters.page;
  } else {
    pageName = pageNameIn(pagePathNormalized.slice(1, -1));
  }
  return {
    pageName,
    parameters,
    dimensions: dimensions ?? {}
  };
};
const requestStateToPath = (routing, request) => {
  var _a, _b;
  if (request === null) {
    throw new PageNotFound(`Unable to generate URL for empty request`);
  }
  const dimensionsString = dimensionsOut(request.dimensions);
  const dimensionsSegment = dimensionsString ? `/${dimensionsString}` : "";
  const prefix = routing.basePath.slice(0, -1) + dimensionsSegment;
  let pathSegment;
  const query = new URLSearchParams(request.parameters);
  if (!routing.routes[request.pageName]) {
    pathSegment = routing.pageInQuery ? "" : "/" + pageNameOut(request.pageName);
    if (routing.pageInQuery && request.pageName !== "index") {
      query.append("page", request.pageName);
    }
  } else {
    const route = routing.routes[request.pageName];
    const pathParameters = route.objectToParams ? route.objectToParams(request.parameters) : request.parameters;
    pathFunctionsCache[_a = route.path] ?? (pathFunctionsCache[_a] = pathToRegexp__namespace.compile(route.path, { encode: encodeURIComponent }));
    pathSegment = pathFunctionsCache[route.path](pathParameters);
    pathKeysCache[_b = route.path] ?? (pathKeysCache[_b] = pathToRegexp__namespace.parse(route.path).flatMap((it) => typeof it !== "string" && typeof it.name === "string" ? [it.name] : []));
    pathKeysCache[route.path].forEach((key) => query.delete(key));
  }
  const queryString = query.toString();
  const querySegment = queryString ? `?${queryString}` : "";
  return prefix + pathSegment + querySegment || "/";
};
class PageNotFound extends Error {
  constructor(reason) {
    super("Page not found" + (reason && ": " + reason));
  }
}
exports.PageNotFound = PageNotFound;
exports.dimensionsIn = dimensionsIn;
exports.dimensionsOut = dimensionsOut;
exports.pageNameIn = pageNameIn;
exports.pageNameOut = pageNameOut;
exports.pathToRequestState = pathToRequestState;
exports.requestStateToPath = requestStateToPath;
//# sourceMappingURL=urlMapper.cjs.map
