import { FC, useState } from 'react';
import { Helmet } from 'react-helmet-async';

import { useMutation, useQuery } from 'react-query';
import { useNavigate } from 'react-router-dom';
import { Navigate } from 'react-router-dom';

import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import useFeed from 'src/hooks/queryHooks/feed';
import useGeneralError from 'src/hooks/useGeneralError';
import useRequiredParams from 'src/hooks/useRequiredParams';
import { feedRoutes } from 'src/pages/dashboard/feed/routes';
import {
  getInsightsAudience,
  getInsightsAudienceReport,
  getInsightsSummary,
  getInsightsSummaryReport,
  getLiveStreamReport,
  getPostLiveStreamStats,
  getPostLiveStreamTimeline,
  getPostLiveStreamViewerReports,
} from 'src/services/posts';
import { AudienceTypes } from 'src/types/stream';
import { getDownloadReportName } from 'src/utils/feed';
import { downloadBlob } from 'src/utils/files';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';
import { getDownloadLiveReportName } from 'src/components/post/insights/livestream/utils';
import InsightsLayout from 'src/components/post/insights/PostInsights';

import useCanViewPostInsights from './hooks/useCanViewPostInsights';
import { feedKeys } from './queries';

const FeedPostInsights: FC = () => {
  const { id } = useRequiredParams(['id']);
  const [isDownloadingSummary, setIsDownloadingSummary] =
    useState<boolean>(false);
  const [isDownloadingAudience, setIsDownloadingAudience] =
    useState<boolean>(false);

  const { t } = useTranslation('post');
  const navigate = useNavigate();
  const { feedDetail } = useFeed();
  const postDataQuery = feedDetail(id);
  const showGeneralError = useGeneralError();
  const { enqueueSnackbar } = useHuSnackbar();

  const user = postDataQuery?.data?.data?.user;

  const showInsights = useCanViewPostInsights(user?.id);

  const insightSummaryQuery = useQuery(
    feedKeys.insights.summary(id),
    () => getInsightsSummary(Number(id)),
    {
      onError: err => {
        showGeneralError(err, t('error_loading_insights_summary'));
      },
      enabled: !!id,
    },
  );

  const {
    mutate: downloadLiveStreamReport,
    isLoading: isDownloadingLiveStreamReport,
  } = useMutation(
    async () => {
      const { data: reportData } = await getLiveStreamReport(id);
      downloadBlob(
        reportData,
        getDownloadLiveReportName(
          postDataQuery.data?.data?.createdAt.toString() ?? '',
          id,
        ),
      );
    },
    {
      onError: () => {
        showGeneralError({
          title: t('live_stream_metrics_download_error'),
        });
      },
    },
  );

  if (user && !showInsights) {
    return (
      <Navigate
        to="/"
        replace
      />
    );
  }

  const handleDownloadSummary = async () => {
    try {
      setIsDownloadingSummary(true);

      const { data: reportData } = await getInsightsSummaryReport(Number(id));
      downloadBlob(
        reportData,
        getDownloadReportName(t('summary').toLowerCase()),
      );

      enqueueSnackbar({
        title: t('success_download_summary'),
        variant: 'success',
      });
    } catch (err) {
      enqueueSnackbar({
        title: t('error_download_summary'),
        variant: 'error',
      });
    } finally {
      setIsDownloadingSummary(false);
    }
  };

  const handleDownloadAudience = async () => {
    try {
      setIsDownloadingAudience(true);

      const { data: reportData } = await getInsightsAudienceReport(Number(id));
      downloadBlob(
        reportData,
        getDownloadReportName(t('post:audience_web').toLowerCase()),
      );

      enqueueSnackbar({
        title: t('success_download_audience'),
        variant: 'success',
      });
    } catch (err) {
      enqueueSnackbar({
        title: t('error_download_audience'),
        variant: 'error',
      });
    } finally {
      setIsDownloadingAudience(false);
    }
  };

  return (
    <>
      <Helmet>
        <title>{formatTitle(t('INSIGHTS'))}</title>
      </Helmet>
      <InsightsLayout
        onClose={() => navigate(feedRoutes.feed())}
        onGoToPostDetail={feedRoutes.post.detail(id)}
        postDataQuery={postDataQuery}
        summaryProps={{
          insightSummaryQuery,
          downloadProps: {
            onDownloadSummary: handleDownloadSummary,
            isDownloadingSummary: isDownloadingSummary,
          },
        }}
        audienceProps={{
          serviceProps: {
            service: (...args) => getInsightsAudience(Number(id), ...args),
            key: (...args) => feedKeys.insights.audience(id, ...args),
          },
          downloadProps: {
            onDownload: handleDownloadAudience,
            isDownloading: isDownloadingAudience,
          },
        }}
        liveStreamProps={{
          timeline: {
            service: () => getPostLiveStreamTimeline(id),
            keys: feedKeys.insights.liveStreamTimeline(id),
          },
          stats: {
            service: () => getPostLiveStreamStats(id),
            keys: feedKeys.insights.liveStreamStats(id),
          },
          viewerReports: {
            service: ({ q, limit, cursor, audienceType }) =>
              getPostLiveStreamViewerReports({
                id,
                q,
                limit,
                cursor,
                audienceType,
              }),
            keys: (type: AudienceTypes, query: string) =>
              feedKeys.insights.liveStreamViewerReports(id, type, query),
          },
          download: {
            onDownload: downloadLiveStreamReport,
            isDownloading: isDownloadingLiveStreamReport,
          },
        }}
      />
    </>
  );
};

export default FeedPostInsights;
