import type { FC } from 'react'
import { useLayoutEffect, useState } from 'react'
import type { StyledTagProps } from '../StyledTag'
import StyledTag from '../StyledTag'

const RERENDER_INTERVAL_SECONDS = 10

export const timedFormatter = ({
  datetime,
  minimal,
}: {
  datetime: Date
  minimal?: boolean
}) => {
  const seconds = Math.floor(Math.abs(Date.now() - datetime.getTime()) / 1000)
  const suffix = Date.now() > datetime.getTime() ? ' ago' : ''
  if (seconds < 10) {
    return minimal
      ? `<10s${suffix}`
      : `${seconds} ${seconds > 1 ? 'seconds' : 'second'}${suffix}`
  }
  if (seconds < 60) {
    return minimal ? `<1m${suffix}` : `less than a minute${suffix}`
  }
  const minutes = Math.floor(seconds / 60)
  if (minutes < 60) {
    return minimal
      ? `${minutes}m${suffix}`
      : `${minutes} ${minutes > 1 ? 'minutes' : 'minute'}${suffix}`
  }
  const hours = Math.floor(minutes / 60)
  if (hours < 24) {
    return minimal
      ? `${hours}h${suffix}`
      : `${hours} ${hours > 1 ? 'hours' : 'hour'}${suffix}`
  }
  const days = Math.floor(hours / 24)
  if (days < 30) {
    return minimal
      ? `${days}d${suffix}`
      : `${days} ${days > 1 ? 'days' : 'day'}${suffix}`
  }
  const months = Math.floor(days / 30)
  if (months < 12) {
    return minimal
      ? `${months}mo${suffix}`
      : `${months} ${months > 1 ? 'months' : 'month'}${suffix}`
  }
  const years = Math.floor(months / 12)
  return minimal
    ? `${years}y${suffix}`
    : `${years} ${years > 1 ? 'years' : 'year'}${suffix}`
}

export const timedFormatterSecondsLeft = (secondsLeft: number) => {
  const datetime = new Date(Date.now() + secondsLeft * 1000)
  return timedFormatter({ datetime, minimal: false })
}

type TimestampProps = StyledTagProps & {
  datetime: Date
  minimal?: boolean
}

const Timestamp: FC<TimestampProps> = ({ datetime, minimal, ...props }) => {
  const [time, setTime] = useState<string>('')
  useLayoutEffect(() => {
    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 <StyledTag content={time} {...props} />
}

export default Timestamp
