import { useCallback, useMemo } from "react";
import { requestChangeFactory, useCurrentRequest, usePushRequest } from "./RequestContext.js";
import { useRouting } from "./RoutingContext.js";
import { RoutingParameter } from "./RoutingParameter.js";
import { requestStateToPath, PageNotFound } from "./urlMapper.js";
const isRoutingLinkTarget = (value) => {
  return typeof value === "string" || typeof value === "function" || typeof value === "object" && value !== null && "pageName" in value;
};
const targetToRequest = (target, currentRequest) => {
  if (typeof target === "string") {
    return requestChangeFactory(target, {})(currentRequest);
  }
  if (typeof target === "function") {
    return target(currentRequest);
  }
  if (target === null) {
    return null;
  }
  return target;
};
const resolveParameters = (parameters, resolveParameter) => {
  return Object.fromEntries(Object.entries(parameters).map(([name, value]) => {
    if (value instanceof RoutingParameter) {
      return [name, resolveParameter(value.name)];
    }
    return [name, value];
  }));
};
const useRoutingLinkFactory = () => {
  const currentRequest = useCurrentRequest();
  const routing = useRouting();
  const pushRequest = usePushRequest();
  return useCallback((target, parameters, parametersResolver) => {
    const tmpRequest = targetToRequest(target, currentRequest);
    const request = tmpRequest === null ? null : {
      pageName: tmpRequest.pageName,
      dimensions: tmpRequest.dimensions ?? currentRequest?.dimensions ?? {},
      parameters: resolveParameters(tmpRequest.parameters ?? {}, (param) => {
        if (param.startsWith("request.")) {
          return currentRequest?.parameters[param.slice("request.".length)];
        }
        if (parameters && param in parameters) {
          return parameters[param];
        }
        if (!parametersResolver) {
          throw new PageNotFound(`Routing parameter ${param} not found`);
        }
        return parametersResolver?.(param);
      })
    };
    let href;
    try {
      href = requestStateToPath(routing, request);
    } catch (e) {
      href = "#";
    }
    return {
      href,
      isActive: window.location.pathname === href,
      navigate: (e) => {
        e?.preventDefault();
        pushRequest(request);
      }
    };
  }, [currentRequest, pushRequest, routing]);
};
const useRoutingLink = (target, parametersResolver, parameters) => {
  const linkFactory = useRoutingLinkFactory();
  return useMemo(() => {
    return linkFactory(target, parameters, parametersResolver);
  }, [linkFactory, parameters, parametersResolver, target]);
};
export { isRoutingLinkTarget, targetToRequest, useRoutingLink, useRoutingLinkFactory };
//# sourceMappingURL=useRoutingLink.js.map
