import { useEffect, useState } from "preact/hooks";
import { getConfig } from "./config";
import { exposeKit } from "./kit";

/**
 * Pro UI slots. The Free table app marks where Pro parts go (winner badges,
 * numeric bars, stock icons, "Add selected to cart"); the Pro add-on's
 * table module (`pro_chunk` in the config, built in the add-on) fills them.
 * It loads only when Pro is active, so Free shoppers never download it.
 */
const registry = {};
let loading = null;
let loaded = false;

/** The component registered for a slot, or null. */
export function slot(name) {
  return registry[name] || null;
}

/** Loads the Pro chunk once (resolves right away without Pro). */
export function loadPro() {
  const url = getConfig().pro && getConfig().pro_chunk;

  if (!url) {
    return Promise.resolve();
  }

  exposeKit();
  loading =
    loading ||
    import(/* @vite-ignore */ url)
      .then((pro) => Object.assign(registry, pro.slots))
      // Without the Pro parts the table still works.
      .catch(() => {})
      .finally(() => {
        loaded = true;
      });

  return loading;
}

/** True once the Pro chunk is in (or not needed). */
export function useProReady() {
  const [ready, setReady] = useState(
    loaded || !(getConfig().pro && getConfig().pro_chunk),
  );

  useEffect(() => {
    if (!ready) {
      loadPro().then(() => setReady(true));
    }
  }, [ready]);

  return ready;
}

/**
 * Renders a slot's Pro component with the given props, else `children`
 * (or nothing).
 */
export function Slot({ name, children = null, ...props }) {
  const Component = registry[name];

  return Component ? <Component {...props}>{children}</Component> : children;
}
