import { InView } from "react-intersection-observer";
import clsx from "clsx";
import { m } from "framer-motion";

import ArticleCard, {
  type ArticleCardVariant,
} from "@/components/article-card";
import Dropdown, { type Option } from "@/components/dropdown";
import SplitText from "@/components/split-text";
import { staggeredFadeUpVariant } from "@/helpers/animation";
import type { Article } from "@/types";

import styles from "./styles.module.scss";

interface ArticleCardsProps {
  articles: Article[];
  variant?: ArticleCardVariant;
  className?: string;
}

function ArticleCards({ articles, variant, className }: ArticleCardsProps) {
  if (!articles || articles.length < 1) return null;

  return (
    <m.div className={className}>
      {articles.map((article, index) => (
        <InView key={article.id} threshold={0.1}>
          {({ inView, ref }) => (
            <m.span
              className={styles.cardWrapper}
              ref={ref}
              variants={staggeredFadeUpVariant(0.05)}
              initial="initial"
              animate={inView ? "animate" : "initial"}
              exit="exit"
              custom={index}
            >
              <ArticleCard variant={variant} {...article} />
            </m.span>
          )}
        </InView>
      ))}
    </m.div>
  );
}

interface ArticleListProps {
  title?: string | null;
  description?: string | null;
  articles: Article[];
  variant?: ArticleCardVariant;
  filterOptions?: Option[];
  onFilterSelect?: (option: Option) => void;
  children?: React.ReactNode;
}

export default function ArticleList({
  title,
  description,
  articles,
  variant = "compact",
  filterOptions,
  onFilterSelect,
  children,
}: ArticleListProps) {
  const showDivider = title || description || children;
  const showDropdown =
    filterOptions && onFilterSelect && typeof onFilterSelect === "function";

  const postArticles = articles.filter((article) => article.type === "post");
  const newsArticles = articles.filter((article) => article.type === "news");

  return (
    <m.div className={clsx(styles.articleList, styles[variant])}>
      {(showDivider || showDropdown) && (
        <div className={styles.upper}>
          <div className={styles.filterBar}>
            {title && <SplitText className={styles.title}>{title}</SplitText>}
            {showDropdown && (
              <Dropdown options={filterOptions} onSelect={onFilterSelect} />
            )}
          </div>
          {description && <p className={styles.description}>{description}</p>}
          {children && <div className={styles.children}>{children}</div>}
        </div>
      )}
      {showDivider && <hr className={styles.divider} />}
      <ArticleCards
        className={clsx(styles.articles, styles.post)}
        articles={postArticles}
        variant={variant}
      />
      <ArticleCards
        className={clsx(styles.articles, styles.news)}
        articles={newsArticles}
        variant={variant}
      />
    </m.div>
  );
}
