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

import type { PageTrackerContext } from '~/src/components/Page';
import type { SelectedPrerelease } from '~/src/store/prereleases/types';

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 {
  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 LazyComponent from '~/src/components/LazyComponent';
import { PAGE_HEADER_HEIGHT } from '~/src/components/PageHeader';
import useHash from '~/src/hooks/useHash';
import useIsLargeScreen from '~/src/hooks/useIsLargeScreen';
import useSelectArtists from '~/src/hooks/useSelectArtists';
import { useI18n } from '~/src/lib/i18n';
import { PrereleaseBanner } from './components/PrereleaseBanner';
import { PrereleasePageActions } from './components/PrereleasePageActions';
import { PRERELEASE_PAGE_SECTION_COMPONENTS } from './constants';
import { usePrereleaseItemContext } from './hooks/usePrereleaseItemContext';
import { toStructuredData } from './utils/toStructuredData';

const sectionComponents = {
  ...CORE_SECTION_COMPONENTS,
  ...PRERELEASE_PAGE_SECTION_COMPONENTS,
};

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

export interface ItemPagePrereleaseProps {
  prerelease: SelectedPrerelease;
}

export const PrereleasePage = ({
  prerelease,

  ...itemPageProps
}: ItemPagePrereleaseProps) => {
  const { t } = useI18n();

  const itemContext = usePrereleaseItemContext({ prerelease });
  const isLargeScreen = useIsLargeScreen();

  const { showArtistIds } = itemContext.config;
  const artists = useSelectArtists(showArtistIds);
  const artistNames = artists?.map(({ name }) => name).join(', ');
  const { hasHashParam, getHashParam, backToBeforeFirstHash } = useHash();
  const editDetailsHashValue = getHashParam('editDetails');
  const editDetailsDialogOpen = hasHashParam('editDetails');
  const focusOnIdentifierField = editDetailsHashValue === 'from-banner';

  return (
    <ItemPage
      testId="prereleasePage"
      pageType={PageTypes.PRERELEASE}
      key={prerelease.id}
      isOwned={prerelease.isOwned}
      isDraft={prerelease.isDraft}
      pageBrand={prerelease.pageBrand}
      pagePath={prerelease.pagePath}
      itemContext={itemContext}
      pageOwnedByAccountIds={prerelease.ownedByAccountIds}
      isLoading={false}
      hasContent={true}
      trackerContext={useMemo(
        (): PageTrackerContext => ({
          prereleaseId: prerelease.id,
          prereleaseName: prerelease.name,

          artistId: prerelease.artistId,
          artistName: prerelease.artistName,
        }),
        [prerelease]
      )}
      header={useMemo(() => {
        const bannerHeight = isLargeScreen ? '5rem' : '4.5rem';
        const banner = (
          <PrereleaseBanner prerelease={prerelease} height={bannerHeight} />
        );

        return {
          height: `calc(${PAGE_HEADER_HEIGHT} + ${
            Boolean(banner) ? bannerHeight : '0rem'
          })`,

          content: (
            <>
              {banner}
              <ItemPageHeader
                pagePath={prerelease.pagePath}
                userCanEdit={prerelease.userCanEdit}
                renderActions={({ isOpen, actionButtonRef, onClose }) => {
                  return (
                    <PrereleasePageActions
                      itemContext={itemContext}
                      isOpen={isOpen}
                      actionButtonRef={actionButtonRef}
                      onClose={onClose}
                    />
                  );
                }}
              />
            </>
          ),
        };
      }, [prerelease, isLargeScreen])}
      content={useMemo(() => {
        return (
          <>
            <PageSections
              items={itemContext.layout.main}
              id=""
              components={sectionComponents}
              itemContext={itemContext}
              withTopMargin={false}
              groupSections={[
                [PageSectionTypes.PAGE_TITLE, PageSectionTypes.ICON_LINKS],
              ]}
            />
            <PageSectionElement>
              <OrchardLegalFooterDynamic />
            </PageSectionElement>
          </>
        );
      }, [prerelease])}
      {...itemPageProps}
    >
      <ItemPageMetadata
        error={undefined}
        pagePath={prerelease.pagePath}
        isOwned={prerelease.isOwned}
        itemContext={itemContext}
        defaultTitle={
          prerelease.name &&
          t('item.albumPageMetaTitle', {
            albumName: prerelease.name,
            artistNames: artistNames ?? '?',
          })
        }
        defaultDescription={
          prerelease.name &&
          t('item.albumPageMetaDescription', {
            albumName: prerelease.name,
            artistNames: 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) => {
          return toStructuredData({
            ...params,
            albumName: prerelease.name,
            artistName: prerelease.artistName,
            artistPagePath: prerelease.artistPagePath,
            // TODO: add artist image (need resolving to full url)
            artistImageUrl: undefined,
          });
        }}
      />
      {editDetailsDialogOpen && (
        <LazyComponent
          // NOTE: webpack chunk name used to target script request in cypress
          loader={() =>
            import(
              /* webpackChunkName: "EditDetailsDialog" */ './components/EditDetailsDialog'
            )
          }
          onClose={backToBeforeFirstHash}
          prerelease={prerelease}
          focusOnField={
            focusOnIdentifierField ? 'releaseIdentifier' : undefined
          }
        />
      )}
    </ItemPage>
  );
};
