import type { ButtonStyle } from '../models/CardEmbedMetadata';
import { FC, ReactNode } from 'react';
import {
  Image,
  ImageStyle,
  Pressable,
  StyleProp,
  StyleSheet,
  Text,
  TextStyle,
  View,
  ViewStyle,
} from 'react-native';
import { SkeletonCard } from './Skeleton';
import { ErrorDisplay } from './ErrorDisplay';

export type CardCoverProps = {
  /**
   * The callback for when the cover is clicked.
   */
  onClick: () => void;

  /**
   * Whether the cover is loading.
   */
  isLoading: boolean;

  /**
   * Whether the cover is in an error state.
   */
  isError?: boolean;

  /**
   * Override the default skeleton loader.
   */
  loader?: ReactNode;

  /**
   * Override the default error display.
   */
  errorDisplay?: ReactNode;

  /**
   * The button style returned from the embed metadata endpoint.
   */
  metaButtonStyle?: ButtonStyle;

  /**
   * Override the button style.
   */
  overrideButtonStyle?: StyleProp<ViewStyle>;

  /**
   * Override the button text style.
   */
  overrideButtonTextStyle?: StyleProp<TextStyle>;

  /**
   * Override the container style.
   */
  containerStyle?: StyleProp<ViewStyle>;

  /**
   * Override the cover image style.
   */
  coverImageStyle?: StyleProp<ImageStyle>;

  /**
   * Whether to hide the cover button.
   */
  hideCoverButton?: boolean;

  /**
   * The url of the cover image.
   * This can be obtained by querying the embed metadata endpoint.
   */
  imageUrl?: string;

  /**
   * The aspect ratio of the cover image.
   * This can be obtained by querying the embed metadata endpoint.
   */
  imageAspectRatio?: number;
};

export const CardCover: FC<CardCoverProps> = ({
  imageUrl,
  imageAspectRatio = 3 / 2,
  onClick,
  isLoading,
  loader,
  isError,
  errorDisplay,
  metaButtonStyle = {},
  overrideButtonStyle = {},
  overrideButtonTextStyle = {},
  containerStyle = {},
  coverImageStyle = {},
  hideCoverButton = false,
}) => {
  const showButton =
    !hideCoverButton && !!metaButtonStyle.text && !isLoading && !isError;

  const isLoadingOrError = isLoading || isError;

  const computedContainerStyle: StyleProp<ViewStyle> = isLoadingOrError
    ? [styles.container, styles.containerConstantSize, containerStyle]
    : [styles.container, containerStyle];

  return (
    <Pressable onPress={onClick} style={computedContainerStyle}>
      {isLoading && (!loader ? <SkeletonCard /> : loader)}
      {!isLoading &&
        isError &&
        (!errorDisplay ? (
          <View style={styles.errorContainer}>
            <ErrorDisplay />
          </View>
        ) : (
          errorDisplay
        ))}

      {!isLoading && !isError && (
        <Image
          style={[
            styles.coverImage,
            { aspectRatio: imageAspectRatio },
            coverImageStyle,
          ]}
          source={{
            uri: imageUrl,
          }}
        />
      )}

      {showButton && (
        <View
          style={[
            styles.button,
            {
              backgroundColor: metaButtonStyle.backgroundColor,
            },
            overrideButtonStyle,
          ]}
        >
          <Text
            style={[
              styles.buttonText,
              { color: metaButtonStyle.color },
              overrideButtonTextStyle,
            ]}
          >
            {metaButtonStyle.text}
          </Text>
        </View>
      )}
    </Pressable>
  );
};

const styles = StyleSheet.create({
  buttonText: {
    color: 'white',
    fontWeight: 'bold',
    textAlign: 'left',
  },
  button: {
    backgroundColor: 'black',
    height: 42,
    justifyContent: 'center',
    padding: 10,
  },
  container: { flexDirection: 'column', width: '100%', maxWidth: '100%' },
  containerConstantSize: { maxWidth: 337, maxHeight: 225 },
  coverImage: { resizeMode: 'cover' },
  errorContainer: {
    height: 225,
    width: '100%',
    backgroundColor: '#f8f8f8',
    minHeight: 200,
  },
});
