import React, { ReactNode } from "react";
import {
  ScrollView,
  ScrollViewProps,
  View,
  StyleProp,
  ViewStyle,
  StyleSheet
} from "react-native";

export interface RNMasonryScrollViewProps extends ScrollViewProps {
  children: ReactNode[];
  columns?: number;
  columnStyle?: StyleProp<ViewStyle>;
  oddColumnStyle?: StyleProp<ViewStyle>;
  evenColumnStyle?: StyleProp<ViewStyle>;
}

export function generateMasonryGrid<T>(data: T[], columns: number): T[][] {
  return data.reduce((collection: T[][], child: T, childIndex: number) => {
    const itemIndex = childIndex % columns;
    if (collection[itemIndex]) {
      collection[itemIndex].push(child);
    } else {
      collection[itemIndex] = [];
      collection[itemIndex].push(child);
    }
    return collection;
  }, []);
}

const RNMasonryScrollView = ({
  children = [],
  columns = 2,
  columnStyle = null,
  oddColumnStyle = null,
  evenColumnStyle = null,
  horizontal,
  ...otherProps
}: RNMasonryScrollViewProps) => {
  const masonryGrid = generateMasonryGrid(children, columns);

  return (
    <ScrollView
      contentContainerStyle={
        horizontal ? styles.horizontalColumnStyle : styles.verticalColumnStyle
      }
      horizontal={horizontal}
      {...otherProps}
    >
      {masonryGrid.map((column, columnIndex) => {
        return (
          <View
            key={columnIndex}
            style={[
              !horizontal
                ? styles.horizontalColumnStyle
                : styles.verticalColumnStyle,
              columnStyle,
              columnIndex % 2 === 0 ? evenColumnStyle : oddColumnStyle
            ]}
          >
            {column.map(item => item)}
          </View>
        );
      })}
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  verticalColumnStyle: { flexDirection: "row" },
  horizontalColumnStyle: { flexDirection: "column" }
});

export default RNMasonryScrollView;