import React, { useState, useRef, useEffect, useCallback, useContext } from 'react'
import { Modal, ModalBody } from 'reactstrap-wc'
import { Icon, ButtonAria } from '$core-components'
import { RootDocumentContext } from '$themeservices'
import { useClickOutside } from '$themehooks'
import { t } from '$themelocalization'
import './DuplicateCopiesPopup.scss'

const DuplicateCopiesPopup = ({ desktopDuplicateButtonRef, onClose, onDuplicate, duplicationMaxItems, kitItemsCount = 0, isMobile }) => {
  const { rootElement } = useContext(RootDocumentContext)()
  const popupRef = useRef(null)
  const inputRef = useRef(null)
  const [inputValue, setInputValue] = useState('1')
  const [error, setError] = useState('')

  const validate = useCallback((value) => {
    if (!value) {
      return t('Cart.Duplicate.CopiesPopup.QuantityRequired')
    }
    const num = parseInt(value, 10)
    if (isNaN(num) || num < 1) {
      return t('Cart.Duplicate.CopiesPopup.QuantityRequired')
    }
    if (duplicationMaxItems > 0) {
      if (kitItemsCount > 0) {
        if (num * kitItemsCount > duplicationMaxItems) {
          return t('Cart.Duplicate.CopiesPopup.MaxCopies', { max: Math.floor(duplicationMaxItems / kitItemsCount) })
        }
      } else if (num > duplicationMaxItems) {
        return t('Cart.Duplicate.CopiesPopup.MaxCopies', { max: duplicationMaxItems })
      }
    }
    return ''
  }, [duplicationMaxItems, kitItemsCount])

  useClickOutside(popupRef, (e) => {
    if (desktopDuplicateButtonRef?.current?.contains(e.target)) return
    onClose()
  }, rootElement)

  useEffect(() => {
    if (isMobile || !desktopDuplicateButtonRef?.current || !popupRef.current) return

    let rafId = null
    const updatePosition = () => {
      if (rafId) return
      rafId = requestAnimationFrame(() => {
        rafId = null
        if (!desktopDuplicateButtonRef?.current || !popupRef.current) return
        const { height, top, left, width } = desktopDuplicateButtonRef.current.getBoundingClientRect()
        popupRef.current.style.top = `${top + height + 15}px`
        popupRef.current.style.left = `${left + width / 2}px`
      })
    }

    updatePosition()
    document.addEventListener('scroll', updatePosition, { passive: true, capture: true })
    window.addEventListener('resize', updatePosition)

    return () => {
      if (rafId) cancelAnimationFrame(rafId)
      document.removeEventListener('scroll', updatePosition, { capture: true })
      window.removeEventListener('resize', updatePosition)
    }
  }, [isMobile, desktopDuplicateButtonRef])

  useEffect(() => {
    inputRef.current?.focus()
    inputRef.current?.select()
  }, [])

  const onInputChange = (e) => {
    const val = e.target.value.replace(/[^0-9]/g, '').slice(0, 5)
    setInputValue(val)
    if (error) setError(validate(val))
  }

  const onKeyDown = (e) => {
    if (e.key === 'Enter') handleDuplicate()
    if (e.key === 'Escape') onClose()
  }

  const handleDuplicate = () => {
    const validationError = validate(inputValue)
    setError(validationError)
    if (validationError) return
    onDuplicate(parseInt(inputValue, 10))
  }

  const copiesLabel = isMobile
    ? t('Cart.Duplicate.CopiesModal.CopiesLabel')
    : t('Cart.Duplicate.CopiesPopup.CopiesLabel')

  const isSubmitDisabled = !!error && inputValue !== ''

  const copiesInput = (
    <input
      ref={inputRef}
      type="text"
      inputMode="numeric"
      className={`duplicate-copies-input${error ? ' has-error' : ''}`}
      value={inputValue}
      onChange={onInputChange}
      onKeyDown={onKeyDown}
      aria-label={copiesLabel}
    />
  )

  const errorMessage = error && (
    <div className="duplicate-copies-error" role="alert">
      <Icon name="cart_error.svg" width="12px" height="12px" wrapperClassName="error-icon" ariaHidden="true" />
      <span>{error}</span>
    </div>
  )

  if (isMobile) {
    return (
      <Modal isOpen={true} className="duplicate-copies-dialog" modalClassName="duplicate-copies-dialog-container"
             container={rootElement} role="dialog" aria-label={t('Cart.Duplicate.CopiesModal.Title')} toggle={onClose}>
        <div className="close-modal">
          <p className="title">{t('Cart.Duplicate.CopiesModal.Title')}</p>
          <button className="close-button" onClick={onClose} aria-label={t('General.Close')}>
            <Icon name="close_black.svg" width="14px" height="14px" ariaHidden="true" />
          </button>
        </div>
        <ModalBody>
          <p className="label">{copiesLabel}</p>
          {copiesInput}
          {errorMessage}
          <div className="action-buttons">
            <ButtonAria
              className="button-secondary"
              text={t('Cart.Duplicate.CopiesModal.Cancel')}
              onClick={onClose}
            />
            <ButtonAria
              className="button-primary"
              text={t('Cart.Duplicate.CopiesPopup.DuplicateButton')}
              onClick={handleDuplicate}
              disabled={isSubmitDisabled}
            />
          </div>
        </ModalBody>
      </Modal>
    )
  }

  return (
    <div ref={popupRef} className="duplicate-copies-popup" role="dialog" aria-label={t('Cart.Duplicate.CopiesPopup.Title')}>
      <div className="duplicate-copies-inner">
        <p className="duplicate-copies-title">{t('Cart.Duplicate.CopiesPopup.Title')}</p>
        <div className="duplicate-copies-field">
          <label className="duplicate-copies-label">{copiesLabel}</label>
          {copiesInput}
        </div>
        {errorMessage}
        <ButtonAria
          className="duplicate-copies-button button-secondary"
          text={t('Cart.Duplicate.CopiesPopup.DuplicateButton')}
          onClick={handleDuplicate}
          disabled={isSubmitDisabled}
        />
      </div>
    </div>
  )
}

export default DuplicateCopiesPopup
