import { useState } from 'react';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { Box, Avatar, Typography, Stack, IconButton, Menu, MenuItem, Select, FormControl } from '@mui/material';
import { AddOutlined, MoreHorizOutlined } from '@mui/icons-material';
import type { TProductExpanded } from '@blocklet/payment-types';
import { findCurrency, formatPrice, usePaymentContext } from '@blocklet/payment-react';
import { dispatch } from 'use-bus';
import cloneDeep from 'lodash/cloneDeep';
import { useProductsContext } from '../../contexts/products';

type ProductDynamicSelectProps = {
  value?: string[];
  onChange: (productIds: string[]) => void;
  disabled?: boolean;
};

const filterPrices = (product: TProductExpanded, hasSelected: (price: any) => boolean) => {
  product.prices = product.prices.filter((x) => {
    const isActive = x.active;
    const notSelected = !hasSelected(x);
    return isActive && notSelected;
  });
  return product;
};

const filterProducts = (products: TProductExpanded[], hasSelected: (price: any) => boolean) => {
  const filtered = cloneDeep(products).map((x) => filterPrices(x, hasSelected));
  return filtered.filter((x) => x.prices.length);
};

export default function ProductDynamicSelect({ value = [], onChange, disabled = false }: ProductDynamicSelectProps) {
  const { t } = useLocaleContext();
  const { products } = useProductsContext();
  const { settings } = usePaymentContext();
  const [menuAnchor, setMenuAnchor] = useState<null | HTMLElement>(null);
  const [selectedProductForMenu, setSelectedProductForMenu] = useState<string | null>(null);
  const [showAdditionalSelector, setShowAdditionalSelector] = useState(false);
  const [selectorOpen, setSelectorOpen] = useState(false);

  const selectedProducts = (products || []).filter((product) => value.includes(product.id));
  const availableProducts = (products || []).filter((product) => !value.includes(product.id));

  const getPriceDisplay = (product: TProductExpanded) => {
    if (!product.prices || product.prices.length === 0) {
      return null;
    }

    if (product.prices.length === 1) {
      const price = product.prices[0];
      if (price) {
        const currency = findCurrency(settings.paymentMethods, price.currency_id ?? '') || settings.baseCurrency;
        return formatPrice(price, currency!);
      }
    }

    return t('admin.price.count', { count: product.prices.length });
  };

  const handleProductSelect = (productId: string) => {
    if (productId === 'add') {
      dispatch('product.create.request');
      return;
    }

    if (productId && !value.includes(productId)) {
      const newValue = [...value, productId];
      onChange(newValue);
      // Hide the additional selector and close dropdown after selection
      setShowAdditionalSelector(false);
      setSelectorOpen(false);
    }
  };

  const handleRemoveProduct = (productId: string) => {
    const newValue = value.filter((id) => id !== productId);
    onChange(newValue);
    setMenuAnchor(null);
    setSelectedProductForMenu(null);
  };

  const handleMenuClick = (event: React.MouseEvent<HTMLElement>, productId: string) => {
    setMenuAnchor(event.currentTarget);
    setSelectedProductForMenu(productId);
  };

  const handleMenuClose = () => {
    setMenuAnchor(null);
    setSelectedProductForMenu(null);
  };

  const handleAddAnotherProduct = () => {
    setShowAdditionalSelector(true);
    setSelectorOpen(true);
  };

  const handleSelectorClose = () => {
    setSelectorOpen(false);
  };

  const handleSelectorOpen = () => {
    setSelectorOpen(true);
  };

  const renderProductItems = () => {
    const filteredProducts = filterProducts(products, () => false); // Show all available products

    if (filteredProducts.length === 0) {
      return [];
    }

    return filteredProducts.map((product) => (
      <MenuItem
        key={`product-${product.id}`}
        value={product.id}
        disabled={value.includes(product.id)} // Disable if already selected
      >
        <Stack
          direction="row"
          spacing={1}
          sx={{
            alignItems: 'center',
            width: '100%',
          }}>
          {product.images[0] ? (
            <Avatar src={product.images[0]} alt={product.name} variant="square" sx={{ width: 24, height: 24 }} />
          ) : (
            <Avatar variant="square" sx={{ width: 24, height: 24, fontSize: '0.75rem' }}>
              {product.name.slice(0, 1)}
            </Avatar>
          )}
          <Box sx={{ flex: 1, minWidth: 0 }}>
            <Typography variant="body2" noWrap>
              {product.name}
            </Typography>
          </Box>
          <Typography
            variant="body2"
            sx={{
              color: 'text.secondary',
              ml: 'auto',
              flexShrink: 0,
            }}>
            {value.includes(product.id) ? 'Added' : getPriceDisplay(product)}
          </Typography>
        </Stack>
      </MenuItem>
    ));
  };

  return (
    <Stack spacing={2}>
      {/* Selected Products */}
      {selectedProducts.map((product) => (
        <Box
          key={product.id}
          sx={{
            display: 'flex',
            alignItems: 'center',
            gap: 2,
            p: 2,
            border: '1px solid',
            borderColor: 'divider',
            borderRadius: 1,
            backgroundColor: 'background.paper',
          }}>
          {/* Product Icon */}
          {product.images[0] ? (
            <Avatar src={product.images[0]} alt={product.name} variant="square" sx={{ width: 40, height: 40 }} />
          ) : (
            <Avatar variant="square" sx={{ width: 40, height: 40, fontSize: '1rem' }}>
              {product.name.slice(0, 1)}
            </Avatar>
          )}

          {/* Product Info */}
          <Box sx={{ flex: 1, minWidth: 0 }}>
            <Typography
              variant="body1"
              noWrap
              sx={{
                fontWeight: 'medium',
              }}>
              {product.name}
            </Typography>
            {getPriceDisplay(product) && (
              <Typography
                variant="body2"
                sx={{
                  color: 'text.secondary',
                }}>
                {getPriceDisplay(product)}
              </Typography>
            )}
          </Box>

          {/* Menu Button */}
          <IconButton
            size="small"
            disabled={disabled}
            onClick={(e) => handleMenuClick(e, product.id)}
            sx={{ color: 'text.secondary' }}>
            <MoreHorizOutlined />
          </IconButton>
        </Box>
      ))}
      {/* Product Selector - Show if no products selected OR if user clicked "add another" */}
      {!disabled && availableProducts.length > 0 && (value.length === 0 || showAdditionalSelector) && (
        <FormControl fullWidth size="small">
          <Select
            value=""
            open={selectorOpen}
            onClose={handleSelectorClose}
            onOpen={handleSelectorOpen}
            displayEmpty
            onChange={(e) => handleProductSelect(e.target.value as string)}
            renderValue={(selected) => {
              if (!selected) {
                return (
                  <Typography
                    variant="body2"
                    sx={{
                      color: 'text.secondary',
                    }}>
                    {t('admin.product.find')}
                  </Typography>
                );
              }
              return selected;
            }}
            MenuProps={{
              style: { maxHeight: 480 },
            }}>
            <MenuItem value="add">
              <Stack
                direction="row"
                spacing={1}
                sx={{
                  alignItems: 'center',
                }}>
                <AddOutlined fontSize="small" color="primary" />
                <Typography
                  variant="body2"
                  sx={{
                    color: 'primary.main',
                    fontWeight: 'medium',
                  }}>
                  {t('admin.product.add')}
                </Typography>
              </Stack>
            </MenuItem>
            {renderProductItems()}
          </Select>
        </FormControl>
      )}
      {/* Add Another Product Link - Only show if products are selected and additional selector is not shown */}
      {!disabled && availableProducts.length > 0 && value.length > 0 && !showAdditionalSelector && (
        <Typography
          variant="body2"
          component="button"
          onClick={handleAddAnotherProduct}
          sx={{
            color: 'primary.main',
            textDecoration: 'none',
            cursor: 'pointer',
            border: 'none',
            background: 'none',
            p: 0,
            textAlign: 'left',
            fontWeight: 'normal',
            '&:hover': {
              textDecoration: 'underline',
            },
          }}>
          {t('admin.coupon.addProduct')}
        </Typography>
      )}
      {/* Context Menu for Product Actions */}
      <Menu
        anchorEl={menuAnchor}
        open={Boolean(menuAnchor)}
        onClose={handleMenuClose}
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'right',
        }}>
        <MenuItem onClick={() => selectedProductForMenu && handleRemoveProduct(selectedProductForMenu)}>
          {t('admin.product.remove')}
        </MenuItem>
      </Menu>
    </Stack>
  );
}
