import type { ToActionItems } from '~/src/components/ItemPage/components/ItemPageActions/ActionsDialog';
import type { FC, RefObject } from 'react';
import type { PrereleaseItemContext } from '../hooks/usePrereleaseItemContext';

import { ItemTypes } from '~/lib/types';
import ItemPageActions from '~/src/components/ItemPage/components/ItemPageActions';
import useUnpublishLivePage from '~/src/components/ItemPage/hooks/useUnpublishLivePage';
import { toShareUrl } from '~/src/components/ItemPage/utils';
import {
  useAppConfirm,
  useAppToast,
} from '~/src/components/NextApp/lib/CoreUi';
import useHash from '~/src/hooks/useHash';
import useSelectArtists from '~/src/hooks/useSelectArtists';
import { toPublicEndpoint } from '~/src/lib/getPublicEndpoint';
import { useI18n } from '~/src/lib/i18n';
import { useAppRouter } from '~/src/lib/router2';
import { archivePrereleaseAction } from '~/src/store/prereleases/actions/archive';
import { useDispatch } from '~/src/store/redux';

export const PrereleasePageActions: FC<{
  itemContext: PrereleaseItemContext;
  isOpen: boolean;
  actionButtonRef: RefObject<HTMLElement | null>;
  onClose: () => void;
}> = ({ itemContext, isOpen, actionButtonRef, onClose }) => {
  const showConfirmDialog = useAppConfirm();
  const { showArtistIds, hasArtistActions } = itemContext.config;
  const artists = useSelectArtists(showArtistIds);
  const artistNames = artists?.map(({ name }) => name).join(', ');
  const { setHashParam } = useHash();
  const unpublishPage = useUnpublishLivePage(ItemTypes.PRERELEASE);
  const router = useAppRouter();
  const prerelease = itemContext.data.item;
  const dispatch = useDispatch();
  const showToast = useAppToast();
  const { t } = useI18n();

  const shareUrl = toShareUrl({
    isOwned: prerelease.isOwned,
    isDraft: prerelease.isDraft,
    pageBrand: prerelease.pageBrand,
  });

  const shareText = prerelease.name && `"${prerelease.name}" by ${artistNames}`;

  const createPageActions: ToActionItems = ({ sections: defaultSections }) => {
    const sections = [...defaultSections];

    if (prerelease.userCanEdit) {
      // Prerelease pages have an "Edit details" action that shows a dialog where
      // (non-orchard) owners can change the name, upc and releaseDate. If the page
      // is in 'live' state it can also be unpublished to revert it back to draft.
      sections[0].push({
        content: t('item.actions.editAlbumDetails'),
        testId: 'editDetails',
        icon: 'info',

        onClick: () => {
          setHashParam({ editDetails: '' });
        },
      });

      // don't allow upgrade and unpublish of draft pages
      if (!prerelease.isDraft) {
        sections[0].push({
          content: t('item.actions.upgradePrerelease'),
          href: `${prerelease.pagePath}/upgrade`,
          testId: 'upgradePrerelease',
          icon: 'publish',
        });

        sections[sections.length - 1].push({
          testId: 'unpublishPage',
          content: t('item.actions.unpublishPage'),
          icon: 'unpublish',
          onClick: () => {
            unpublishPage({
              itemId: prerelease.id,
              itemName: prerelease.name,
              pagePath: prerelease.pagePath,
            });
          },
        });
      }

      sections[0].push({
        testId: 'viewInDashboard',
        content: t('item.actions.viewInDashboard'),
        href: `/dashboard/prerelease/${prerelease.id}`,
        icon: 'chart',
      });

      sections.push([
        {
          content: t('item.actions.archivePage'),
          testId: 'archivePage',
          icon: 'archive',

          onClick: () => {
            showConfirmDialog({
              content: prerelease.isDraft
                ? t('item.actions.archiveDraftPageConfirm')
                : t('item.actions.archiveLivePageConfirm'),
              actionText: t('item.actions.archive'),
              cancelText: t('app.actions.cancel'),

              onConfirm: async () => {
                // TODO: During the archive event we also dispatch a delete action to remove the prerelease from the store.
                // This causes a brief flash of the 404 page, before we redirect to home.
                await dispatch(archivePrereleaseAction({ id: prerelease.id }));

                showToast({
                  text: t('item.events.pageArchived'),
                });

                router.push('/catalog');
              },
            });
          },
        },
      ]);

      return sections;
    }

    const artistsToShow = hasArtistActions
      ? artists?.filter(({ deleted }) => !deleted)
      : undefined;

    if (artistsToShow?.length) {
      sections.push(
        artistsToShow.map(({ name, pagePath }) => ({
          content: name,
          href: toPublicEndpoint(pagePath),
          icon: 'person',
        }))
      );
    }

    return sections;
  };

  return (
    <ItemPageActions
      isOpen={isOpen}
      item={prerelease}
      targetElRef={actionButtonRef}
      onClose={onClose}
      userCanEdit={prerelease.userCanEdit}
      pagePath={prerelease.pagePath}
      shareUrl={shareUrl}
      shareText={shareText}
      toActionItems={createPageActions}
    />
  );
};
