import { useMemo } from 'react';
import dynamic from 'next/dynamic';

import type { PageTrackerContext } from '~/src/components/Page';

import { PageTypes } from '~/lib/types';
import ItemPage from '~/src/components/ItemPage';
import ItemPageHeader from '~/src/components/ItemPage/components/ItemPageHeader';
import ItemPageMetadata from '~/src/components/ItemPage/components/ItemPageMetadata';
import { toObservedLoadingComponent } from '~/src/components/ItemPage/components/LoadingObserver';
import {
  PageSectionElement,
  PageSections,
} from '~/src/components/ItemPage/components/SectionRenderer';
import { CORE_SECTION_COMPONENTS } from '~/src/components/ItemPage/constants';
import { PageSectionTypes } from '~/src/components/ItemPage/sections/types';
import { PAGE_HEADER_HEIGHT } from '~/src/components/PageHeader';
import useSelectArtists from '~/src/hooks/useSelectArtists';
import useSelectTrack from '~/src/hooks/useSelectTrack';
import { useI18n } from '~/src/lib/i18n';
import { TrackPageActions } from './components/TrackPageActions';
import toStructuredData from './toStructuredData';
import useTrackChecks from './useTrackChecks';
import useTrackItemContext from './useTrackItemContext';

const OrchardLegalFooterDynamic = dynamic(
  () => import('~/src/components/ItemPage/components/OrchardLegalFooter'),
  { ssr: true }
);

const VideosSectionDynamic = dynamic(
  () => import('~/src/components/ItemPage/sections/VideosSection')
);

const MerchSectionDynamic = dynamic(
  () => import('~/src/components/ItemPage/sections/MerchSection'),
  {
    loading: toObservedLoadingComponent(),
  }
);

// REVIEW: do we have shows on a track page?
const ShowsSectionDynamic = dynamic(
  () => import('~/src/components/ItemPage/sections/ShowsSection'),
  {
    loading: toObservedLoadingComponent(),
  }
);

const PAGE_SECTION_COMPONENTS = {
  ...CORE_SECTION_COMPONENTS,

  [PageSectionTypes.VIDEOS]: VideosSectionDynamic,
  [PageSectionTypes.MERCH]: MerchSectionDynamic,
  [PageSectionTypes.SHOWS]: ShowsSectionDynamic,
};

const TrackPage = ({ trackId }: { trackId: number }) => {
  const { t } = useI18n();

  const track = useSelectTrack(trackId)!;
  const itemContext = useTrackItemContext({ track })!;
  const { showArtistIds } = itemContext!.config;
  const artists = useSelectArtists(showArtistIds);
  const artistNames = artists?.map(({ name }) => name).join(', ') ?? '-';

  useTrackChecks(track);

  return (
    <ItemPage
      key={trackId}
      pageType={PageTypes.TRACK}
      itemContext={itemContext}
      hasContent={!!track.links}
      testId="itemPageTrack"
      error={track.error}
      isLoading={!!track.isLoading}
      isOwned={track.isOwned}
      pageBrand={track.pageBrand}
      withRedirectIfNeeded
      pagePath={track.pagePath}
      pageOwnedByAccountIds={track.ownedByAccountIds}
      trackerContext={useMemo(
        (): PageTrackerContext => ({
          artistId: track.artistId,
          artistName: track.artistName,

          trackId: track.id,
          trackName: track.name,
        }),
        [track]
      )}
      header={useMemo(() => {
        return {
          height: PAGE_HEADER_HEIGHT,

          content: (
            <>
              <ItemPageHeader
                pagePath={track.pagePath}
                userCanEdit={track.userCanEdit}
                renderActions={({ isOpen, actionButtonRef, onClose }) => {
                  return (
                    <TrackPageActions
                      itemContext={itemContext}
                      isOpen={isOpen}
                      actionButtonRef={actionButtonRef}
                      onClose={onClose}
                    />
                  );
                }}
              />
            </>
          ),
        };
      }, [track])}
      content={useMemo(() => {
        return (
          <>
            <PageSections
              items={itemContext.layout.main}
              id=""
              components={PAGE_SECTION_COMPONENTS}
              itemContext={itemContext}
              withTopMargin={false}
              groupSections={[
                [PageSectionTypes.PAGE_TITLE, PageSectionTypes.ICON_LINKS],
              ]}
            />
            <PageSectionElement>
              <OrchardLegalFooterDynamic />
            </PageSectionElement>
          </>
        );
      }, [itemContext.layout.main])}
    >
      <ItemPageMetadata
        error={track.error}
        pagePath={track.pagePath}
        itemContext={itemContext}
        isOwned={track.isOwned!}
        defaultTitle={
          track.name &&
          t('item.trackPageMetaTitle', {
            trackName: track.name,
            artistNames,
          })
        }
        defaultDescription={
          track.name &&
          t('item.trackPageMetaDescription', {
            trackName: track.name,
            artistNames,
          })
        }
        // REVIEW: this could be a <StructuredData> component instead
        // of having to pass props down the tree to <PageMetaData>
        // which is getting quite overloaded now
        toStructuredData={(params) =>
          // @ts-ignore
          toStructuredData({
            ...params,
            trackName: track.name,
            artistName: track.artistName,
            artistPagePath: track.artistPagePath,
            // TODO: add artist image (need resolving to full url)
            artistImageUrl: undefined,
          })
        }
      />
    </ItemPage>
  );
};

export default TrackPage;
