import styled from '@emotion/native';
import type { Theme } from '@emotion/react';
import { View } from 'react-native';
import type { FlexStyleProps, StyleProps, ThemeScale } from './types';
import { pick } from '../../utils/helpers';
import type { ConfigType } from './config';
import config, { flexPropsKey } from './config';

const getThemeValue = (
  theme: Theme,
  key: keyof StyleProps,
  props: StyleProps
) => {
  const propConfig = config[key];
  const propValue = props[key];

  if (!propValue) return undefined;

  const { scale, property } = propConfig;

  switch (scale) {
    case 'colors':
      return { [property]: theme.colors[propValue as ThemeScale['colors']] };
    case 'space':
      return { [property]: theme.space[propValue as ThemeScale['space']] };
    case 'radii':
      return { [property]: theme.radii[propValue as ThemeScale['radii']] };
    case 'borderWidths':
      return {
        [property]: theme.borderWidths[propValue as ThemeScale['borderWidths']],
      };
  }
};

const mapStylePropToThemeValue = (theme: Theme, props: StyleProps) => {
  const entries = Object.keys(props) as Array<keyof StyleProps>;
  return entries.reduce(
    (result, key) => ({
      ...result,
      ...getThemeValue(theme, key, props),
    }),
    {}
  );
};

const configKeys = Object.keys(config) as Array<keyof ConfigType>;

const StyledBox = styled(View)<StyleProps & FlexStyleProps>(
  ({ theme, ...otherProps }) => {
    const styleProps = pick(configKeys, otherProps);
    const flexProps = pick([...flexPropsKey], otherProps);
    return { ...mapStylePropToThemeValue(theme, styleProps), ...flexProps };
  }
);

export { StyledBox };
