import { FC, RefObject, useState } from 'react';
import { useQuery } from 'react-query';

import { AxiosError } from 'axios';
import {
  IconDownload,
  IconHourglassEmpty,
  IconInfoCircle,
} from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';

import { useAuth } from 'src/contexts/JWTContext';
import useGeneralError from 'src/hooks/useGeneralError';
import { ResponseError } from 'src/types/services';
import { LiveStreamInsights, ResponseErrorCodes } from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getCurrentLocale } from 'src/utils/locale';

import AudienceTable from './AudienceTable';
import EmptyState from './EmptyState';
import PlatformChart from './PlatformChart';
import Summary from './Summary';

type LivestreamInsightsProps = {
  insights: LiveStreamInsights;
  summaryRef?: RefObject<HTMLDivElement>;
  audienceRef?: RefObject<HTMLDivElement>;
  audiencePerMinuteRef?: RefObject<HTMLDivElement>;
  platformsRef?: RefObject<HTMLDivElement>;
};

const LivestreamInsights: FC<LivestreamInsightsProps> = ({
  insights,
  summaryRef,
  audienceRef,
  platformsRef,
}) => {
  const { t } = useLokaliseTranslation('livestream');
  const { user } = useAuth();
  const [isReportUnavailable, setIsReportUnavailable] = useState(false);
  const showGeneralError = useGeneralError();

  const currentLocale = getCurrentLocale(user);

  const { data: stats, isLoading: isLoadingStats } = useQuery(
    insights.stats.keys,
    insights.stats.service,
    {
      onError: (err: AxiosError<ResponseError>) => {
        const { code } = err.response?.data || {};
        if (code === ResponseErrorCodes.LIVE_STREAM_STATS_NOT_READY) {
          setIsReportUnavailable(true);
        } else {
          showGeneralError(err, t('ERROR_LOADING_STATS'));
        }
      },
    },
  );

  if (isReportUnavailable) {
    return (
      <EmptyState
        Icon={IconHourglassEmpty}
        title={t('EMPTY_STATE_TITLE')}
        description={t('EMPTY_STATE_DESCRIPTION')}
      />
    );
  }

  const {
    averageViewingTimeSeconds,
    endedAt,
    maximumConcurrentViewers,
    startedAt,
    totalViewers,
    viewers,
    totalUniqueViewers,
  } = stats?.data || {};

  const hasViewers = typeof totalViewers === 'number' && totalViewers > 0;

  return (
    <Stack sx={{ gap: 4, pb: 7 }}>
      <Stack
        sx={{
          flexDirection: 'row',
          justifyContent: 'space-between',
          alignItems: 'center',
        }}
      >
        <Stack>
          <Typography
            variant="globalL"
            fontWeight="fontWeightSemiBold"
          >
            {t('general:liveStream')}
          </Typography>
          <Typography variant="globalS">{t('LIVE_STREAM_METRICS')}</Typography>
        </Stack>
        <Button
          variant="secondary"
          size="small"
          endIcon={<IconDownload />}
          onClick={insights.download.onDownload}
          disabled={insights.download.isDownloading}
          sx={{ display: 'none' }}
        >
          {t('LIVE_STREAM_METRICS_DOWNLOAD')}
        </Button>
      </Stack>
      <Summary
        ref={summaryRef}
        currentLocale={currentLocale}
        isLoadingStats={isLoadingStats}
        summary={{
          averageViewingTimeSeconds,
          endedAt,
          maximumConcurrentViewers,
          startedAt,
          totalViewers,
          totalUniqueViewers,
        }}
      />
      {!hasViewers && !isLoadingStats && (
        <EmptyState
          Icon={IconInfoCircle}
          title={t('NO_VIEWERS_TITLE')}
          description={t('NO_VIEWERS_DESCRIPTION')}
        />
      )}
      {(hasViewers || isLoadingStats) && (
        <>
          <AudienceTable
            ref={audienceRef}
            insights={insights}
            currentLocale={currentLocale}
          />
          <PlatformChart
            ref={platformsRef}
            isLoadingStats={isLoadingStats}
            platformData={{ viewers, totalViewers }}
          />
        </>
      )}
    </Stack>
  );
};

export default LivestreamInsights;
