import * as R from "ramda";

import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
import { isNotNil } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";

export const getButtonsCount = (
  configuration: Record<string, unknown>,
  prefix: string
): number => {
  const button1Key = `${prefix}_button_1_button_enabled`;
  const button2Key = `${prefix}_button_2_button_enabled`;
  const button3Key = `${prefix}_button_3_button_enabled`;

  return R.toPairs(configuration).filter(
    ([key, value]) =>
      [button1Key, button2Key, button3Key].includes(key) && value
  ).length;
};

export const getPluginIdentifier = (
  configuration: Record<string, unknown>,
  prefix: string,
  index: number
): string => {
  const match = `${prefix}_button_\\d_assign_action`;
  const re = new RegExp(match);

  const rejectNils = R.compose(R.path([index]), R.filter(isNotNil));

  return rejectNils(
    R.toPairs(configuration)
      .filter(([key]) => R.startsWith(`${prefix}_button`, key))
      .map(([key, value]) => {
        const matched = key.match(re);

        return matched ? value : undefined;
      })
  );
};

type Label = {
  name: string;
};

type LabelContainer = {
  elements: Array<Label>;
};

type LabelExtraContainer = {
  elements: Array<LabelContainer>;
};

const withButtons = (labelName, buttons, labels) => {
  return labels.reduce((acc, label) => {
    if (label.name === labelName) {
      return [...acc, label, buttons];
    }

    return [...acc, label];
  }, []);
};

const withButtonsInContainer = (labelName, buttons, views) => {
  return views.map((view) => {
    return {
      ...view,
      elements: view.elements.reduce((acc, label) => {
        if (label.name === labelName) {
          return [...acc, label, buttons];
        }

        return [...acc, label];
      }, []),
    };
  });
};

export const insertButtonsBetweenLabels = (
  configuration: Record<string, unknown>,
  buttons,
  labels: Label[] = []
) => {
  if (R.isNil(buttons)) {
    return labels;
  }

  const position = R.pathOr(
    undefined,
    ["tv_buttons_container_position"],
    configuration
  );

  if (position === "on_top") {
    return [buttons, ...labels];
  }

  const labelsWithButtons = withButtons(position, buttons, labels);

  if (R.equals(labelsWithButtons, labels)) {
    // put buttons after all labels by default
    return [...labels, buttons];
  }

  return labelsWithButtons;
};

export const insertButtonsBetweenLabelContainers = (
  configuration: Record<string, unknown>,
  buttons,
  labelContainers: Array<LabelExtraContainer> = []
) => {
  if (R.isNil(buttons)) {
    return labelContainers;
  }

  if (R.isEmpty(labelContainers)) {
    return [buttons];
  }

  const position = R.pathOr(
    undefined,
    ["tv_buttons_container_position"],
    configuration
  );

  if (position === "on_top") {
    const firstContainerLabels = R.lensPath([0, "elements"]);

    return R.over(firstContainerLabels, R.prepend(buttons), labelContainers);
  }

  const labelContainersWithButtons = labelContainers.map((labelContainer) => {
    return {
      ...labelContainer,
      elements: withButtonsInContainer(
        position,
        buttons,
        labelContainer.elements
      ),
    };
  });

  if (R.equals(labelContainersWithButtons, labelContainers)) {
    // put buttons in last container
    const lastContainerLabels = R.lensPath([
      labelContainers.length - 1,
      "elements",
    ]);

    return R.over(lastContainerLabels, R.append(buttons), labelContainers);
  }

  return labelContainersWithButtons;
};

export const mapSelfAlignment = (horizontalPosition) => {
  switch (horizontalPosition) {
    case "left":
      return "flex-start";
    case "right":
      return "flex-end";
    case "center":
      return "center";
    default:
      return "flex-start";
  }
};

export const getTextTransform = (textTransform: string) => {
  if (R.isNil(textTransform) || R.isEmpty(textTransform)) {
    return "none";
  }

  if (textTransform.toLowerCase() === "default") {
    return "none";
  }

  return textTransform;
};

export const withAntialiasing = () => {
  if (isWeb()) {
    return {
      WebkitFontSmoothing: "antialiased",
      MozOsxFontSmoothing: "grayscale",
    };
  }

  return {};
};
