import React from 'react';
import { twMerge } from 'tailwind-merge';
import { SetOptional } from 'type-fest';

import DiscoverCarousel, {
  DiscoverCarouselProps,
} from '@/components/carousel/carousels/DiscoverCarousel';
import FeedItemList, {
  FeedItemListProps,
} from '@/components/feed/FeedItemList';
import TrendingFeedItemList from '@/components/feed/TrendingFeedItemList';
import { components } from '@/lib/gen';

type FeaturedFeedSchema = components['schemas']['FeaturedFeedSchema'];

export type Props = Omit<
  React.HTMLAttributes<HTMLDivElement>,
  keyof DiscoverCarouselProps<FeaturedFeedSchema>
> &
  SetOptional<DiscoverCarouselProps<FeaturedFeedSchema>, 'renderItem'> & {
    feedItemLists: FeaturedFeedSchema[];
  };

const LIST_ITEM_COMPONENT: Record<string, React.FC<FeedItemListProps>> = {
  featured_feed_trending: TrendingFeedItemList,
};

const defaultRenderItem: NonNullable<Props['renderItem']> = ({
  item,
  index,
  ...restProps
}) => {
  const Component = LIST_ITEM_COMPONENT[item.id || ''] || FeedItemList;
  const slicedFeedItems = (item.items || [])
    .filter(
      (item) =>
        item.entity_type !== 'following_feed_item_schema' ||
        (item.entity_type === 'following_feed_item_schema' &&
          ['publish_song', 'suggest_creator'].includes(item.activity_type))
    )
    .slice(0, 5);
  // hide the link if there are no songs in the following feed
  const shouldShowLink =
    item.id !== 'featured_feed_following' ||
    (item.id === 'featured_feed_following' &&
      slicedFeedItems.filter(
        (item) =>
          item.entity_type === 'following_feed_item_schema' &&
          item.activity_type === 'publish_song'
      ).length > 0);

  // always show the featured_feed because you can change the filters to get results
  return slicedFeedItems.length > 0 || item.id === 'featured_feed_trending' ? (
    <Component
      key={item.id}
      id={item.id ?? ''}
      feedItems={slicedFeedItems}
      title={item.title ?? ''}
      link={shouldShowLink ? item.link : undefined}
      index={index}
      {...restProps}
    />
  ) : null;
};

const FeaturedFeed: React.FC<Props> = (props) => {
  const { className, feedItemLists, ...restProps } = props;

  return (
    <DiscoverCarousel
      className={twMerge('mt-4 pb-4', className)}
      itemsContainerClassName='grid grid-flow-col grid-cols-[repeat(var(--carousel-columns),var(--carousel-column-width))] gap-(--carousel-gap)'
      items={feedItemLists}
      renderItem={defaultRenderItem}
      style={
        {
          '--carousel-columns': Math.max(1, feedItemLists.length),
          '--carousel-gap': '1.5rem', // `gap-6`
          '--carousel-column-width': `clamp(${[
            // minimum: fixed width or viewport-based minimum
            'min(22rem, calc(100vw - 2rem))',
            // attempt to divide into equal columns
            'calc((100% - (var(--carousel-columns) - 1) * var(--carousel-gap)) / var(--carousel-columns))',
            // max: static limit
            '40rem',
          ].join(', ')})`,
        } as React.CSSProperties
      }
      {...restProps}
    />
  );
};

export default FeaturedFeed;
