import type { PropsWithChildren } from 'react'
import Link from 'next/link'
import cx from 'classnames'

import type { PropsWithClassName } from '@/lib/types'

export type Props = PropsWithChildren &
  PropsWithClassName & {
    as?: keyof HTMLElementTagNameMap
    href?: string
    onClick?(): void
    external?: boolean
    inverted?: boolean
    disableHover?: boolean
  }

const Shutters = ({ inverted }: { inverted: boolean }) => {
  return (
    <span className="block absolute inset-0 rounded-100 overflow-hidden z-0">
      <span
        className={cx(
          'block absolute top-0 bottom-1/2 w-full translate-y-0 group-hover:-translate-y-full transition-all duration-300 transform-gpu',
          inverted ? 'bg-black' : 'bg-white'
        )}
      />
      <span
        className={cx(
          'block absolute top-1/2 bottom-0 w-full translate-y-0 group-hover:translate-y-full transition-all duration-300 transform-gpu',
          inverted ? 'bg-black' : 'bg-white'
        )}
      />
    </span>
  )
}

export default function CircleButton({
  as: Component = 'button',
  href,
  onClick,
  external,
  inverted = false,
  disableHover = false,
  className,
  children,
}: Props) {
  const classNames = cx(
    'group flex justify-center items-center relative overflow-hidden text-view-button w-14 h-14 xs:w-20 xs:h-20 md:w-24 md:h-24 lg:w-28 lg:h-28 rounded-100 transition-color duration-300',
    // TODO: ick, need to clean this up
    disableHover
      ? inverted
        ? 'text-white bg-black'
        : 'text-black bg-white'
      : inverted
      ? 'text-white hover:text-black bg-black hover:bg-white'
      : 'text-black hover:text-white bg-white hover:bg-black',
    className
  )

  const contents = disableHover ? (
    children
  ) : (
    <>
      <span className="z-10">{children}</span>
      <Shutters inverted={inverted} />
    </>
  )

  if (href) {
    const LinkComponent = external ? 'a' : Link
    return (
      <LinkComponent href={href} className={classNames}>
        {contents}
      </LinkComponent>
    )
  }

  return (
    <Component onClick={onClick} className={classNames}>
      {contents}
    </Component>
  )
}
