import React from 'react'
import '../tailwind.css'

import { classNames } from '../utils/css'
export interface ButtonProps {
  // The content to display inside the button
  children?: string | React.ReactNode
  // Identifies the primary action in a set of buttons
  primary?: boolean
  // Indicates a dangerous or potentially negative action
  negative?: boolean
  // Indicates a positive action
  positive?: boolean
  // Gives the button a subtle alternative to the default button style
  outline?: boolean
  // Allows the button to grow to the width of its container
  fullWidth?: boolean
  // Renders the button to look like a link
  plain?: boolean
  // Allows the button to submit a form
  submit?: boolean
  // Display larger button
  large?: boolean
  // A destination to link to, rendered in the href attribute of a link
  url?: string
  // Forces url to open in a new tab
  external?: boolean
  // Disables the button, disallowing interaction
  disabled?: boolean
  // Replaces button text with a spinner while a background action is being performed
  loading?: boolean
  // Callback when clicked
  onClick?(): void
}

const styles = {
  baseButton:
    'flex justify-center items-center font-medium cursor-pointer transition-colors duration-200 rounded-lg',
  primary: 'bg-primary text-on-primary-text hover:bg-primary-hover',
  outline:
    'text-primary hover:text-on-primary-text hover:bg-primary border border-primary hover:border-primary',
  negative: 'bg-negative text-on-primary-text hover:bg-negative-hover',
  positive: 'bg-positive text-on-primary-text hover:bg-positive-hover',
  isDisabled: 'opacity-50 cursor-not-allowed',
  plain: 'text-primary hover:underline py-0 px-0',
  fullWidth: 'w-full',
  fitContent: 'w-fit',
  loading: 'opacity-500 cursor-default',
  shadow: '',
  smallPadding: 'py-2 px-3',
  largePadding: 'py-3 px-4',
  smallFont: 'text-sm',
  largeFont: 'text-base'
}

const loadingMarkup = (
  <svg
    className="h-5 w-5 animate-spin"
    xmlns="http://www.w3.org/2000/svg"
    fill="none"
    viewBox="0 0 24 24"
  >
    <circle
      className="opacity-25"
      cx="12"
      cy="12"
      r="10"
      stroke="currentColor"
      strokeWidth="4"
    ></circle>
    <path
      className="opacity-75"
      fill="currentColor"
      d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
    ></path>
  </svg>
)

export const Button = ({
  children,
  primary,
  negative,
  positive,
  disabled,
  loading,
  outline,
  fullWidth,
  plain,
  url,
  external,
  submit,
  onClick,
  large,
  ...any
}: ButtonProps) => {
  const isDisabled = disabled || loading
  const target = external ? '_blank' : undefined
  const rel = external ? 'noopener noreferrer' : undefined

  const className = classNames(
    styles.baseButton,
    !outline && !negative && !plain && !positive && styles.primary,
    primary && styles.primary,
    outline && styles.outline,
    negative && styles.negative,
    positive && styles.positive,
    disabled && styles.isDisabled,
    fullWidth && styles.fullWidth,
    !fullWidth && styles.fitContent,
    loading && styles.loading,
    plain && styles.plain,
    !plain && styles.shadow,
    !plain && styles.smallPadding,
    large && styles.largePadding,
    !large && styles.smallFont,
    large && styles.largeFont
  )

  const buttonMarkup = (
    <button
      className={className}
      disabled={isDisabled}
      onClick={onClick}
      type={submit ? 'submit' : 'button'}
      {...any}
    >
      {loading ? loadingMarkup : children}
    </button>
  )

  const linkMarkup = (
    <a
      className={className}
      target={target}
      href={!disabled ? url : undefined}
      rel={rel}
      onClick={onClick}
      {...any}
    >
      {loading ? loadingMarkup : children}
    </a>
  )

  return <>{url ? linkMarkup : buttonMarkup}</>
}
