import * as React from 'react';
import {
  forwardRef,
  useContext,
  createRef,
  useCallback,
  useMemo,
  MouseEvent,
  KeyboardEvent,
  CSSProperties,
  useEffect,
} from 'react';
import { stylesheet } from 'typestyle';
import { StoreContext } from '../../../../../../../services/store';
import { CustomProductButtons, IMedia, IProduct } from '../../../../../../../types';
import { onKeyDownEventCallback } from '../../../../../../../utils/onKeyDown';
import useBorderRadius from '../../../../../../../hooks/useBorderRadius';
import formatCurrency from '../../../../../../../utils/formatCurrency';
import ProductImage from '../../../components/ProductImage';
import Arrow from '../../../../../../Icons/Arrows/Arrow';
import AddToCartButton from '../../../../../../Icons/AddToCart/AddToCartButton';

const ITEM_MAX_SIZE = 80;

interface ProductProps {
  product: IProduct;
  parentMedia: IMedia;
  isVisible: boolean;
  containerWidth: number;
  onAddToCart?: (product: IProduct, media: IMedia) => void;
}

const ProductListItem = forwardRef<HTMLDivElement, ProductProps>(
  ({ product, parentMedia, isVisible, onAddToCart }, ref) => {
    const context = useContext(StoreContext);
    const anchorRef = createRef<HTMLAnchorElement>();

    const borderRadius = useBorderRadius(
      ITEM_MAX_SIZE,
      ITEM_MAX_SIZE,
      context.data.settings.thumbnail_corners,
    );

    const title = [product.title, product.variant_name].filter(Boolean).join(' - ');
    const imageLink = isVisible ? product.image_link : undefined;

    // Trigger productViewed event on mount and whenever the viewed post changes
    useEffect(() => {
      if (context.post && isVisible) {
        context.triggerEvent(
          'productViewed',
          {
            post: context.post,
            product: product.id,
          },
          context.data.id,
        );
      }
    }, [context.post?.id]);

    const handleShopClick = useCallback(
      (e: MouseEvent | KeyboardEvent) => {
        if (context.post) {
          context.triggerEvent(
            'productClicked',
            {
              post: context.post,
              originalEvent: e.nativeEvent,
              product: product.id,
            },
            context.data.id,
          );
        }

        setTimeout(() => {
          if (context.config.shopThisLookHandler) {
            context.config.shopThisLookHandler({ media: parentMedia, product }, product.link);
          } else {
            window.open(product.link, '_self');
          }
        }, 300);
      },
      [product, parentMedia, context],
    );

    const customButtons = useMemo(() => {
      if (context.config.getCustomProductButtons) {
        return Object.entries(
          context.config.getCustomProductButtons(React, product, parentMedia),
        ).map(([position, Button]) => (
          <div
            key={position}
            className={styles.buttonPositions[position as keyof CustomProductButtons]}
          >
            <Button onClick={() => {}} />
          </div>
        ));
      }
      return undefined;
    }, [context.config.getCustomProductButtons, product.id, parentMedia.id]);

    return (
      <div
        ref={ref}
        style={styles.product}
        className={`${context.config.classPrefix}-postviewer-details-product`}
        onClick={handleShopClick}
        onKeyDown={(e) => onKeyDownEventCallback(e, () => handleShopClick(e))}
        role='button'
        tabIndex={0}
        aria-label={`Open product page for ${title}${
          product.price && product.currency
            ? `. Price: ${formatCurrency(product.price, product.currency)}`
            : ''
        }`}
      >
        <div style={styles.imageContainer}>
          <ProductImage
            imageLink={imageLink}
            title={title}
            onImageClick={() => anchorRef.current?.click()}
            cornerType={context.data.settings.thumbnail_corners}
            borderRadius={borderRadius}
            customButtons={customButtons}
            containerWidth={ITEM_MAX_SIZE}
            productId={product.id}
            mode='list'
            isFocusable={false}
          />
        </div>

        <div style={styles.productInfo(context.isMobile)}>
          <div style={styles.title}>{title}</div>
          {product.price !== undefined && product.price > 0 && product.currency ? (
            <div style={styles.price(context.isMobile)}>
              {formatCurrency(product.price, product.currency)}
            </div>
          ) : null}
        </div>

        <div style={styles.arrowContainer} aria-hidden='true'>
          {context.config.addToCartHandler ? (
            <AddToCartButton
              size='compact'
              onClick={(e) => {
                e.stopPropagation();
                onAddToCart?.(product, parentMedia);
              }}
              ariaLabel={`Add ${title} to cart`}
              classPrefix={context.config.classPrefix}
              customIcon={context.config.addToCartIcon}
            />
          ) : null}
          <Arrow
            direction='right'
            size='compact'
            show={true}
            disabled={false}
            classPrefix='product-list'
            onClick={handleShopClick}
          />
        </div>
      </div>
    );
  },
);

const styles = {
  product: {
    width: '100%',
    height: 'fit-content',
    display: 'flex',
    alignItems: 'center',
    cursor: 'pointer',
    backgroundColor: '#FFFFFF',
    transition: 'background-color 0.2s',
    $nest: {
      '&:hover': {
        backgroundColor: '#F5F5F5',
      },
    },
  } as CSSProperties,

  imageContainer: {
    height: 'auto',
    width: 'auto',
    flexShrink: 0,
    display: 'flex',
    alignItems: 'center',
  } as CSSProperties,

  productInfo: (isMobile: boolean): CSSProperties => ({
    flex: 1,
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    padding: '0 15px',
    overflow: 'hidden',
    fontSize: isMobile ? 14 : 16,
  }),

  title: {
    fontWeight: 300,
    whiteSpace: 'normal',
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    marginBottom: 5,
    display: '-webkit-box',
    WebkitLineClamp: 2,
    WebkitBoxOrient: 'vertical',
    lineHeight: 1.2,
    color: 'black',
    textDecoration: 'none',
  } as CSSProperties,

  price: (isMobile: boolean): CSSProperties => ({
    fontSize: isMobile ? 12 : 14,
    color: '#666666',
  }),

  arrowContainer: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    flexShrink: 0,
    gap: 4,
  } as CSSProperties,

  buttonPositions: stylesheet({
    topRight: { position: 'absolute', top: 0, right: 0 },
    topLeft: { position: 'absolute', top: 0, left: 0 },
    bottomRight: { position: 'absolute', bottom: 0, right: 0 },
    bottomLeft: { position: 'absolute', bottom: 0, left: 0 },
  }),
};

export default ProductListItem;
