import React, { Children } from 'react'
import '../tailwind.css'
import { classNames } from '../utils/css'
import { Item } from './components/Item'

export interface StackProps {
  /* Controls how the items are positioned along the container's cross axis */
  items?: 'start' | 'end' | 'center' | 'baseline' | 'stretch'
  /* Controls how the items are positioned along the container's main axis */
  justify?: 'start' | 'end' | 'center' | 'between' | 'around' | 'evenly'
  /*  Controls the direction of the items */
  direction?: 'row' | 'row-reverse' | 'col' | 'col-reverse'
  /*  Controls the space between  items */
  spacing?:
  | 'extraTight'
  | 'tight'
  | 'baseTight'
  | 'loose'
  | 'extraLoose'
  | 'none'
  /*  Controls if the items will wrap */
  noWrap?: boolean
  /* Allows the stack to grow to the width of its container */
  fullWidth?: boolean
  /** Stack the elements vertically */
  vertical?: boolean
  /* Inner content of the stack */
  children: React.ReactNode
}

const styles = {
  base: 'flex',
  wrap: 'flex-wrap',
  noWrap: 'flex-nowrap',
  fullWidth: 'w-full',
  defaultSpacing: 'mt-3',
  extraTightSpacing: 'mt-1',
  tightSpacing: 'mt-2',
  baseTightSpacing: 'mt-4',
  looseSpacing: 'mt-5',
  extraLooseSpacing: 'mt-6',
  noneSpacing: 'mt-0 ml-0',
  defaultLeftSpacing: 'ml-3',
  extraTightLeftSpacing: 'ml-1',
  tightLeftSpacing: 'ml-2',
  baseTightLeftSpacing: 'ml-4',
  looseLeftSpacing: 'ml-5',
  extraLooseLeftSpacing: 'ml-6'
}

const spacingStyles = (
  spacing: StackProps['spacing'],
  fullWidth: StackProps['fullWidth'],
  vertical: StackProps['vertical']
) => {
  return classNames(
    ...[
      fullWidth && styles.fullWidth,
      !spacing && styles.defaultSpacing,
      spacing === 'extraTight' && styles.extraTightSpacing,
      spacing === 'tight' && styles.tightSpacing,
      spacing === 'baseTight' && styles.baseTightSpacing,
      spacing === 'loose' && styles.looseSpacing,
      spacing === 'extraLoose' && styles.extraLooseSpacing,
      spacing === 'none' && styles.noneSpacing,
      // Left spacing
      spacing === 'extraTight' && !vertical && styles.extraTightLeftSpacing,
      spacing === 'tight' && !vertical && styles.tightLeftSpacing,
      spacing === 'baseTight' && !vertical && styles.baseTightLeftSpacing,
      spacing === 'loose' && !vertical && styles.looseLeftSpacing,
      spacing === 'extraLoose' && !vertical && styles.extraLooseLeftSpacing
    ]
  )
}

export const Stack = ({
  children,
  items,
  justify,
  direction,
  noWrap,
  spacing,
  fullWidth,
  vertical
}: StackProps) => {
  const spacingClassName = spacingStyles(spacing, fullWidth, vertical)
  const className = classNames(
    styles.base,
    !noWrap && styles.wrap,
    noWrap && styles.noWrap,
    fullWidth && styles.fullWidth,
    items && `items-${items}`,
    justify && `justify-${justify}`,
    direction && `flex-${direction}`
  )

  const AllChildren = Children.map(children, (child) => (
    <div className={spacingClassName}>{child}</div>
  ))

  return <div className={className}>{AllChildren}</div>
}

Stack.Item = Item
