import * as React from 'react';
import {
  useState, useCallback, useRef, useEffect, forwardRef, useImperativeHandle,
} from 'react';
import { keyframes, style } from 'typestyle';
import { useStore } from '../../../services/store';
import { ISettings, IMedia, Direction } from '../../../types';
import { productListButtonsZIndex, productListZIndex } from '../../consts';
import ProductList from '../../PostViewer/components/Products/ProductList';
import Content from '../../PostViewer/components/Content';
import CloseIcon from '../../Icons/Close';
import Arrow from '../../Icons/Arrows/Arrow';
import useBorderRadius from '../../../hooks/useBorderRadius';
import { useAccessibilityMessage } from '../../../hooks/useAccessibilityMessage';
import { usePostViewerEvents } from '../../../hooks/usePostViewerEvents';
import {
  getContentAnnouncementMessage,
  getSrOnlyStyle,
} from '../../Layouts/Carousel/shared/accessibility';
import AttributionFooter from '../../PostViewer/components/AttributionFooter';

interface ListProps {
  settings: ISettings;
  classPrefix: string;
  onClose: () => void;
  post: IMedia;
  totalPosts: number;
  onPostChange: (post: IMedia | null) => void;
  /** When true, renders inline (position: relative, full-height)
   * instead of fixed/animated. Used by DesktopPlayer. */
  inline?: boolean;
}

export interface ShopThisLookProductListHandle {
  close: () => void;
}

const ShopThisLookProductList = forwardRef<ShopThisLookProductListHandle, ListProps>((
  {
  settings,
  classPrefix,
  onClose,
  post,
  totalPosts,
  onPostChange,
  inline = false,
  },
  ref,
) => {
  const store = useStore();
  const { triggerNavigationEvent } = usePostViewerEvents();
  const containerRef = useRef<HTMLDivElement>(null);
  const contentRef = useRef<HTMLDivElement>(null);
  const { accessibilityMessage, announce } = useAccessibilityMessage();
  const { isMobile } = store;
  const [isClosing, setIsClosing] = useState(false);
  const [containerDimensions, setContainerDimensions] = useState({ width: 0, height: 0 });
  const borderRadius = useBorderRadius(
    containerDimensions.width,
    containerDimensions.height,
    settings.thumbnail_corners,
    isMobile ? 'top' : 'left',
  );
  const isShopThisLookEnabled = settings.shop_this_look_display !== 'none';
  const showAttribution = settings.show_attribution !== false; // default to true

  // Announce content details when product list opens or post changes
  useEffect(() => {
    announce(getContentAnnouncementMessage(post, post.postIndex, totalPosts));
  }, [post.id, totalPosts, announce]); // Announce whenever the post changes

  const handleClose = useCallback(() => {
    setIsClosing(true);
    setTimeout(onClose, 300);
  }, [onClose]);

  useImperativeHandle(ref, () => ({ close: handleClose }), [handleClose]);

  const handleArrowClick = (dir: Direction) => {
    const newIndex = dir === 'left' ? post.postIndex - 1 : post.postIndex + 1;

    // Check if the new index is within bounds
    // in order to handle clone posts for ProductList's infinite scroll
    let validIndex = newIndex;
    if (validIndex < 0) {
      // If the new index is less than 0, set it to the last post
      validIndex = totalPosts - 1;
    } else if (validIndex >= totalPosts) {
      // If the new index is greater than or equal to totalPosts, set it to 0
      validIndex = 0;
    }
    const newPost = store.data.content.medias[validIndex];

    store.setStoreState((state) => ({
      ...state,
      currentPosition: validIndex,
    }));

    triggerNavigationEvent(newPost, dir);
    onPostChange(newPost);
    // Announcement handled by useEffect when post changes
  };

  // observe container dimensions to adapt borderradius
  useEffect(() => {
    if (!containerRef.current) return;

    const resizeObserver = new ResizeObserver((entries) => {
      const { width, height } = entries[0].contentRect;
      setContainerDimensions({ width, height });
    });

    resizeObserver.observe(containerRef.current);

    // cleanup
    // eslint-disable-next-line consistent-return
    return () => resizeObserver.disconnect();
  }, []);

  return (
    <div
      ref={containerRef}
      className={`${classPrefix}-productlist 
      ${styles.container(isMobile, isShopThisLookEnabled, isClosing, borderRadius, inline)}`}
    >
      <div style={getSrOnlyStyle()} role='status' aria-live='polite' aria-atomic='true'>
        {accessibilityMessage}
      </div>
      <div className={styles.actionBar}>
        <div
          className={`${styles.actionButtons} 
          ${store.config.classPrefix}-productlist-action-buttons`}
        >
          <Arrow
            direction='left'
            disabled={false}
            onClick={() => handleArrowClick('left')}
            show={!isMobile && !inline}
            classPrefix={classPrefix}
            size='compact'
            ariaLabel='Previous post'
          />
          <Arrow
            direction='right'
            disabled={false}
            onClick={() => handleArrowClick('right')}
            show={!isMobile && !inline}
            classPrefix={classPrefix}
            size='compact'
            ariaLabel='Next post'
          />
          {!inline ? (
            <button
              type='button'
              className={`${styles.closeButton} ${classPrefix}-productlist-close`}
              onClick={handleClose}
              aria-label='Close product list'
            >
              <CloseIcon size={11} />
            </button>
          ) : null}
        </div>
      </div>

      {isShopThisLookEnabled ? (
        <div className={styles.productList(isMobile)}>
          <ProductList />
        </div>
      ) : (
        <div className={styles.content(isShopThisLookEnabled)}>
          <Content ref={contentRef} />
        </div>
      )}

      {showAttribution ? (
        <AttributionFooter classPrefix={store.config.classPrefix} type='list' />
      ) : null}
    </div>
  );
});

const styles = {
  container: (
    isMobile: boolean,
    shopThisLookEnabled: boolean,
    isClosing: boolean,
    borderRadius: string,
    inline: boolean = false,
  ) => {
    const slideUp = keyframes({
      from: { transform: 'translateY(100%)' },
      to: { transform: 'translateY(0)' },
    });

    const slideDown = keyframes({
      from: { transform: 'translateY(0)' },
      to: { transform: 'translateY(100%)' },
    });

    const slideRight = keyframes({
      from: { transform: 'translateX(100%)' },
      to: { transform: 'translateX(0)' },
    });

    const slideLeft = keyframes({
      from: { transform: 'translateX(0)' },
      to: { transform: 'translateX(100%)' },
    });

    if (inline) {
      return style({
        position: 'relative',
        height: '100%',
        width: '100%',
        display: 'flex',
        flexDirection: 'column',
        backgroundColor: '#FFFFFF',
        borderRadius,
        zIndex: productListZIndex,
        overflow: 'hidden',
      });
    }

    return style({
      position: 'fixed',
      bottom: 0,
      right: 0,
      // eslint-disable-next-line no-nested-ternary
      height: isMobile ? (shopThisLookEnabled ? 'auto' : '70vh') : '100%',
      maxHeight: isMobile && shopThisLookEnabled ? '57vh' : undefined,
      width: isMobile ? '100%' : '20%',
      display: 'flex',
      flexDirection: 'column',
      backgroundColor: '#FFFFFF',
      borderRadius,
      zIndex: productListZIndex,
      ...(isMobile
        ? {
            transform: 'translateY(100%)',
            animation: isClosing
              ? `${slideDown} 0.3s ease-in forwards`
              : `${slideUp} 0.3s ease-out forwards`,
          }
        : {
            transform: 'translateX(100%)',
            animation: isClosing
              ? `${slideLeft} 0.3s ease-in forwards`
              : `${slideRight} 0.3s ease-out forwards`,
          }),
    });
  },

  actionBar: style({
    height: '7vh',
    width: '100%',
    display: 'flex',
    justifyContent: 'flex-end',
    alignItems: 'center',
  }),

  actionButtons: style({
    display: 'flex',
    alignItems: 'center',
    zIndex: productListButtonsZIndex,
  }),

  closeButton: style({
    margin: '12px',
    cursor: 'pointer',
    background: 'none',
    border: 'none',
    padding: 0,
  }),

  content: (isShopThisLook: boolean) =>
    style({
      maxHeight: isShopThisLook ? '50%' : '100%',
      width: '100%',
      overflow: 'hidden',
      display: 'flex',
      flexDirection: 'column',
    }),

  productList: (isMobile: boolean) =>
    style({
      flex: isMobile ? '0 1 auto' : 1,
      minHeight: 0,
      width: '100%',
      overflow: isMobile ? 'auto' : 'hidden',
    }),
};

export default ShopThisLookProductList;
