import React, { useState, useCallback, useEffect, useRef } from 'react'
import { observer } from 'mobx-react-lite'
import { t } from '$themelocalization'
import { Select } from '$core-components'
import CartUnitInfo from './CartUnitInfo'
import './CartQuantity.scss'

const CartQuantity = observer(({ item, onDeleteRequest, onErrorChange, quantityConfig, inventoryLimit, configLoaded }) => {
  const { quantity, product } = item

  const totalQuantity = item.numRecipients && item.quantityPerRecipient
    ? item.numRecipients * item.quantityPerRecipient
    : quantity

  const editableQuantity = item.numRecipients && item.quantityPerRecipient
    ? item.quantityPerRecipient
    : quantity

  const [inputValue, setInputValue] = useState(String(editableQuantity))
  const [error, setErrorState] = useState('')
  const [updating, setUpdating] = useState(false)
  const debounceRef = useRef(null)

  const setError = useCallback((err) => {
    setErrorState(err)
    item._cartModel.setQuantityError(item.orderItemId, !!err)
    onErrorChange?.(err)
  }, [item, onErrorChange])

  useEffect(() => {
    setInputValue(String(editableQuantity))
    setError('')
  }, [editableQuantity])

  // Cleanup debounce on unmount
  useEffect(() => {
    return () => { if (debounceRef.current) clearTimeout(debounceRef.current) }
  }, [])

  const validate = useCallback((value) => {
    if (value === '' || value === undefined || value === null) {
      return t('KitQuantity.Validation_required')
    }
    const num = parseInt(value, 10)
    if (isNaN(num)) {
      return t('KitQuantity.Validation_required')
    }
    if (num === 0) {
      return t('KitQuantity.Validation_minimum', { MinimumQuantity: 1 })
    }
    if (quantityConfig) {
      if (quantityConfig.Minimum && num < quantityConfig.Minimum) {
        return t('KitQuantity.Validation_minimum', { MinimumQuantity: quantityConfig.Minimum })
      }
      if (quantityConfig.Maximum && num > quantityConfig.Maximum) {
        return t('KitQuantity.Validation_maximum', { MaximumQuantity: quantityConfig.Maximum })
      }
    }
    if (inventoryLimit !== null && num > inventoryLimit) {
      return t('KitQuantity.Validation_inventory', { InventoryQuantity: inventoryLimit })
    }
    return ''
  }, [quantityConfig, inventoryLimit])

  const doUpdate = useCallback(async (num) => {
    setUpdating(true)
    try {
      await item.updateQuantity(num)
    } catch (e) {
      setError(e?.Message || t('KitQuantity.Validation_required'))
      setInputValue(String(editableQuantity))
    } finally {
      setUpdating(false)
    }
  }, [editableQuantity, item])

  // Debounced submit for +/- buttons
  const submitDebounced = useCallback((newValue) => {
    const validationError = validate(newValue)
    setError(validationError)
    if (validationError) return

    const num = parseInt(newValue, 10)
    if (debounceRef.current) clearTimeout(debounceRef.current)
    debounceRef.current = setTimeout(() => doUpdate(num), 500)
  }, [validate, doUpdate])

  // Immediate submit for blur/enter
  const submitImmediate = useCallback((newValue) => {
    const validationError = validate(newValue)
    setError(validationError)
    if (validationError) return

    const num = parseInt(newValue, 10)
    if (debounceRef.current) clearTimeout(debounceRef.current)
    doUpdate(num)
  }, [validate, doUpdate])

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

  const onBlur = () => {
    submitImmediate(inputValue)
  }

  const onKeyDown = (e) => {
    if (e.key === 'Enter') {
      e.target.blur()
    }
    if (e.key === '.' || e.key === '-' || e.key === '+' || e.key === 'e') {
      e.preventDefault()
    }
  }

  const onMinus = (e) => {
    e.preventDefault()  // prevent blur on input
    const current = parseInt(inputValue, 10) || 0
    if (current <= 1) {
      if (onDeleteRequest) onDeleteRequest()
      return
    }
    const newVal = current - 1
    setInputValue(String(newVal))
    setError('')
    submitDebounced(newVal)
  }

  const onPlus = (e) => {
    e.preventDefault()  // prevent blur on input
    const current = parseInt(inputValue, 10) || 0
    const newVal = current + 1
    const validationError = validate(newVal)
    setInputValue(String(newVal))
    setError(validationError)
    if (!validationError) {
      submitDebounced(newVal)
    }
  }

  const onDropdownChange = (key) => {
    const newVal = String(key)
    setInputValue(newVal)
    setError('')
    submitImmediate(newVal)
  }

  // While config is loading, show read-only display
  if (!configLoaded) {
    return (
      <div className="cart-quantity cart-quantity-readonly">
        <span className="cart-quantity-label">{t('product.quantity')}:</span>
        <span className="cart-quantity-value">{totalQuantity}</span>
      </div>
    )
  }
  // Read-only mode (backend says not changeable) — same layout as original ItemQuantity
  if (quantityConfig && !quantityConfig.Changeable) {
    return (
      <div className="total"><span className="total-label">{t('Cart.Item.Total')}:</span>
        <span className="item-quantity">
        {product.unit.packSingular ? (
          <>
            <span className="total-quantity">{totalQuantity}</span>
            <span className="quantity-units">{quantity > 1 ? product.unit.packPlural : product.unit.packSingular}</span>
            <span className="bracket-open">(</span>
            <span className="quantity">{product.unit.quantity}</span>
            <span className="quantity-base">{product.unit.quantity > 1 ? product.unit.plural : product.unit.singular}</span>
            <span className="dividing-slash">/</span>
            <span className="pack-singular">{product.unit.packSingular}</span>
            <span className="bracket-close">)</span>
          </>
        ) : (
          <>
            <span className="total-quantity">{totalQuantity}</span>
            <span className={totalQuantity > 1 ? 'product-units-plural' : 'product-units-singular'}>
              {totalQuantity > 1 ? product.unit.plural : product.unit.singular}
            </span>
          </>
        )}
        </span>
      </div>
    )
  }

  const unitInfo = (
    <CartUnitInfo
      unit={product.unit}
      totalQuantity={totalQuantity}
      numRecipients={item.numRecipients}
      quantityPerRecipient={item.quantityPerRecipient}
    />
  )

  // Dropdown mode
  if (quantityConfig?.Options && quantityConfig.Options.length > 0) {
    const dropdownItems = quantityConfig.Options.map((opt) => ({ id: String(opt.Value), name: opt.Name }))
    return (
      <div className={`cart-quantity cart-quantity-dropdown ${error ? 'has-error' : ''}`}>
        {unitInfo}
        <Select
          className="cart-quantity-select"
          items={dropdownItems}
          selectedKey={inputValue}
          onSelectionChange={onDropdownChange}
          isDisabled={updating}
          isInvalid={!!error}
          ariaLabel={t('product.quantity')}
          ariaDescribedBy={error ? `cart-quantity-error-${item.orderItemId}` : undefined}
          portalSelector=".item-box-container"
        />
      </div>
    )
  }

  // Editable input mode with +/- buttons
  return (
    <div className={`cart-quantity cart-quantity-editable ${error ? 'has-error' : ''}`}>
      {unitInfo}
      <div className="cart-quantity-control">
        <button
          className="cart-quantity-btn minus"
          onMouseDown={(e) => e.preventDefault()}
          onClick={onMinus}
          disabled={updating}
          aria-label="minus"
          type="button"
        >
          &minus;
        </button>
        <input
          type="text"
          inputMode="numeric"
          className={`cart-quantity-input ${inputValue.length > 3 ? 'wide' : ''}`}
          value={inputValue}
          onChange={onInputChange}
          onBlur={onBlur}
          onKeyDown={onKeyDown}
          disabled={updating}
          aria-label={t('product.quantity')}
          aria-invalid={!!error}
          aria-describedby={error ? `cart-quantity-error-${item.orderItemId}` : undefined}
        />
        <button
          className="cart-quantity-btn plus"
          onMouseDown={(e) => e.preventDefault()}
          onClick={onPlus}
          disabled={updating}
          aria-label="plus"
          type="button"
        >
          +
        </button>
      </div>
    </div>
  )
})

export default CartQuantity
