import { useCallback, useMemo, useRef } from 'react';
import dynamic from 'next/dynamic';

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

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 ItemPageNav, {
  ItemPageNavProvider,
} from '~/src/components/ItemPage/components/ItemPageNav';
import {
  LoadingObserver,
  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 useSelectArtist from '~/src/hooks/useSelectArtist';
import { useI18n } from '~/src/lib/i18n';
import { ArtistPageActions } from './lib/ArtistPageActions';
import ScrollPrompt from './lib/ScrollPrompt';
import toStructuredData from './lib/toStructuredData';
import useArtistChecks from './lib/useArtistChecks';
import useArtistItemContext from './lib/useArtistItemContext';

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

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

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

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

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

const ARTIST_PAGE_SECTION_COMPONENTS = {
  [PageSectionTypes.VIDEOS]: VideosSectionDynamic,
  [PageSectionTypes.SHOWS]: ShowsSectionDynamic,
  [PageSectionTypes.MERCH]: MerchDynamic,
  [PageSectionTypes.RELEASES]: ReleasesSectionDynamic,
};

const ArtistPage: FC<{
  artistId: number;
}> = ({ artistId }) => {
  const scrollPromptApiRef = useRef<() => void>(null);
  const { t } = useI18n();
  const artist = useSelectArtist(artistId)!;
  const itemContext = useArtistItemContext({ artist });

  useArtistChecks(artist);

  return (
    <LoadingObserver>
      <ItemPageNavProvider>
        <ItemPage
          key={artistId}
          pageType={PageTypes.ARTIST}
          itemContext={itemContext}
          hasContent={!!artist.links}
          testId="artistPage"
          error={artist.error}
          withRedirectIfNeeded={true}
          pageOwnedByAccountIds={artist.ownedByAccountIds}
          isLoading={!!artist.isLoading}
          isOwned={artist.isOwned}
          pageBrand={artist.pageBrand}
          pagePath={artist.pagePath}
          // COMPLEX: <ItemPageNav> must be rendered *after* all the page sections
          // so that they can register their NavItems *before* <ItemPageNav> is
          // rendered. If not then the SSR html won't contain any nav items.
          // We have exposed this special option to ensure <itemPageNav> appears
          // in the correct order of the react component tree.
          withBeforeContentAfterMain
          trackerContext={useMemo(
            (): PageTrackerContext => ({
              artistId: artist.id,
              artistName: artist.name,
            }),
            [artist]
          )}
          header={useMemo(() => {
            return {
              height: PAGE_HEADER_HEIGHT,

              content: (
                <ItemPageHeader
                  pagePath={artist.pagePath}
                  userCanEdit={!!artist.userCanEdit}
                  renderContent={() => {
                    return <ItemPageNav />;
                  }}
                  renderActions={({ isOpen, actionButtonRef, onClose }) => {
                    return (
                      <ArtistPageActions
                        itemContext={itemContext}
                        isOpen={isOpen}
                        actionButtonRef={actionButtonRef}
                        onClose={onClose}
                      />
                    );
                  }}
                />
              ),
            };
          }, [artist])}
          content={useMemo(() => {
            return (
              <>
                <PageSections
                  items={itemContext.layout.main}
                  id=""
                  components={{
                    ...CORE_SECTION_COMPONENTS,
                    ...ARTIST_PAGE_SECTION_COMPONENTS,
                  }}
                  itemContext={itemContext}
                  withTopMargin={false}
                  groupSections={[
                    [PageSectionTypes.PAGE_TITLE, PageSectionTypes.ICON_LINKS],
                  ]}
                />
                <PageSectionElement>
                  <OrchardLegalFooterDynamic />
                </PageSectionElement>
              </>
            );
          }, [itemContext.layout.main])}
          onScroll={useCallback(() => {
            if (scrollPromptApiRef.current) {
              scrollPromptApiRef.current();
            }
          }, [])}
        >
          <>
            <ItemPageMetadata
              error={artist.error}
              pagePath={artist.pagePath}
              itemContext={itemContext!}
              isOwned={artist.isOwned}
              defaultTitle={artist.name}
              defaultDescription={
                artist.name &&
                t('item.artistPageDescription', { artistName: artist.name })
              }
              toStructuredData={(params: any) =>
                toStructuredData({
                  ...params,
                  artistName: artist.name,
                })
              }
            />
            {/* REVIEW: it might make more sense for this to be part of the layout */}
            <ScrollPrompt apiRef={scrollPromptApiRef} />
          </>
        </ItemPage>
      </ItemPageNavProvider>
    </LoadingObserver>
  );
};

export default ArtistPage;
