---
import type { ComponentInstance } from 'astro';

import SectionCard from '@/components/section-card.astro';
import Typography from '@/components/typography.astro';
import type { SectionKey } from '@/types/data';
import type { Book, FavoritesSection, Media, Person, Video } from '@/types/favorites-section';

import BookTile from './book-tile.astro';
import MediaTile from './media-tile.astro';
import PersonTile from './person-tile.astro';
import VideoTile from './video-tile.astro';

export interface Props extends FavoritesSection {}

const {
  config: { title },
  books,
  medias,
  people,
  videos,
} = Astro.props;

type Subsection = 'books' | 'medias' | 'people' | 'videos';
type SubsectionData = Book | Media | Person | Video;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- required to avoid type casting
type SubsectionComponent = (_props: { value: any }) => ComponentInstance;

interface FavoritesSubsection<T extends SubsectionData> {
  name: Subsection;
  data: T[];
  title: string;
  columnsLayout: string;
  Component: SubsectionComponent;
}

const booksSubsection: FavoritesSubsection<Book> = {
  name: 'books',
  columnsLayout: 'grid-cols-fluid200',
  Component: BookTile,
  ...books,
};

const mediasSubsection: FavoritesSubsection<Media> = {
  name: 'medias',
  columnsLayout: 'grid-cols-fluid120',
  Component: MediaTile,
  ...medias,
};

const peopleSubsection: FavoritesSubsection<Person> = {
  name: 'people',
  columnsLayout: 'grid-cols-fluid120',
  Component: PersonTile,
  ...people,
};

const videosSubsection: FavoritesSubsection<Video> = {
  name: 'videos',
  columnsLayout: 'grid-cols-fluid240',
  Component: VideoTile,
  ...videos,
};

const subsections = [booksSubsection, peopleSubsection, videosSubsection, mediasSubsection];

const section: SectionKey = 'favorites';
---

<SectionCard section={section} title={title}>
  <div class="flex flex-col gap-16">
    {
      subsections.map(({ Component, data, name, columnsLayout, title: subsectionTitle }) => (
        <div class="flex flex-col gap-6">
          <Typography variant="section-subtitle" id={`${section}-${name}-heading`}>
            {subsectionTitle}
          </Typography>
          <div class:list={['grid gap-8', columnsLayout]}>
            {data.map((value) => (
              <Component value={value} />
            ))}
          </div>
        </div>
      ))
    }
  </div>
</SectionCard>
