import { Colors } from '@blueprintjs/colors'
import { Cross } from '@blueprintjs/icons'
import { css, cx } from '@emotion/css'
import type { Definition } from '@inject/graphql/fragment-types'
import { useTypedQuery } from '@inject/graphql/graphql'
import { GetDefinitions } from '@inject/graphql/queries'
import { timedFormatter } from '@inject/shared/components/StyledTag/Timestamp'
import notEmpty from '@inject/shared/utils/notEmpty'
import type { FC } from 'react'
import { useMemo } from 'react'
import Table from '../Table'
import type { Column, Row } from '../Table/typing'
import DefinitionButtons from './DefinitionButtons'

const verticallyCentered = css`
  vertical-align: middle;
`

const hideOnSmallScreen = css`
  @media (max-width: 60rem) {
    display: none;
  }
`

type DefinitionListProps = {
  className?: string
}

const DefinitionList: FC<DefinitionListProps> = ({ className }) => {
  const [{ data, fetching: loading }] = useTypedQuery({
    query: GetDefinitions,
  })

  const definitions = useMemo(
    () => data?.definitions?.filter(notEmpty) || [],
    [data?.definitions]
  )

  const columns: Column<Definition>[] = useMemo(() => {
    const columns: Column<Definition>[] = [
      {
        id: 'name',
        name: 'Name',
        style: { textAlign: 'left' },
        renderValue: definition => definition.name,
        className: verticallyCentered,
      },
      {
        id: 'version',
        name: 'Version',
        style: { textAlign: 'right', width: '10ch' },
        renderValue: definition => definition.version,
        className: verticallyCentered,
      },
      {
        id: 'roles',
        name: 'Roles',
        style: { textAlign: 'right', width: '10ch' },
        renderValue: definition =>
          definition.roles.length || <Cross color={Colors.RED3} />,
        className: cx(verticallyCentered, hideOnSmallScreen),
      },
      {
        id: 'uploaded-at',
        name: 'Uploaded',
        style: { textAlign: 'right', width: '12ch' },
        renderValue: definition =>
          timedFormatter({
            datetime: new Date(definition.timestampCreated),
            minimal: true,
          }),
        className: verticallyCentered,
      },
      {
        id: 'actions',
        name: 'Actions',
        style: { textAlign: 'right', width: '12ch' },
        renderValue: definition => (
          <span>
            <DefinitionButtons definition={definition} />
          </span>
        ),
        className: verticallyCentered,
      },
    ]

    return columns
  }, [])

  const rows: Row<Definition>[] = useMemo(() => {
    const rows: Row<Definition>[] = definitions.map(definition => ({
      id: definition.id,
      value: definition,
    }))

    return rows
  }, [definitions])

  return (
    <Table<Definition>
      columns={columns}
      className={className}
      rows={rows}
      loading={loading}
      noDataStateProps={{
        title: 'No definitions',
        description: 'There are no definitions to display',
      }}
    />
  )
}

export default DefinitionList
