import type { SelectedAnalyticsUnlockEvents } from '~/src/store/dashboard/selectors/analytics';
import type { ReactNode } from 'react';

import { ServiceTypes } from '~/lib/types';
import Box from '~/src/components/Box';
import EmailIcon from '~/src/components/Icon/EmailIcon';
import PageLoading from '~/src/components/PageLoading';
import Text from '~/src/components/Text';
import useTheme from '~/src/hooks/useTheme';
import getServiceDisplayData from '~/src/lib/getServiceDisplayData';
import { useI18n } from '~/src/lib/i18n';
import toShortNumber from '~/src/lib/utils/toShortNumber';
import HorizontalBarChart from './HorizontalBarChart';

interface ChartItem {
  color: string;
  label: ReactNode;
  detailText: string;
  total: number;
}

// Map unlock methods to service types for icons/colors
const UNLOCK_METHOD_TO_SERVICE: Record<string, ServiceTypes | 'email'> = {
  email: 'email',
  spotify: ServiceTypes.SPOTIFY,
  itunes: ServiceTypes.ITUNES,
  amazonMusic: ServiceTypes.AMAZON_MUSIC,
  deezer: ServiceTypes.DEEZER,
};

const UNLOCK_METHOD_DISPLAY = {
  email: {
    name: 'Email',
    Icon: EmailIcon,
    color: '#888',
  },
};

const UnlocksChart = ({
  data,
  totalDays,
}: {
  data?: SelectedAnalyticsUnlockEvents;
  totalDays: number;
}) => {
  const { t } = useI18n('dashboard');
  const theme = useTheme();

  const chartItems = data?.items
    .map(({ total, unlockMethod }): ChartItem | undefined => {
      const serviceType = UNLOCK_METHOD_TO_SERVICE[unlockMethod];

      let displayData;

      if (serviceType === 'email') {
        displayData = UNLOCK_METHOD_DISPLAY.email;
      } else {
        displayData = getServiceDisplayData(serviceType);
      }

      if (!displayData) {
        return;
      }

      const { Icon, name, color } = displayData;

      return {
        color,
        total,

        detailText: t('totalServiceUnlocks', {
          total,
          serviceName: name,
        }),

        label: (
          <>
            <Icon size="1.3em" isInline margin="0 0.5em 0 0" />
            <Text isInline isBold size="0.9em">
              {name}
            </Text>
          </>
        ),
      };
    })
    .filter((item: ChartItem): item is ChartItem => !!item);

  return (
    <Box testId="dashboardUnlocksChart" positionRelative>
      {(() => {
        if (!chartItems || !data) return <PageLoading />;

        return (
          <>
            <Text isBold centered size="1.5em" color={theme.textColor90}>
              {t('totalUnlocks', { total: toShortNumber(data.total) })}
            </Text>
            <Text
              size="0.9em"
              color={theme.textColor40}
              centered
              margin="0.4em 0 2em"
            >
              {t('fansUnlockedPastDays', { totalDays })}
            </Text>
            <HorizontalBarChart
              items={chartItems}
              total={data.total}
              metric="unlocks"
            />
          </>
        );
      })()}
    </Box>
  );
};

export default UnlocksChart;
