import React, { useEffect, useState } from 'react'
import { observer } from 'mobx-react-lite'
import { UStoreProvider } from '@ustore/core'
import { t } from '$themelocalization'
import { Icon, LoadingDots } from '$core-components'
import theme from '$styles/theme'
import CartCheckbox from '../CartList/CartCheckbox'
import CartErrorModel from '../model/CartErrorModel'
import ConfirmationDialog from '../ConfirmationDialog'
import DisplayPrice from './DisplayPrice'
import CartItemActions from './CartItemActions'
import ProductName from './ProductName'
import ProductProperties from './ProductProperties'
import CartItemThumbnail from './CartItemThumbnail'
import CartItemAlert from './CartItemAlert'
import InfoMessage from './InfoMessage'
import './index.scss'
import { Nickname } from './Nickname'
import CartQuantity from './CartQuantity'
import IncludedProductsDetails from "./IncludedProductsDetails";

const Price = observer(({ currencyState, price, hasPricing }) =>
  price
    ? (<DisplayPrice
      price={price}
      hasPricing={hasPricing}
      isHighlighted
      currencyState={currencyState}
    />)
    : (
      <LoadingDots className="loading-dots"/>
    )
)

const CartItem = ({
  currencyState,
  item,
  showSelection = true,
}) => {
  const {
    orderItemId,
    checked,
    quantity,
    thumbnailUrl,
    quantityPerRecipient,
    numRecipients,
    product,
    errors,
    warnings,
    price,
    _listModel,
    _cartModel,
  } = item
  const [alertMessage, setAlertMessage] = useState('')
  const [showQuantityDeleteDialog, setShowQuantityDeleteDialog] = useState(false)
  const [hasMounted, setHasMounted] = useState(false)
  const [quantityError, setQuantityError] = useState('')
  const [isMobile, setIsMobile] = useState(false)
  const [quantityConfig, setQuantityConfig] = useState(null)
  const [inventoryLimit, setInventoryLimit] = useState(null)
  const [configLoaded, setConfigLoaded] = useState(false)
  // todo: change to the hook useMobile with change <=
  useEffect(() => {
    const mdBreakpoint = parseInt(theme.md.replace('px', ''))
    const check = () => setIsMobile(window.innerWidth <= mdBreakpoint)
    check()
    window.addEventListener('resize', check)
    return () => window.removeEventListener('resize', check)
  }, [])

  useEffect(() => {
    let cancelled = false
    const isProductUnavailable = item.errors?.some(e => e.errorType === CartErrorModel.CART_ERROR_TYPES.ProductNotAvailable)
    if (isProductUnavailable) {
      setConfigLoaded(true)
      return
    }
    const loadConfig = async () => {
      try {
        const productData = await UStoreProvider.api.products.getProductByID(product.productId, false, { suppressGlobalError: true })
        if (!cancelled && productData?.Configuration?.Quantity) {
          setQuantityConfig(productData.Configuration.Quantity)
        }
        if (!cancelled && productData?.Inventory && !productData.Inventory.AllowOutOfStockPurchase) {
          setInventoryLimit(productData.Inventory.Quantity)
        }
      } catch (e) {
        // Product may be unavailable — ignore
      }
      if (!cancelled) setConfigLoaded(true)
    }
    loadConfig()
    return () => { cancelled = true }
  }, [product.productId])

  const hasMessages = Boolean(errors?.length || warnings?.length)

  useEffect(() => {
    setHasMounted(true)
  }, [])

  const onDelete = () => {
    setAlertMessage(t('Cart.CartItemDeleted'))
    item.delete()
  }

  const handleTransitionEnd = (e) => {
    let target = e.target
    if (!target.classList.contains('cart-ng-confirmation-dialog-backdrop') && target.nextElementSibling?.classList.contains('cart-ng-confirmation-dialog-backdrop')) {
      target = target.nextElementSibling
    }
    if (target.classList.contains('cart-ng-confirmation-dialog-backdrop') && target.classList.contains('fade') && !target.classList.contains('show')) {
      onDelete()
    }
  }

  const editDisabled = item == null || errors.some(({ errorType }) => errorType === CartErrorModel.CART_ERROR_TYPES.ProductNotAvailable)
  const itemInListMode = !_listModel.isUnassigned && _cartModel.isListsMode

  return (
    <div
      className={`item-box-container ${_listModel.isOrderEdit ? 'item-order-edit' : ''} ${alertMessage ? 'close-item' : ''}`}
      onTransitionEnd={handleTransitionEnd}>
      <CartItemAlert message={alertMessage} className={alertMessage ? 'move-right' : ''}/>
      <div className={`item-box ${alertMessage ? 'move-right' : ''} ${showSelection ? 'has-selection' : ''} `}>
        <div className="mobile-title-container">
          <div className="mobile-product-name">
            {showSelection && (
              <div className="cart-item-checkbox-cell">
                <CartCheckbox
                  id={orderItemId}
                  name={orderItemId}
                  className="item-checkbox"
                  checked={checked}
                  onSelect={() => item.toggleSelect()}
                />
              </div>
            )}
            <ProductName item={item}/>
          </div>
          <div className="mobile-nickname">
            {item.nickname && <Nickname
              nickname={item.nickname}
              setNickname={(newNickname) => item.updateNickname(newNickname)}
            />}
          </div>
        </div>
        {showSelection && (
          <div className="cart-item-checkbox-cell">
            <CartCheckbox
              id={orderItemId}
              name={orderItemId}
              className="item-checkbox"
              checked={checked}
              onSelect={() => item.toggleSelect()}
            />
          </div>
        )}
        <CartItemThumbnail src={thumbnailUrl} onThumbnailClick={() => item.edit()} orderItemId={orderItemId}
                           editDisabled={editDisabled} proofInProgress={item.proof.Status === 1}
                           proofWarning={item.proof.Status === 3}
                           proofFailedMessage={warnings.find(warning => warning.errorType === 997)?.message}
        />
        <div className="item-description">
          <ProductName item={item}/>
          <Price
            price={price}
            hasPricing={product.hasPricing}
            currencyState={currencyState}
          />
          <IncludedProductsDetails includedProducts={item.subItems}/>
          <ProductProperties product={product} item={item} quantityConfig={quantityConfig}/>
          {!isMobile && (
            <div className="cart-quantity-wrapper">
              <CartQuantity item={item} onDeleteRequest={() => setShowQuantityDeleteDialog(true)} onErrorChange={setQuantityError} quantityConfig={quantityConfig} inventoryLimit={inventoryLimit} configLoaded={configLoaded} />
              {quantityError && (
                <div id={`cart-quantity-error-${orderItemId}`} className="cart-quantity-error" role="alert">
                  <Icon name="cart_error.svg" width="12px" height="12px" wrapperClassName="error-icon" ariaHidden="true"/>
                  <span>{quantityError}</span>
                </div>
              )}
            </div>
          )}
        </div>
        <div className="item-actions">
          <Price
            price={price}
            currencyState={currencyState}
            hasPricing={product.hasPricing}
          />
          {isMobile && (
            <div className="cart-quantity-wrapper mobile-only">
              <CartQuantity item={item} onDeleteRequest={() => setShowQuantityDeleteDialog(true)} onErrorChange={setQuantityError} quantityConfig={quantityConfig} inventoryLimit={inventoryLimit} configLoaded={configLoaded} />
            </div>
          )}
          <CartItemActions {...{ editDisabled, item, setAlertMessage }}
          />
        </div>
        {isMobile && quantityError && (
          <div id={`cart-quantity-error-${orderItemId}`} className="cart-quantity-error" role="alert">
            <Icon name="cart_error.svg" width="12px" height="12px" wrapperClassName="error-icon" ariaHidden="true"/>
            <span>{quantityError}</span>
          </div>
        )}
        {hasMessages ? <div className={`cart-item-warning-error-messages ${itemInListMode ? 'warning-in-list-mode':''}`} role={errors?.length ? 'alert' : 'status'}>
          {hasMounted && errors?.length ? <InfoMessage type="error" messages={errors}/> : null}
          {hasMounted && warnings?.length ? <InfoMessage type="warning" messages={warnings}/> : null}
        </div> : null}
        <ConfirmationDialog
          open={showQuantityDeleteDialog}
          itemThumbnail={item.thumbnailUrl}
          confirmationText={t('Cart.Dialog.Delete.ConfirmDeleteItem')}
          confirmButtonText={t('Cart.Dialog.Delete.ConfirmDeleteButtonText')}
          rejectButtonText={t('Cart.Dialog.Delete.RejectButtonText')}
          onReject={() => setShowQuantityDeleteDialog(false)}
          onConfirm={() => {
            setShowQuantityDeleteDialog(false)
          }}
        />
      </div>
    </div>
  )
}

export default observer(CartItem)
