import React from 'react'
import PropTypes from 'prop-types'
import {
  Link,
  responsiveProps,
  selectSystemProps,
  useResponsiveProp,
  useThemeTokens,
  withLinkRouter,
  useViewport,
  Typography,
  getTokensPropType
} from '@telus-uds/components-base'
import styled from 'styled-components'
import OrderedListBase from '../OrderedList/OrderedListBase'
import ItemBase from '../OrderedList/ItemBase'
import Image from '../Image'
import { htmlAttrs } from '../utils'

const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])

const row = (rowSize, rowBorderWidth) => ({
  flexBasis: `calc(100% / ${rowSize})`,
  [`:not(:nth-of-type(${rowSize}n + 1))`]: {
    borderLeftWidth: `${rowBorderWidth}px`
  },
  [`:nth-of-type(n+${rowSize + 1})`]: {
    borderTopWidth: `${rowBorderWidth}px`
  }
})

const Container = styled(OrderedListBase)({
  display: 'flex',
  flexDirection: 'row',
  flexWrap: 'wrap',
  justifyContent: 'flex-start'
})

const Item = styled(ItemBase)(({ rowSize, itemPadding, itemBorderColor, rowBorderWidth }) => ({
  display: 'flex',
  flexDirection: 'row',
  alignItems: 'center',
  justifyContent: 'center',
  flexGrow: 1,
  flexShrink: 1,
  padding: `${itemPadding}px`,
  boxSizing: 'border-box',
  borderStyle: 'solid',
  borderColor: itemBorderColor,
  borderWidth: 0,
  '& > a': {
    alignSelf: 'center'
  },
  ...row(rowSize, rowBorderWidth)
}))

const Center = styled('div')({
  display: 'flex',
  flexDirection: 'column',
  alignItems: 'center',
  textAlign: 'center'
})

/**
 * The WaffleGrid is used to show items in a waffle like manner with borders surrounding the element
 */
const WaffleGrid = React.forwardRef(
  ({ items, rowSize = null, LinkRouter, tokens, variant, linkRouterProps, ...rest }, ref) => {
    const viewport = useViewport()
    const themeTokens = useThemeTokens('WaffleGrid', tokens, variant, { viewport })
    const currentRowSize = useResponsiveProp(rowSize)

    return (
      <Container ref={ref} {...selectProps(rest)}>
        {items.map((child) => (
          <Item
            {...themeTokens}
            key={child.href}
            rowSize={rowSize ? currentRowSize : themeTokens.rowSize}
          >
            <Link
              href={child.href}
              LinkRouter={child.LinkRouter || LinkRouter}
              linkRouterProps={{ ...linkRouterProps, ...child.linkRouterProps }}
            >
              <Center>
                {typeof child.image === 'string' ? (
                  // Assuming that string passed is the image URL
                  <Image src={child.image} alt={child.imageAltText} width={96} />
                ) : (
                  // Otherwise it must be an arbitrary content, which we just display by itself
                  child.image
                )}
                <Typography variant={{ weight: 'semibold' }}>{child.text}</Typography>
              </Center>
            </Link>
          </Item>
        ))}
      </Container>
    )
  }
)

WaffleGrid.displayName = 'WaffleGrid'

WaffleGrid.propTypes = {
  ...selectedSystemPropTypes,
  /**
   * The image and the link to display. `items` should be an array of objects with the following keys:
   */
  items: PropTypes.arrayOf(
    PropTypes.shape({
      /**
       * The src attribute for the HTML img element or custom JSX content to render instead
       */
      image: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
      /**
       * The alt attribute for the HTML img element (note that this is ignored if a custom
       * JSX content is used instead of an image URL)
       */
      imageAltText: PropTypes.string,
      /**
       * The text displayed under the image
       */
      text: PropTypes.string,

      /**
       * Target URL
       */
      href: PropTypes.string,
      ...withLinkRouter.propTypes
    })
  ).isRequired,
  /**
   * Sets the tokens for WaffleGrid element.
   */
  tokens: getTokensPropType('WaffleGrid'),
  /**
   * Row size, optionally depending on the viewport
   */
  rowSize: responsiveProps.getTypeOptionallyByViewport(PropTypes.number),
  ...withLinkRouter.propTypes
}

export default WaffleGrid
