import { useMemo } from 'react';
import type { FC } from 'react';
import { View, StyleSheet } from 'react-native';
import type { ViewStyle } from 'react-native';

import { Cell } from './cell';
import type { RowProps, RowsProps } from '../types';
import { sum } from '../util';

/** Row component - Renders a single row of cells*/
export const Row: FC<RowProps> = ({
  data,
  style,
  widthArr,
  height,
  flexArr,
  textStyle,
  borderStyle,
  onPress,
  cellTextStyle,
  ...props
}) => {
  // calc total width based on width array
  const totalWidth = widthArr ? sum(widthArr) : 0;

  // calc row styles based on props
  const rowStyle = useMemo((): ViewStyle => {
    const styles: ViewStyle = {};
    if (totalWidth) styles.width = totalWidth;
    if (height) styles.height = height;
    return styles;
  }, [totalWidth, height]);

  if (!data || !data.length) return null;

  return (
    <View style={[styles.row, rowStyle, style]}>
      {data.map((item, index) => {
        const cellFlex = flexArr?.[index];
        const cellWidth = widthArr?.[index];
        const customTextStyle = cellTextStyle
          ? cellTextStyle(item, index)
          : undefined;

        return (
          <Cell
            key={index}
            data={item}
            width={cellWidth}
            height={height}
            flex={cellFlex}
            borderStyle={borderStyle}
            textStyle={[customTextStyle, textStyle]}
            onPress={onPress}
            {...props}
          />
        );
      })}
    </View>
  );
};

/** Rows component - Renders multiple rows*/
export const Rows: FC<RowsProps> = ({
  data,
  style,
  widthArr,
  heightArr,
  flexArr,
  textStyle,
  borderStyle,
  ...props
}) => {
  // calc total flex and width
  const totalFlex = flexArr ? sum(flexArr) : 0;
  const totalWidth = widthArr ? sum(widthArr) : 0;

  // calc container styles
  const containerStyle = useMemo((): ViewStyle => {
    const styles: ViewStyle = {};
    if (totalFlex) styles.flex = totalFlex;
    if (totalWidth) styles.width = totalWidth;
    return styles;
  }, [totalFlex, totalWidth]);

  if (!data || !data.length) return null;

  return (
    <View style={containerStyle}>
      {data.map((rowData, index) => {
        const rowHeight = heightArr?.[index];

        return (
          <Row
            key={index}
            data={rowData}
            widthArr={widthArr}
            height={rowHeight}
            flexArr={flexArr}
            style={style}
            textStyle={textStyle}
            borderStyle={borderStyle}
            {...props}
          />
        );
      })}
    </View>
  );
};

const styles = StyleSheet.create({
  row: {
    flexDirection: 'row',
    overflow: 'hidden',
  },
});
