import React, { useId, useState, useEffect } from "react";
import classNames from "classnames";

import debounce from "lodash/debounce";

import { Carousel } from "@arc-ui/components/Carousel";
import { SectionHeading, type SectionHeadingProps } from "../SectionHeading";
import { filterAttrs } from "@arc-ui/community-utils/filter-attrs";

import { ArcBreakpoints } from "../../helpers/arc-breakpoints";

import { MediaCard, MediaCardProps } from "@arc-ui/components/MediaCard";

import { useMediaQuery } from "@arc-ui/components/use-media-query";
import { ArcSizeBreakpointsL } from "@arc-ui/tokens-arc";

import styles from "./ArticleCarousel.module.css";

/**
 * Use `ArticleCarousel` to give supporting information about a page or proposition in the form of the `Carousel` containing only `MediaCard` components.
 */
export const ArticleCarousel: React.FC<ArticleCarouselProps> = ({
  cards,
  heading,
  content,
  id,
  headingLevel,
  isHeadingWordWrap,
  isCentered,
  isPadded = true,
  cardsContained = true,
  minHeights,
  ...props
}) => {
  const componentId = useId();

  const [minimumHeight, setMinimumHeight] = useState<number | undefined>(
    undefined,
  );

  const isMinWidthArcBreakpointL = useMediaQuery(
    `(min-width: ${ArcSizeBreakpointsL})`,
  );

  const checkMinHeight = debounce(() => {
    for (const [key, value] of Object.entries(ArcBreakpoints) as [
      keyof typeof ArcBreakpoints,
      number,
    ][]) {
      if (window.innerWidth > value && minHeights?.[key] != null) {
        setMinimumHeight(minHeights[key]);
        return;
      }
    }

    setMinimumHeight(undefined);
  }, 100);

  useEffect(() => {
    checkMinHeight();
    window.addEventListener("resize", checkMinHeight);

    return () => {
      window.removeEventListener("resize", checkMinHeight);

      checkMinHeight.cancel();
    };
  }, [minHeights, checkMinHeight]);

  return (
    <div {...filterAttrs(props)}>
      <SectionHeading
        isPadded={isPadded}
        id={id}
        data-testid="ArticleCarousel-header"
        heading={heading}
        isHeadingWordWrap={isHeadingWordWrap}
        headingLevel={headingLevel}
        content={content}
        isCentered={isCentered}
      />
      <div className={styles.carouselWrapper}>
        <Carousel
          overflow={isMinWidthArcBreakpointL ? "hidden" : "visible"}
          itemsPerSlide={isMinWidthArcBreakpointL ? 3 : 1}
          itemsToScroll={isMinWidthArcBreakpointL ? 3 : 1}
          behavior={isMinWidthArcBreakpointL ? "default" : "adaptive"}
          withGutter={isMinWidthArcBreakpointL ? true : false}
        >
          {cards.map((card, i) => (
            <div
              key={`${componentId}`}
              className={classNames(
                styles.carouselSlide,
                styles.cardWrapperCarousel,
                {
                  [styles.lastCard]: i === cards.length - 1,
                },
              )}
            >
              <MediaCard
                isContained={cardsContained}
                minHeight={minimumHeight}
                {...card}
              />
            </div>
          ))}
        </Carousel>
      </div>
    </div>
  );
};

export interface ArticleCarouselProps extends SectionHeadingProps {
  /**
   * Cards object of MediaCards for Carousel to display.
   */
  cards: MediaCardProps[];
  /**
   * Determine if MediaCards are displayed in their contained or uncontained styles.
   */
  cardsContained?: boolean;
  /**
   * Determine minimum height of cards per breakpoint.
   */
  minHeights?: {
    xxl?: number;
    xl?: number;
    l?: number;
    m?: number;
    s?: number;
    xs?: number;
  };
}
