import { findPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";

import { componentsLogger } from "../../Helpers/logger";
import defaultCellRenderer from "../default-cell-renderer";

type Props = {
  component: any;
  plugins: [{ module: any; type: string; name: string }];
  styles: any;
  cellStyles: any;
  isRTL?: boolean;
  generateId?: () => string;
};

const logger = componentsLogger.addSubsystem("CellRendererResolver");

/**
 * Checks the matching cellPluginConfigurationId in the cellStyles redux store
 * and retrieves the requested renderer plugin from the plugins redux store.
 * If any of the identifiers do not match, falls back to the default renderer plugin.
 * @param {*} cellPluginConfigurationId from the "styles" section of the river component
 * @param {*} plugins from redux store
 * @param {*} cellStyles from redux store
 */
function rendererPluginFromCellStyles(
  cellPluginConfigurationId,
  plugins,
  cellStyles
) {
  const cellPluginConfiguration = cellStyles[cellPluginConfigurationId];

  if (!cellPluginConfiguration) {
    return null;
  }

  const plugin = findPluginByIdentifier(
    cellPluginConfiguration.plugin_identifier,
    plugins
  );

  return plugin;
}

/**
 * Retrieve cell renderer plugin for the component
 * @param {} component component data from rivers
 * @param {*} plugins from redux store
 * @param {*} cellStyles from redux store
 */
function getRendererPlugin(component, plugins, cellStyles) {
  if (component?.styles?.cell_plugin_configuration_id && cellStyles) {
    return rendererPluginFromCellStyles(
      component.styles.cell_plugin_configuration_id,
      plugins,
      cellStyles
    );
  }

  return null;
}

/**
 * Returns a matching cell renderer for the component type.
 * Currently returns the default cell renderer if available.
 * This section will be blown out later to a full-fledged feature
 * with support of any plugins of type "cell_builder"
 * @param {*} component component data from rivers
 * @param {*} plugins from redux store
 * @param {*} styles from redux store
 * @param {*} cellStyles from redux store
 * @returns {function|undefined} React Component to be used for rendering the component's cells
 */

export function CellRendererResolver({
  component,
  plugins,
  styles,
  cellStyles,
  ...cellOptions
}: Props) {
  const cellRendererPlugin = getRendererPlugin(component, plugins, cellStyles);

  if (!cellRendererPlugin && component.component_type !== "group-qb") {
    logger.warning({
      message: "Could not resolve cell builder plugin",
      data: { component },
    });
  }

  return (cellRendererPlugin?.module || defaultCellRenderer)({
    component,
    styles,
    cellStyles,
    cellOptions,
    ...cellOptions, // fallback for existing plugins
  });
}
