import { useEffect, useState } from 'react';

import type { LookupServiceLinks } from '~/lib/songwhipApi/types';
import type { ServiceLinkOverrideCallback } from '~/src/features/presave';
import type { SelectedPrereleaseItem } from '~/src/store/types';

import Box from '~/src/components/Box';
import { useAppConfirm } from '~/src/components/NextApp/lib/CoreUi';
import Page from '~/src/components/Page';
import PageError from '~/src/components/PageError';
import HeaderBackButton from '~/src/components/PageHeader/HeaderBackButton';
import HeaderTitle from '~/src/components/PageHeader/HeaderTitle';
import PageLoading from '~/src/components/PageLoading';
import PageMetadata from '~/src/components/PageMetadata';
import { useI18n } from '~/src/lib/i18n';
import { useAppRouter } from '~/src/lib/router2';
import { PrereleaseLookupError } from './components/PrereleaseLookupError';
import { UpgradePrereleaseContent } from './Content';
import { usePrereleaseUpgrade } from './hooks/usePrereleaseUpgrade';
import { formatErrorMessage } from './utils';

export const PrereleaseUpgradePage = ({
  prerelease,
}: {
  prerelease: SelectedPrereleaseItem;
}) => {
  const [linksOverride, setLinksOverride] = useState<LookupServiceLinks>();

  const { t, tx } = useI18n('upgradePrerelease');
  const showConfirmDialog = useAppConfirm();
  const router = useAppRouter();

  const { status, error, data, upgrade } = usePrereleaseUpgrade({ prerelease });

  useEffect(() => {
    void upgrade({ dryRun: true });
  }, [upgrade]);

  const handleLinksChange: ServiceLinkOverrideCallback = (service, link) => {
    setLinksOverride((prevLinks) => ({
      ...prevLinks,
      [service]: link,
    }));
  };

  const handleUpgrade = async () => {
    if (!data) return;

    const { warnings } = data;

    const performUpgrade = async () => {
      const isUpgraded = await upgrade({ dryRun: false, linksOverride });

      if (isUpgraded) {
        await router.replace(prerelease.pagePath);
      }
    };

    if (warnings?.length > 0) {
      await showConfirmDialog({
        content: tx('upgradeWithErrors', { br: <br /> }),
        actionText: t('upgradeAnyway'),
        isDanger: false,
        onConfirm: () => {
          void performUpgrade();
        },
      });
    } else {
      await showConfirmDialog({
        content: t('upgradeWarning'),
        actionText: t('confirmUpgrade'),
        onConfirm: () => {
          void void performUpgrade();
        },
      });
    }
  };

  const renderContent = () => {
    // Note that the dry-run upgrade request only throws for certain errors,
    // validation errors are returned in the response object.
    // If the live album can't be found or the prerelease is not properly configured,
    // show the lookup error component which allows
    // the user to modify the release details and try again.
    if (
      error &&
      (error.code === 'NO_LIVE_ALBUM_FOUND' ||
        error.code === 'LOOKUP_CONFIG_MISSING')
    ) {
      return (
        <PrereleaseLookupError
          prerelease={prerelease}
          onRelease={() => {
            void upgrade({ dryRun: true });
          }}
        />
      );
    }

    if (
      status === 'fetchingPreview' ||
      (status === 'idle' && !data && !error)
    ) {
      return <PageLoading timeout={0} text={t('presaveLoading')} />;
    }

    if (data) {
      return (
        <UpgradePrereleaseContent
          album={prerelease}
          preview={data}
          error={error}
          linksOverride={linksOverride}
          isUpgrading={status === 'upgrading'}
          onUpgrade={handleUpgrade}
          onDetailsChange={() => {
            void upgrade({ dryRun: true });
          }}
          onLinksChange={handleLinksChange}
        />
      );
    }

    return (
      <PageError
        error={{
          message: formatErrorMessage(t, error ?? { code: 'UNKNOWN_ERROR' }),
        }}
        withRefreshButton
      />
    );
  };

  return (
    <Page
      testId="upgradePrereleasePage"
      withGradient
      renderHeaderContent={() => <HeaderTitle text={t('upgradePrerelease')} />}
      renderHeaderLeft={() => (
        <HeaderBackButton
          testId="upgradeBackButton"
          onClick={() => {
            router.push(prerelease.pagePath);
          }}
        />
      )}
    >
      <Box padding="6.8rem 2rem 10rem" maxWidth={700} isCentered>
        {renderContent()}
      </Box>
      <PageMetadata title={t('upgradePrerelease')} />
    </Page>
  );
};
