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

interface ModalProps {
  post: IMedia;
  settings: ISettings;
  totalPosts: number;
  onClose: () => void;
  onPostChange: (post: IMedia | null) => void;
  classPrefix: string;
}

const ShopThisLookModal: FC<ModalProps> = ({
  post,
  totalPosts,
  onClose,
  onPostChange,
  settings,
  classPrefix,
}) => {
  const store = useStore();
  const context = useContext(StoreContext);
  const { triggerNavigationEvent } = usePostViewerEvents();
  const contentRef = useRef<HTMLDivElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);

  const { accessibilityMessage, announce } = useAccessibilityMessage();

  const [isClosing, setIsClosing] = useState(false);

  const baseSize = Math.min(window.innerHeight * 0.7, window.innerWidth * 0.7);
  const borderRadius = useBorderRadius(baseSize, baseSize, settings.thumbnail_corners);

  const isShopThisLookModalEnabled =
    settings.shop_this_look_display === 'modal' && !!(post.products && post.products.length > 0);

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

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

    // Handle infinite scroll with wrap-around
    let validIndex = newIndex;
    if (validIndex < 0) {
      validIndex = totalPosts - 1;
    } else if (validIndex >= totalPosts) {
      validIndex = 0;
    }

    const targetPost = store.data.content.medias[validIndex];
    if (!targetPost) return;

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

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

  const handleClose = useCallback(
    (e?: MouseEvent<HTMLElement | SVGElement | HTMLOrSVGElement>) => {
      e?.stopPropagation();
      setIsClosing(true);
      setTimeout(() => {
        onClose();
      }, 300);
    },
    [onClose],
  );

  return (
    <div
      className={`${styles.desktop} ${store.config.classPrefix}-productlist`}
      onClick={handleClose}
    >
      <div style={getSrOnlyStyle()} role='status' aria-live='polite' aria-atomic='true'>
        {accessibilityMessage}
      </div>
      <div className={styles.containerWrapper} onClick={(e) => e.stopPropagation()}>
        <Arrow
          direction='left'
          disabled={false}
          onClick={() => handleArrowClick('left')}
          show={true}
          classPrefix={classPrefix}
          size='large'
          ariaLabel='Previous post'
        />

        <div
          ref={containerRef}
          className={`${classPrefix}-postviewer ${styles.container({
            borderRadius,
            shopThisLook: isShopThisLookModalEnabled,
            baseSize,
            isClosing,
          })}`}
        >
          <div className={styles.content(isShopThisLookModalEnabled)}>
            <div
              className={styles.blurredBackground}
              style={{
                backgroundImage: (post.thumbnail ?? post.image)
                  ? `url(${post.thumbnail ?? post.image})`
                  : 'none',
                backgroundColor: (post.thumbnail ?? post.image) ? 'transparent' : '#000',
              }}
            />
            <Content ref={contentRef} autoplay showMuteButton showDurationBar showUsernamePill />
          </div>

          {isShopThisLookModalEnabled ? (
            <div
              className={styles.details(context.config.displayCustomShopThisLook)}
              role='region'
              aria-label='Product list'
            >
              <ProductModal />
            </div>
          ) : null}

          <button
            type='button'
            className={`${classPrefix}-postviewer-close ${styles.closeButton}`}
            onClick={(e) => handleClose(e)}
            aria-label='Close product modal'
          >
            <CloseIcon size={11} />
          </button>
        </div>

        <Arrow
          direction='right'
          disabled={false}
          onClick={() => handleArrowClick('right')}
          show={true}
          classPrefix={classPrefix}
          size='large'
          ariaLabel='Next post'
        />
      </div>
    </div>
  );
};

// Keyframes are defined once at module level so the animation name is stable across re-renders.
const scaleUp = keyframes({
  from: {
    transform: 'scale(0.5)',
    opacity: 0,
  },
  to: {
    transform: 'scale(1)',
    opacity: 1,
  },
});

const scaleDown = keyframes({
  from: {
    transform: 'scale(1)',
    opacity: 1,
  },
  to: {
    transform: 'scale(0.5)',
    opacity: 0,
  },
});

const styles = {
  desktop: style({
    position: 'fixed',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    padding: 40,
    overflow: 'auto',
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
    zIndex: productListZIndex,
  }),

  containerWrapper: style({
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    width: 'fit-content',
    maxWidth: '100%',
    margin: '0 auto',
    position: 'relative',
    gap: '20px',
  }),

  container: (props: {
    borderRadius: string;
    shopThisLook: boolean;
    baseSize: number;
    isClosing: boolean;
  }) =>
    style({
      borderRadius: props.borderRadius,
      backgroundColor: 'white',
      position: 'relative',
      alignItems: 'center',
      width: props.shopThisLook ? props.baseSize * 2 : props.baseSize,
      height: props.baseSize,
      display: 'flex',
      animation: props.isClosing
        ? `${scaleDown} 0.3s ease-in forwards`
        : `${scaleUp} 0.3s ease-out forwards`,
    }),

  blurredBackground: style({
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%',
    backgroundSize: 'cover',
    backgroundPosition: 'center',
    filter: 'blur(20px)',
    transform: 'scale(1.2)',
    zIndex: 0,
  }),

  content: (shopThisLook: boolean) =>
    style({
      display: 'flex',
      flexDirection: 'row',
      width: shopThisLook ? '50%' : '100%',
      height: '100%',
      overflow: 'hidden',
      position: 'relative',
      borderTopLeftRadius: 'inherit',
      borderTopRightRadius: shopThisLook ? 0 : 'inherit',
      borderBottomRightRadius: shopThisLook ? 0 : 'inherit',
      borderBottomLeftRadius: 'inherit',
    }),

  details: (customShopThisLook?: DisplayCustomShopThisLook) =>
    style({
      width: '50%',
      height: '100%',
      overflow: typeof customShopThisLook === 'function' ? 'auto' : 'hidden',
      borderTopRightRadius: 'inherit',
      borderBottomRightRadius: 'inherit',
    }),

  closeButton: style({
    position: 'absolute',
    top: 27,
    background: 'none',
    border: 'none',
    padding: 0,
    right: 20,
    cursor: 'pointer',
    zIndex: 2,
  }),
};

export default ShopThisLookModal;
