import React, { forwardRef, RefObject } from "react";
import URL from "url";

import { useBuildPipesUrl } from "@applicaster/zapp-react-native-utils/reactHooks/feed";

/**
 * Merges the query params resolved from a pipes endpoint context into the url.
 * Returns the url unchanged when there is nothing to merge.
 */
export function buildUrlWithQuery(url: string, requestParams): string {
  if (!url || !requestParams?.params) {
    return url;
  }

  const parsedURL = URL.parse(url, true);

  parsedURL.query = { ...parsedURL.query, ...requestParams.params };
  parsedURL.search = null;

  return URL.format(parsedURL);
}

type Props = {
  uri: string;
} & Record<string, unknown>;

/**
 * HOC that resolves the wrapped component's `uri` against its matching Zapp
 * Pipes endpoint. Endpoint context keys are added as query params (merged into
 * the uri) and as request `headers`. Rendering is deferred until the context
 * has been resolved so the component never loads without its required headers.
 */
export function withPipesEndpoint(Component) {
  function WithPipesEndpoint(props: Props, ref: RefObject<unknown>) {
    const { requestParams } = useBuildPipesUrl({ url: props.uri });

    if (requestParams !== null) {
      const urlWithQuery = buildUrlWithQuery(props.uri, requestParams);

      return (
        <Component
          ref={ref}
          {...props}
          uri={urlWithQuery}
          headers={requestParams.headers || {}}
        />
      );
    }

    return null;
  }

  return forwardRef(WithPipesEndpoint);
}
