import type { Alignment } from '@blueprintjs/core'
import { Button } from '@blueprintjs/core'
import { css } from '@emotion/css'
import type { FC } from 'react'
import { useCallback, useEffect, useRef } from 'react'

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

const button = css`
  flex: unset;
`

const POLLING_INTERVAL = 20

const Reloader: FC<
  {
    minimal?: boolean
    fill?: boolean
    withLabel?: boolean
    alignText?: Alignment
    text?: string
  } & (
    | { queries?: never; onRefetch: () => void }
    | { queries: () => void | Array<() => void>; onRefetch?: never }
  )
> = ({ queries, minimal, fill, text, alignText, withLabel, onRefetch }) => {
  const timeLeft = useRef<number>(POLLING_INTERVAL)
  const timeLeftRef = useRef<HTMLSpanElement>(null)

  const handleRefetch = useCallback(() => {
    if (onRefetch) {
      onRefetch()
    } else {
      if (Array.isArray(queries)) {
        queries.forEach(callFn => callFn())
      } else {
        queries()
      }
    }
    // ensures that timer shows 20s :)
    timeLeft.current = POLLING_INTERVAL + 1
    if (timeLeftRef.current !== null) {
      timeLeftRef.current.innerText = `${POLLING_INTERVAL}s`
    }
  }, [onRefetch, queries])

  useEffect(() => {
    const interval = setInterval(() => {
      timeLeft.current =
        timeLeft.current > 0 ? timeLeft.current - 1 : timeLeft.current
      if (timeLeft.current <= 0) {
        handleRefetch()
      }
      if (timeLeftRef.current !== null)
        timeLeftRef.current.innerText = `${timeLeft.current}s`
    }, 1000)
    return () => {
      clearInterval(interval)
    }
  }, [handleRefetch, timeLeft])

  return (
    <Button
      alignText={alignText}
      className={button}
      rightIcon={withLabel ? undefined : 'refresh'}
      icon={withLabel ? 'refresh' : undefined}
      title='Reload'
      text={text}
      onClick={handleRefetch}
      minimal={minimal}
      fill={fill}
    >
      {!withLabel && (
        <span className={label} ref={timeLeftRef}>
          {POLLING_INTERVAL}s
        </span>
      )}
    </Button>
  )
}

export default Reloader
