import { Colors, Tag } from '@blueprintjs/core'
import { css, cx } from '@emotion/css'
import type { CSSProperties, FC } from 'react'
import { useEffect, useState } from 'react'

export const tag = css`
  /* prevent stretching */
  align-self: center;
`

const read = css`
  background-color: ${Colors.GREEN3}4d !important;
`
const notRead = css`
  background-color: ${Colors.ORANGE3}4d !important;
`
const achieved = css`
  background-color: ${Colors.GREEN3} !important;
`
const notAchieved = css`
  background-color: ${Colors.RED3} !important;
`

const RERENDER_INTERVAL_SECONDS = 10

const timedFormatter = (datetime: Date, minimal: boolean) => {
  const secs = (Date.now() - datetime.getTime()) / 1000
  if (secs < 10) {
    return 'Just now'
  }
  if (secs < 60) {
    return minimal ? '<1m ago' : 'Less than a minute ago'
  }
  const hours = Math.floor(secs / 3600)
  const minutes = Math.floor(secs / 60) % 60
  const hourString = minimal
    ? `${hours}h`
    : `${hours} ${hours > 1 ? 'hours' : 'hour'}`
  const minuteString = minimal
    ? `${minutes}m`
    : `${minutes % 60} ${minutes % 60 > 1 ? 'minutes' : 'minute'}`

  return `${hours > 0 ? hourString : ''} ${minutes > 0 ? minuteString : ''} ago`
}

type TimestampProps = {
  minimal?: boolean
  style?: CSSProperties
  className?: string
} & (
  | {
      isRead?: boolean
      isAchieved?: never
    }
  | {
      isRead?: never
      isAchieved?: boolean
    }
) &
  (
    | {
        datetime: Date
        alternativeContent?: never
      }
    | {
        datetime?: never
        alternativeContent: string
      }
  )

const Timestamp: FC<TimestampProps> = ({
  datetime,
  alternativeContent,
  minimal = false,
  style,
  className,
  isRead,
  isAchieved,
}) => {
  const [time, setTime] = useState<string>(alternativeContent || '')

  useEffect(() => {
    if (datetime === undefined) return

    setTime(timedFormatter(datetime, minimal))
    const interval = setInterval(() => {
      setTime(timedFormatter(datetime, minimal))
    }, RERENDER_INTERVAL_SECONDS * 1000)
    return () => {
      clearInterval(interval)
    }
  }, [datetime, minimal])

  return (
    <Tag
      minimal
      round
      style={style}
      className={cx({
        [tag]: true,
        [className || '']: className !== undefined,
        [isRead ? read : notRead]: isRead !== undefined,
        [isAchieved ? achieved : notAchieved]: isAchieved !== undefined,
      })}
    >
      {time || datetime?.toLocaleTimeString() || alternativeContent}
    </Tag>
  )
}

export default Timestamp
