import Item from "./Item"

import styles from "./grid.module.css"

import type { GridProps, Order, RowSpan } from "./grid"

export default function Grid({ children, items, tag = "section" }: GridProps) {
  const Elm = tag

  const allRows: number[] = items.columns.map((col) => col.rows.length)
  const onlySingleRows = allRows.every((row) => row === 1)
  const oneColumnWithTwoRows = allRows.includes(2)
  const oneColumnWithThreeRows = allRows.includes(3)
  /**
   * When we have one column with 2 rows and another with 3,
   * we have to reach the closest denominator which is 6 to be
   * able to have the column with 2 rows span half the grid each.
   */
  const doubleTheRows = oneColumnWithTwoRows && oneColumnWithThreeRows
  return (
    <Elm className={styles.grid}>
      {items.columns.map((column, columnIndex) => {
        const rows = column.rows.map((row) => row.rowConnection.edges).flat()
        let rowSpan: RowSpan = 1
        if (!onlySingleRows) {
          if (doubleTheRows) {
            switch (rows.length) {
              case 1:
                rowSpan = 6
                break
              case 2:
                rowSpan = 3
                break
              case 3:
                rowSpan = 2
                break
            }
          } else if (oneColumnWithTwoRows) {
            if (rows.length === 1) {
              rowSpan = 2
            }
          } else if (oneColumnWithThreeRows) {
            if (rows.length === 1) {
              rowSpan = 3
            }
          }
        }
        return rows.map(({ node: row }, rowIndex) => {
          const order = (columnIndex +
            1 +
            rowIndex * items.columns.length) as Order
          return (
            <Item
              key={order}
              columns={column.span}
              order={order}
              rows={rowSpan}
            >
              {children(row)}
            </Item>
          )
        })
      })}
    </Elm>
  )
}
