import {
  mergeRight,
  compose,
  pickBy,
  replace,
  includes,
  when,
  equals,
  always,
  nthArg,
} from "ramda";

import React from "react";
import { TextStyle, ViewStyle, View, Text, TextProps } from "react-native";

import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
import { mapKeys } from "@applicaster/zapp-react-native-utils/objectUtils";

type TextConfig = {
  enable: boolean;
  font_color: string;
  font_size: number;
  ios_font_family: string;
  android_font_family: string;
  line_height: number;
  letter_spacing_ios: number;
  letter_spacing_android: number;
  text_alignment: TextStyle["textAlign"];
  text_transform: TextStyle["textTransform"];
  number_of_lines: number;
  margin_top: number;
  margin_bottom: number;
  margin_left: number;
  margin_right: number;
  padding_top: number;
  padding_bottom: number;
  padding_left: number;
  padding_right: number;
  background_color: string;
  corner_radius: number;
};

type Props = {
  config: TextConfig;
  containerStyle?: ViewStyle;
  textStyle?: TextStyle;
  children: string;
};

const fixTextTransform = when(equals("default"), always("none"));

function getTextStyles(config: TextConfig): TextStyle {
  return {
    fontFamily: platformSelect({
      ios: config.ios_font_family,
      android: config.android_font_family,
    }),
    fontSize: config.font_size,
    color: config.font_color,
    lineHeight: config.line_height,
    letterSpacing: platformSelect({
      ios: config.letter_spacing_ios,
      android: config.letter_spacing_android,
    }),
    marginTop: config.margin_top,
    marginBottom: config.margin_bottom,
    marginLeft: config.margin_left,
    marginRight: config.margin_right,
    paddingTop: config.padding_top,
    paddingBottom: config.padding_bottom,
    paddingLeft: config.padding_left,
    paddingRight: config.padding_right,
    backgroundColor: config.background_color,
    overflow: "hidden",
    textAlign: config.text_alignment,
    textTransform: fixTextTransform(config.text_transform),
    borderRadius: config.corner_radius,
  };
}

export function getConfigKeys(prefix: string, config: Record<string, any>) {
  return compose(
    mapKeys(replace(`${prefix}_`, "")),
    pickBy(compose(includes(prefix), nthArg(1)))
  )(config);
}

export function ZappText(props: TextProps & Props) {
  const {
    config,
    containerStyle,
    textStyle = {},
    children,
    ...otherTextProps
  } = props;

  if (!config.enable) return null;

  const textProps: TextProps = {
    ...otherTextProps,
    style: mergeRight(getTextStyles(config), textStyle),
  };

  if (config.number_of_lines && !Number.isNaN(config.number_of_lines)) {
    textProps.numberOfLines = config.number_of_lines;
  }

  if (containerStyle) {
    return (
      <View style={containerStyle}>
        <Text {...textProps}>{children}</Text>
      </View>
    );
  }

  return <Text {...textProps}>{children}</Text>;
}
