import { useCallback } from 'react';

import type { SelectedAnalyticsCountries } from '~/src/store/dashboard/selectors/analytics';

import Box from '~/src/components/Box';
import CountryFlag from '~/src/components/CountryFlag';
import PageLoading from '~/src/components/PageLoading';
import Text from '~/src/components/Text';
import useTheme from '~/src/hooks/useTheme';
import { useI18n } from '~/src/lib/i18n';
import { getCountryName } from '~/src/lib/utils/countriesByCode';
import HorizontalBarChart from './HorizontalBarChart';

const CountriesChart = ({ data }: { data?: SelectedAnalyticsCountries }) => {
  const { t } = useI18n('dashboard');
  const theme = useTheme();

  /**
   * If there are different unsuported country codes we display multiple
   * "unknown" items in the list.
   * This function groups items by country name and sums their totals to avoid duplication.
   */
  const groupUnknownCountry = useCallback(
    (items: { total: number; country: string }[]) => {
      return Object.values(
        items.reduce(
          (acc, { total, country }) => {
            const unknownCountry = t('labels.unknown');
            const countryName = getCountryName(country) || unknownCountry;

            /**
             * "unknown" is not a valid country code in country-emoji lib,
             * so it always returns the globe emoji.
             * This fixes cases where countries-list doesn't find country name
             * but country-emoji finds the flag (e.g. "UK" displays United Kingdom flag
             * but "unknown" country name).
             */
            const countryCode =
              countryName === unknownCountry ? 'unknown' : country;

            if (!acc[countryName]) {
              acc[countryName] = { countryName, countryCode, total: 0 };
            }

            acc[countryName].total += total;

            return acc;
          },
          {} as { total: number; countryName: string; countryCode: string }[]
        )
      )
        .sort((a, b) => b.total - a.total)
        .map(({ total, countryName, countryCode }) => {
          return {
            detailText: t('totalVisitsFrom', {
              total,
              source: countryName,
            }),
            label: (
              <>
                <CountryFlag
                  countryCode={countryCode}
                  margin="0 10 0 0"
                  size="1.3em"
                />
                <Text isInline isBold size="0.9em">
                  {countryName}
                </Text>
              </>
            ),
            total,
          };
        });
    },
    []
  );

  return (
    <Box testId="dashboardCountriesChart" positionRelative>
      {(() => {
        if (!data?.items) return <PageLoading />;

        return (
          <>
            <Text isBold centered size="1.5em" color={theme.textColor90}>
              {t('visitorCountries')}
            </Text>
            <Text
              size="0.9em"
              color={theme.textColor40}
              centered
              margin="0.4em 0 2em"
            >
              {t('visitorCountriesHelp')}
            </Text>
            <HorizontalBarChart
              items={groupUnknownCountry(data.items)}
              total={data.total}
            />
          </>
        );
      })()}
    </Box>
  );
};

export default CountriesChart;
