import { FunctionComponent } from 'react'
import AdminPage from './AdminPage'
import Link from 'next/link'
import theme from '../../styles/theme'
import { QueryResult, MutationTuple, QueryHookOptions, MutationHookOptions } from '@apollo/client'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faEdit, faTrash, faPlusCircle } from '@fortawesome/free-solid-svg-icons'

interface IAdminList<TQueryData, TQueryVariables, TDeleteData, TDeleteVariables> {
  name: string
  adminMenu?: string
  dataKey: keyof TQueryData
  get: (
    baseOptions?: QueryHookOptions<TQueryData, TQueryVariables>
  ) => QueryResult<TQueryData, TQueryVariables>
  remove?: (
    baseOptions?: MutationHookOptions<TDeleteData, TDeleteVariables>
  ) => MutationTuple<TDeleteData, TDeleteVariables>
  Component: FunctionComponent<any>
}

const AdminList = <
  TQueryData extends { [dataKey: string]: any[] },
  TQueryVariables,
  TDeleteData,
  TDeleteVariables
>({
  name,
  adminMenu,
  dataKey,
  get,
  remove,
  Component,
}: IAdminList<TQueryData, TQueryVariables, TDeleteData, TDeleteVariables>) => {
  const [removeFunction, removeResult] = remove ? remove() : [undefined, undefined]
  const { data, error, loading, refetch } = get({ fetchPolicy: 'network-only' })

  let content
  if (loading) content = <p>Loading data...</p>
  else if (error) content = <p>Error loading data.</p>
  else if (!data) content = <p>No data found.</p>
  else
    content = (
      <ul>
        {data[dataKey].map((item: any) => (
          <li key={item.id}>
            <Component key={item.id} item={item} className='admin-component' />

            <div className='admin-toolbar'>
              <Link href={`/${adminMenu}/[id]`} as={`${adminMenu}/${item.id}`}>
                <a title='edit'>
                  <button type='button'>
                    <FontAwesomeIcon icon={faEdit} height={16} />
                  </button>
                </a>
              </Link>
              {removeFunction && (
                <button
                  onClick={async (event) => {
                    const deletedItem = await removeFunction({ variables: { id: item.id } } as any)
                    if (deletedItem) refetch()
                  }}
                  disabled={removeResult?.loading}
                  title='delete'
                >
                  <FontAwesomeIcon icon={faTrash} height={16} />
                </button>
              )}
            </div>
          </li>
        ))}
        <style jsx>{`
          ul {
            padding: 0;
          }
          ul :global(li) {
            padding: 0.2em 0.5em;
            display: flex;
            list-style: none;
            align-items: center;
            background-color: #0770;
            transition: background-color 250ms ease-in-out;
            border-top: 1px solid #0002;
            position: relative;
          }
          ul :global(li:last-child) {
            border-bottom: 1px solid #0002;
          }
          ul :global(li:hover) {
            background-color: ${theme.colors.formHighlightBackground}22;
          }
          ul :global(.admin-component) {
            flex-grow: 1;
          }
          ul :global(.admin-toolbar button) {
            padding: 0.4em;
            margin: 0;
            color: ${theme.colors.buttonBackground};
            background-color: transparent;
          }

          ul :global(a) {
            color: ${theme.colors.highlight};
            text-decoration: none;
          }
          ul :global(button > a) {
            color: ${theme.colors.button};
            text-decoration: none;
          }
          ul :global(li .admin-toolbar) {
            display: none;
            position: absolute;
            top: 0;
            right: 0;
            width: 80px;
            background-color: ${theme.colors.background};
            box-shadow: ${theme.bsSmall};
          }
          ul :global(li:hover .admin-toolbar) {
            display: flex;
          }
        `}</style>
      </ul>
    )

  return (
    <AdminPage>
      <h2>{name}</h2>
      <Link href={`${adminMenu}/create`}>
        <a>
          <button>
            <FontAwesomeIcon icon={faPlusCircle} height={36} />
          </button>
        </a>
      </Link>
      {content}
      <style jsx>{`
        button {
          color: ${theme.colors.buttonBackground};
          background-color: transparent;
          display: inline;
          margin: 0.4rem;
          padding: 0;
        }
      `}</style>
    </AdminPage>
  )
}

export default AdminList
