import * as React from "react";
import { ImageStyle } from "react-native";
import { toFiniteNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";

type Source = {
  uri: string;
};

type Props = Record<string, any> & {
  style: ImageStyle;
  uri?: string;
  placeholderImage?: string;
  entry?: ZappEntry | ZappFeed;
  withDimensions: (source: Source) => Source;
};

const normalize = Math.ceil;

const isValidSize = (size: unknown): boolean =>
  toFiniteNumberWithDefault(0, size) > 0;

type WidthDimensions = { aspectRatio?: number; width: number; height?: number };
type HeightDimensions = {
  aspectRatio?: number;
  width?: number;
  height: number;
};
type FullDimensions = { aspectRatio?: number; width: number; height: number };
type Dimensions = WidthDimensions | HeightDimensions | FullDimensions;

const calculateDimensions = ({ aspectRatio, width, height }: Dimensions) => {
  if (aspectRatio) {
    return {
      width: width || height * aspectRatio,
      height: height || width / aspectRatio,
    };
  }

  return { width, height };
};

const getSourceWithMaxSizes = (applyMaxSize, style, source) => {
  const { width, height } = calculateDimensions(style);

  if (!applyMaxSize || !isValidSize(width) || !isValidSize(height)) {
    return source;
  }

  return {
    ...source,
    maxWidth: normalize(width),
    maxHeight: normalize(height),
  };
};

export default function useImageSize(props: Props) {
  const { style, applyMaxSize, source, withDimensions } = props;

  const sourceWithMaxSizes = React.useMemo(
    () => withDimensions(getSourceWithMaxSizes(applyMaxSize, style, source)),
    [applyMaxSize, style?.height, style?.width, source?.uri, withDimensions]
  );

  return sourceWithMaxSizes;
}
