import React, { useState, memo } from 'react'
import classnames from 'classnames'
import { Product } from '@dollarshaveclub/types'
import { PriceAddButton } from '../Buttons/PriceAddButton'
import { Tray } from '../Tray'
import { TileOverlay } from '../ProductTileOverlay'
import Imgix from 'react-imgix'

type Props = Readonly<{
  product: Product
  priceData?: PriceData
  onClickAdd?: (product: Product) => void
  handleShouldUpdateToRestock?: (
    product: Product,
    shouldRestock: boolean
  ) => Promise<boolean>
  onClickRemove?: (sku: string) => void
  onImgClick?: (product: Product) => void
  recommended?: string
  showAddAnimation?: boolean
  isAdded?: boolean
  isLoading?: boolean
  isSoldOut?: boolean
  isShowingOverlay?: boolean
  isLoadingOverlay?: boolean
  isAutoRestock?: boolean
  showSize?: boolean
  showPriceComparison?: boolean
  showBaseNameOnly: boolean
  dataTestId?: string
  childrenMiddle?: JSX.Element
  childrenBottom?: JSX.Element
  additionalButtonClasses?: string
  disabled?: boolean
}>

type PriceData = {
  formattedRetailPrice: string
  formattedPrice: string
}

const noop = () => {}

const ProductTileBase: React.FunctionComponent<Props> = ({
  product,
  priceData,
  onClickAdd,
  handleShouldUpdateToRestock,
  onClickRemove,
  onImgClick,
  recommended,
  showAddAnimation = false,
  isAdded = false,
  isLoading = false,
  isSoldOut = false,
  isShowingOverlay = false,
  isLoadingOverlay = false,
  isAutoRestock = false,
  showSize,
  showPriceComparison = false,
  showBaseNameOnly = false,
  dataTestId,
  childrenMiddle,
  childrenBottom,
  additionalButtonClasses,
  disabled = false,
}) => {
  const productImage = product.assets.productTile.file.url
  const price = priceData?.formattedPrice
  const retailPrice = priceData?.formattedRetailPrice
  const buttonClasses = classnames('ui-price-btn--mb', additionalButtonClasses)
  const { newBadge } = product
  const [shouldRefocusButton, setShouldRefocusButton] = useState(false)

  const renderFrequencyText = () => {
    if (isAutoRestock) {
      return (
        <div>
          <span className="ui-icon ui-icon--repeat ui-mr--1" />
          <span>Auto-restock</span>
        </div>
      )
    } else {
      return (
        <div>
          <span className="ui-icon ui-icon--repeat-once ui-mr--1" />
          <span>Get this once</span>
        </div>
      )
    }
  }

  const handleShouldUpdateToRestockSubmit = (shouldRestock: boolean) => {
    if (!handleShouldUpdateToRestock) return
    setShouldRefocusButton(true)
    handleShouldUpdateToRestock(product, shouldRestock)
  }

  return (
    <div
      aria-live="polite"
      className={classnames(
        'ui-product-tile ui-bg__paper--lightest ui-border-radius ui-text--center ui-position--relative',
        {
          'ui-pt--1': !recommended,
          'ui-product-tile--recommended': recommended,
        }
      )}
    >
      {recommended && (
        <div className="ui-text--sm ui-product-tile__recommendation-wrapper">
          {recommended}
        </div>
      )}
      {newBadge ? (
        <span
          className={classnames(
            'ui-text__label ui-text__label--md ui-product-tile__new-badge'
          )}
        >
          New
        </span>
      ) : (
        <div className={classnames('ui-product-tile__empty-badge')} />
      )}
      <Imgix
        className={classnames('ui-img--fluid', {
          'ui-cursor--pointer': !!onImgClick,
        })}
        disableLibraryParam
        imgixParams={{ fit: 'crop' }}
        src={productImage}
        sizes="auto"
        htmlAttributes={{
          'alt': '',
          'role': 'presentation',
          'data-testid': 'product-image',
          'onClick': onImgClick ? () => onImgClick(product) : noop,
        }}
      />
      <div className="ui-product-tile__name ui-v-align__container">
        <div
          className={classnames(
            'ui-color--paper-darkest ui-v-align__item--top'
          )}
        >
          {showBaseNameOnly ? (
            <span className="ui-product-tile__product-name">
              {product.basename}
            </span>
          ) : (
            <span className="ui-product-tile__product-name">
              {[product.modifier, product.basename].join(' ')}
            </span>
          )}
          {product.scent && (
            <div className="ui-text--sm ui-color--paper-medium ui-product-tile__product-details">
              {product.scent}
            </div>
          )}
          {showSize && (
            <div className="ui-color--paper-medium ui-text--sm ui-product-tile__product-details">
              {product.sizeNumber} {product.abbrSizeUnit}
            </div>
          )}
        </div>
      </div>
      <div className="ui-product-tile__children-wrapper ui-product-tile__review-stars">
        {childrenBottom}
      </div>
      <div className="ui-product-tile__price-wrapper">
        {childrenMiddle ||
          (price && onClickAdd && (
            <PriceAddButton
              {...{
                disabled,
                product,
                onClickAdd,
                price,
                dataTestId,
                isLoading,
                isAdded,
                isSoldOut,
                showAddAnimation,
                onClickRemove,
                additionalButtonClasses: buttonClasses,
                shouldRefocusButton,
              }}
            />
          ))}
        {(!isAdded || isLoading || showAddAnimation) && showPriceComparison && (
          <div className="ui-text--sm">
            Regular: <s>{retailPrice}</s>
          </div>
        )}
        {product.planEligible &&
          handleShouldUpdateToRestock &&
          isAdded &&
          !showAddAnimation &&
          !isLoading &&
          renderFrequencyText()}
      </div>
      <Tray
        padding={false}
        backdrop={false}
        isOpen={isShowingOverlay}
        position="bottom"
        isRelativePosition
        role="alertdialog"
        ariaLabel="Restock options"
        ariaDescId={`product-tile-dialog-desc-for-${product.sku}`}
      >
        <TileOverlay
          handleShouldUpdateToRestock={handleShouldUpdateToRestockSubmit}
          id={`product-tile-dialog-desc-for-${product.sku}`}
          isLoading={isLoadingOverlay}
          isVisible={isShowingOverlay}
        />
      </Tray>
    </div>
  )
}

export const ProductTile = memo(ProductTileBase)
