'use client';

import { useQuery } from '@tanstack/react-query';
import { observer } from 'mobx-react-lite';
import { memo, useMemo } from 'react';
import React from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import {
  FeedSkeleton,
  RowSkeleton,
} from '@/components/carousel/carousels/SkeletonCarousel';
import SongList from '@/components/song/Songlist';
import usePageViewLog from '@/hooks/usePageViewLog';
import { useApiClient } from '@/lib/apiClient';
import { components } from '@/lib/gen';
import { ContextType } from '@/logging/contextTypes';
import { Clip } from '@/state/clipStore';
import { DiscoverSection } from '@/state/discoverStore';

const getPrimarySection = (
  sections: DiscoverSection[] | undefined,
  clipsStoreUpdate: (clips: Clip[]) => void
) => {
  if (!sections || sections.length === 0) {
    return undefined;
  }

  const clipsToUpdate: Clip[] = [];

  sections.forEach((section) => {
    if (section.section_type === 'playlist') {
      clipsToUpdate.push(...section.items);
    } else if (section.section_type === 'featured_feed') {
      section.items?.forEach((feedSection) => {
        if (!feedSection?.items) return;

        feedSection.items.forEach((item) => {
          if (!item) return;

          if (item.entity_type === 'song_schema') {
            clipsToUpdate.push(item);
          } else if (
            item.entity_type === 'following_feed_item_schema' &&
            item.activity_type === 'publish_song' &&
            item.clip_schema
          ) {
            clipsToUpdate.push(item.clip_schema);
          }
        });
      });
    }
  });

  if (clipsToUpdate.length) {
    clipsStoreUpdate(clipsToUpdate);
  }

  return sections[0];
};

const SECTION_SONG_LIMIT = 50;

const ExploreSongList = memo(
  function ExploreSongList({
    section,
    contextId,
  }: {
    section: DiscoverSection;
    contextId: string;
  }) {
    const songs = useMemo(
      () => ((section.items ?? []) as Clip[]).slice(0, SECTION_SONG_LIMIT),
      [section.items]
    );

    return (
      <SongList
        songs={songs}
        playlistId={contextId}
        contextId={contextId}
        contextType={ContextType.FeaturedFeed}
        enableInfiniteScroll={false}
        songRowProps={{
          showStats: true,
          showUser: true,
          trendingMode: true,
          showModelTagOnly: true,
        }}
      />
    );
  },
  (prevProps, nextProps) => prevProps.section === nextProps.section
);

const ExplorePageClient = observer(() => {
  usePageViewLog({ actionName: 'PageViewed', componentContext: 'discover' });

  const apiClient = useApiClient();
  const { clips: clipsStore } = useStores();

  // Fetch Newest feed
  const newestQuery = useQuery({
    queryKey: ['explore', 'newest'],
    queryFn: async () => {
      const response = await apiClient.POST('/api/discover', {
        body: {
          start_index: undefined,
          page_size: 1,
          section_name: 'new_songs_playlist',
          section_content: null,
          secondary_section_content: null,
          product: null,
        },
      });

      const data = response.data as
        | components['schemas']['DiscoverResp']
        | undefined;
      return getPrimarySection(
        data?.sections as DiscoverSection[] | undefined,
        clipsStore.updateClips
      );
    },
    staleTime: 5 * 60000, // 5 minutes
  });

  // Fetch Trending feed
  const trendingQuery = useQuery({
    queryKey: ['explore', 'trending'],
    queryFn: async () => {
      const response = await apiClient.POST('/api/discover', {
        body: {
          start_index: undefined,
          page_size: 1,
          section_name: 'trending_songs',
          section_content: null,
          secondary_section_content: null,
          product: null,
        },
      });

      const data = response.data as
        | components['schemas']['DiscoverResp']
        | undefined;
      return getPrimarySection(
        data?.sections as DiscoverSection[] | undefined,
        clipsStore.updateClips
      );
    },
    staleTime: 5 * 60000, // 5 minutes
  });

  const newestSongs = useMemo(() => {
    if (!newestQuery.data) return undefined;
    return {
      ...newestQuery.data,
      id: 'explore_newest',
      title: '',
    } as DiscoverSection;
  }, [newestQuery.data]);

  const trendingSongs = useMemo(() => {
    if (!trendingQuery.data) return undefined;
    return {
      ...trendingQuery.data,
      id: 'explore_trending',
      title: '',
    } as DiscoverSection;
  }, [trendingQuery.data]);

  const isLoading = newestQuery.isLoading || trendingQuery.isLoading;

  return (
    <div className='relative flex h-screen w-full flex-col overflow-y-auto bg-background-primary'>
      {/* Search Bar */}
      <div className='flex items-center justify-center border-b border-border-primary px-6 py-6'>
        <input
          type='search'
          inputMode='search'
          placeholder='add a preference…'
          className='w-full max-w-2xl rounded-full bg-background-secondary px-6 py-3 text-center text-sm text-foreground-primary placeholder:text-foreground-tertiary focus:outline-none'
          aria-label='Add a preference'
        />
      </div>

      {/* Main Content */}
      <main className='flex flex-1 px-6 py-8'>
        {isLoading ? (
          <div className='flex w-full gap-8'>
            <div className='flex-1'>
              <FeedSkeleton />
            </div>
            <div className='flex-1'>
              <RowSkeleton />
            </div>
          </div>
        ) : newestSongs || trendingSongs ? (
          <div className='flex w-full gap-8'>
            {/* Newest Column */}
            <section
              aria-labelledby='newest-heading'
              className='flex flex-1 flex-col gap-6'
            >
              <h2
                id='newest-heading'
                className='text-xl font-semibold text-foreground-primary'
              >
                Newest
              </h2>
              {newestSongs ? (
                <ExploreSongList
                  section={newestSongs}
                  contextId='explore_newest'
                />
              ) : (
                <div className='rounded-lg bg-background-secondary/40 p-6 text-sm text-foreground-secondary'>
                  No newest feed available.
                </div>
              )}
            </section>

            {/* Trending Column */}
            <section
              aria-labelledby='trending-heading'
              className='flex flex-1 flex-col gap-6'
            >
              <div className='flex items-center gap-3'>
                <h2
                  id='trending-heading'
                  className='text-xl font-semibold text-foreground-primary'
                >
                  Trending
                </h2>
                <button
                  type='button'
                  className='rounded-full bg-background-secondary px-3 py-1 text-xs text-foreground-secondary'
                >
                  Now
                </button>
              </div>
              {trendingSongs ? (
                <ExploreSongList
                  section={trendingSongs}
                  contextId='explore_trending'
                />
              ) : (
                <div className='rounded-lg bg-background-secondary/40 p-6 text-sm text-foreground-secondary'>
                  No trending feed available.
                </div>
              )}
            </section>
          </div>
        ) : (
          <div className='flex flex-1 flex-col items-center justify-center gap-3 text-center'>
            <p className='text-lg font-semibold text-foreground-primary'>
              No sections available
            </p>
            <p className='max-w-sm text-sm text-foreground-secondary'>
              Configure backend sections to populate feeds.
            </p>
          </div>
        )}
      </main>
    </div>
  );
});

ExplorePageClient.displayName = 'ExplorePageClient';

export default ExplorePageClient;
