import { memo } from 'react';

import type { I18nFormatter } from '~/src/lib/i18n';
import type { MappedUserPage } from '~/src/lib/songwhipApi/users/types';
import type { ReactNode } from 'react';

import { ItemTypes } from '~/lib/types';
import Box from '~/src/components/Box';
import WarningIcon from '~/src/components/Icon/WarningIcon';
import { useAppToast } from '~/src/components/NextApp/lib/CoreUi';
import Text from '~/src/components/Text';
import { useCopyPageLink } from '~/src/hooks/useCopyPageLink';
import useTheme from '~/src/hooks/useTheme';
import { useI18n } from '~/src/lib/i18n';
import formatDate from '~/src/lib/utils/formatDate';
import { concat } from '~/src/lib/utils/string';
import { CatalogItem } from '../../components';
import { formatTimestamp, getItemTypeLabelKey } from '../utils';

const THREE_DAYS_IN_MS = 72 * 60 * 60 * 1000;

export const PageItem = memo(
  ({
    testId,
    item,
    renderActions,
  }: {
    testId?: string;
    item: MappedUserPage;
    renderActions(
      item: MappedUserPage,
      { copy }: { copy(): Promise<void> }
    ): ReactNode;
  }) => {
    const { t: appT } = useI18n('app');
    const { t } = useI18n('catalog');
    const appToast = useAppToast();
    const theme = useTheme();

    const { copyPageLink } = useCopyPageLink({
      itemId: item.id,
      type: item.type as ItemTypes,
    });

    const copyLink = async () => {
      const link = await copyPageLink();

      if (!link) return;

      appToast({
        timeoutSecs: 2,
        text: t('linkCopied', { link }),
      });
    };

    const title = (() => {
      if (item.isDraft) return item.name;

      const hasMissingServices =
        item.missingServices && item.missingServices.length > 0;

      if (item.type === ItemTypes.PRERELEASE) {
        const timeToReleaseMs = getMsToRelease(item);

        const isCloseToRelease =
          timeToReleaseMs !== undefined && timeToReleaseMs <= THREE_DAYS_IN_MS;

        const isReleaseIdentifierMissing = !item.upc && !item.isrc && !item.url;

        if (isCloseToRelease && isReleaseIdentifierMissing) {
          return (
            <Box flexRow alignCenter gap="1rem">
              <Text withEllipsis>{item.name}</Text>
              <Text title={t('missingDetails')} noFlexShrink>
                <WarningIcon
                  testId="catalogItemWarning"
                  size="1.1em"
                  color={theme.colorDanger}
                />
              </Text>
            </Box>
          );
        }

        return item.name;
      }

      // Show warning for albums with missing services
      if (item.type === ItemTypes.ALBUM && hasMissingServices) {
        return (
          <Box flexRow alignCenter gap="1rem">
            <Text withEllipsis>{item.name}</Text>
            <Text title={t('missingServices')} noFlexShrink>
              <WarningIcon
                testId="catalogItemMissingServicesWarning"
                size="1.1em"
                color={theme.colorDanger}
              />
            </Text>
          </Box>
        );
      }

      return item.name;
    })();

    const header = (() => {
      const isPrerelease = item.type === ItemTypes.PRERELEASE;
      const isCustomPage = item.type === ItemTypes.CUSTOM_PAGE;

      const status = (() => {
        if (isPrerelease || isCustomPage) {
          const color = item.isDraft ? '#d99959' : '#00aa4e';
          const status = item.isDraft ? 'draft' : 'live';

          return (
            <>
              <div
                style={{
                  width: '0.7rem',
                  height: '0.7rem',
                  borderRadius: '50%',
                  backgroundColor: color,
                }}
              />
              <Text>{t(status)}</Text>
              <span>•</span>
            </>
          );
        }
      })();

      return (
        <Box flexRow alignCenter gap="0.3rem">
          {status}
          <Text>{appT(getItemTypeLabelKey(item))}</Text>
        </Box>
      );
    })();

    return (
      <CatalogItem
        testId={testId}
        href={item.path}
        header={header}
        title={title}
        subtitle={getItemSubtitle(item, t)}
        image={item.image}
        squareImage={item.type !== ItemTypes.ARTIST}
        renderAfterOuter={() => renderActions(item, { copy: copyLink })}
      />
    );
  }
);

const getItemSubtitle = (
  item: MappedUserPage,
  t: I18nFormatter<'catalog'>
): string => {
  const formattedDate = item.updatedAtTimestamp
    ? formatTimestamp(item.updatedAtTimestamp, t)
    : undefined;

  return concat([
    item.artistName,
    item.releaseDate &&
      `Release: ${formatDate(item.releaseDate, { useUtc: true })}`,
    formattedDate && `Updated: ${formattedDate}`,
  ]);
};

const getMsToRelease = (page: MappedUserPage) => {
  if (!page.releaseDate) return;

  const releaseDate = new Date(page.releaseDate);

  // TODO: Add releaseTimezone back when backend supports it
  // if (page.releaseTimezone) {
  //   const timezoneOffset = getTimezoneOffset(releaseDate, page.releaseTimezone);
  //   releaseDate.setHours(releaseDate.getHours() + timezoneOffset);
  // }

  return releaseDate.getTime() - Date.now();
};
