import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
import * as R from "ramda";

import { schemeHandlerHooks } from ".";
import { parseUrl } from "../../helpers";

import { log_warning } from "../../logger";

type useUrlSchemeHandlerArgs = {
  url: string;
  onFinish: (callback: (done: () => void) => void) => void;
};

function resolveSchemeHandler(host, plugins) {
  if (schemeHandlerHooks?.[host]) return schemeHandlerHooks?.[host];

  const elligiblePlugins = R.filter(
    R.hasPath(["module", "urlScheme"]),
    plugins
  );

  if (elligiblePlugins?.length > 0) {
    const match = R.compose(
      R.prop("handler"),
      R.head,
      R.filter(R.propEq("host", host)),
      R.map(R.path(["module", "urlScheme"]))
    )(elligiblePlugins);

    return match;
  }
}

const skipSchemeHandle = ({ url }) => {
  throw new Error(
    `Non of the installed plugins knows how to handle this urlScheme ${url}`
  );
};

export function useUrlSchemeHandler({
  url,
  onFinish,
}: useUrlSchemeHandlerArgs) {
  const { host, query } = parseUrl(url);
  const { plugins } = usePickFromState(["plugins"]);

  const useSchemeHandler =
    resolveSchemeHandler(host, plugins) || skipSchemeHandle;

  try {
    useSchemeHandler({ query, url, onFinish });
  } catch (e) {
    onFinish((done) => {
      log_warning(`unable to resolve ${url}: ${e.message}`);
      done?.();
    });
  }
}

export function handleActionSchemeUrl({ url }) {
  const { host, query } = parseUrl(url);
  const plugins = appStore.get("plugins");

  const actionScheme = resolveSchemeHandler(host, plugins) || skipSchemeHandle;

  actionScheme({ query, url });
}
