import React, { useMemo } from "react";
import * as R from "ramda";
import {
  ImageStyle,
  StyleSheet,
  Text,
  TextProps,
  TextStyle,
  View,
  ViewStyle,
} from "react-native";
import { defaultAsset } from "./defaultAsset";
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
import { QBImage as Image } from "@applicaster/zapp-react-native-ui-components/Components/Image";
import { Button } from "./Button";

type ButtonProp = {
  text: string;
  onPress: () => void;
};

type Styles = {
  screen: ViewStyle;
  component: ViewStyle;
  asset: ImageStyle;
  title: TextStyle;
  message: TextStyle;
  button: ViewStyle;
  focusedButton: ViewStyle;
  buttonText: TextStyle;
  focusedText: TextStyle;
};

type Props = {
  styles?: Styles;
  asset?: string;
  assetEnabled?: boolean;
  title?: string;
  titleProps?: TextProps;
  message?: string;
  messageProps?: TextProps;
  buttons?: Array<ButtonProp>;
  dismissError?: () => void;
};

const baseStyles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
  },
  buttonContainer: {
    alignItems: "center",
  },
});

const defaultProps = {
  asset: defaultAsset,
  title: "Something went wrong",
  message: "The app has encountered an error.",
  styles: {
    screen: {
      backgroundColor: "black",
    },
    content: { maxWidth: 280 },
    asset: {
      width: 180,
      height: 180,
      marginHorizontal: 50,
      marginBottom: 30,
    },
    title: {
      height: 30,
      marginBottom: 10,
      fontFamily: platformSelect({
        ios: "SFProText-Bold",
        android: "Roboto-Black",
      }),
      fontSize: 24,
      lineHeight: 30,
      letterSpacing: -0.6,
      textAlign: "center",
      color: "rgba(255, 255, 255, 1)",
    },
    message: {
      paddingHorizontal: 5,
      marginBottom: 32,
      fontFamily: platformSelect({
        ios: "SFProText-Medium",
        android: "Roboto-Medium",
      }),
      fontSize: 15,
      lineHeight: 20,
      letterSpacing: -0.46,
      textAlign: "center",
      color: "rgba(255, 255, 255, 0.65)",
    },
    button: {
      height: 40,
      marginBottom: 16,
      backgroundColor: "#1e1e1e",
      borderRadius: 4,
      paddingHorizontal: 20,
      alignItems: "center",
      justifyContent: "center",
    },
    focusedButton: {
      backgroundColor: "#3a3a3a",
      borderColor: "#ffffff",
      borderWidth: 2,
    },
    buttonText: {
      fontFamily: platformSelect({
        ios: "SFProText-Medium",
        android: "Roboto-Medium",
      }),
      fontSize: 13,
      lineHeight: 20,
      letterSpacing: 0.2,
      color: "rgba(255, 255, 255, 1)",
      textTransform: "uppercase",
    },
    focusedText: {
      color: "#ffffff",
    },
  },
};

export function ErrorScreen(props: Props) {
  const navigator: QuickBrickAppNavigator = useNavigation();

  const defaultButtons = useMemo(
    () => [
      {
        text: "Go home",
        onPress: () => {
          navigator.goHome();
          props.dismissError?.();
        },
      },
    ],
    []
  );

  const {
    asset = defaultProps.asset,
    assetEnabled = true,
    title = defaultProps.title,
    message = defaultProps.message,
    buttons = defaultButtons,
    titleProps = {},
    messageProps = {},
  } = props;

  const styles = R.mergeRight(defaultProps.styles, props?.styles || {});

  return (
    <View style={[baseStyles.container, styles.screen]}>
      <View style={[baseStyles.container, styles.component]}>
        {assetEnabled ? (
          <Image
            fadeDuration={0}
            source={{ uri: asset }}
            style={styles.asset}
          />
        ) : null}
        <Text style={styles.title} {...titleProps}>
          {title}
        </Text>
        <Text style={styles.message} {...messageProps}>
          {message}
        </Text>
        {buttons.map((button, key) => (
          <View style={baseStyles.buttonContainer} key={key}>
            <Button styles={styles} {...button} />
          </View>
        ))}
      </View>
    </View>
  );
}
