import type { RefetchQueriesInclude } from '@apollo/client'
import { Button } from '@blueprintjs/core'
import { css } from '@emotion/css'
import useApolloClient from '@inject/graphql/client/useApolloClient'
import { useCountDown } from 'ahooks'
import type { FC } from 'react'
import { useCallback, useState } from 'react'

const label = css`
  min-width: 3ch;
  display: inline-block;
  text-align: center;
`

const button = css`
  flex: unset;
`

const POLLING_INTERVAL = 20000

type ReloaderProps = {
  minimal?: boolean
  fill?: boolean
  withLabel?: boolean
} & (
  | { queries?: never; onRefetch: () => void }
  | { queries: RefetchQueriesInclude; onRefetch?: never }
)

const Reloader: FC<ReloaderProps> = ({
  queries,
  minimal,
  fill,
  withLabel,
  onRefetch,
}) => {
  const [targetDate, setTargetDate] = useState(Date.now() + POLLING_INTERVAL)

  const client = useApolloClient()
  const handleRefetch = useCallback(() => {
    setTargetDate(Date.now() + POLLING_INTERVAL)
    if (onRefetch) {
      onRefetch()
    } else {
      client.refetchQueries({ include: queries })
    }
  }, [client, onRefetch, queries])

  const [, { seconds }] = useCountDown({
    targetDate,
    onEnd: handleRefetch,
  })

  return (
    <Button
      className={button}
      rightIcon={withLabel ? undefined : 'refresh'}
      icon={withLabel ? 'refresh' : undefined}
      title='Reload'
      onClick={handleRefetch}
      minimal={minimal}
      fill={fill}
      text={withLabel ? `Reload (${seconds + 1}s)` : undefined}
    >
      {!withLabel && <span className={label}>{`${seconds + 1}s`}</span>}
    </Button>
  )
}

export default Reloader
