// @ts-nocheck
// ^ File is legacy and gonna be removed soon.

import { useState } from 'react';
import { useQuery } from 'react-query';

import Circle from '@material-hu/icons/material/Circle';
import InfoOutlined from '@material-hu/icons/material/InfoOutlined';
import Box from '@material-hu/mui/Box';
import Breadcrumbs from '@material-hu/mui/Breadcrumbs';
import Card from '@material-hu/mui/Card';
import Chip from '@material-hu/mui/Chip';
import * as colors from '@material-hu/mui/colors';
import Link from '@material-hu/mui/Link';
import Paper from '@material-hu/mui/Paper';
import Skeleton from '@material-hu/mui/Skeleton';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';
import Tooltip from '@material-hu/mui/Tooltip';
import Typography from '@material-hu/mui/Typography';

import useResultsFilters from 'src/contexts/ManagerResultsFiltersContext';
import useSurveyId from '../hooks/useSurveyId';
import {
  getEnpsChart,
  getEnpsComparedChart,
  getEnpsScores,
  getEnpsScoresDifference,
  getManagerSurveyDetail,
} from '../services';
import {
  type EnpsScoresResponse,
  type EnpsSegment,
  type SegmentFilter,
  SegmentType,
  StatKey,
} from '../types';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { getBaseSegments } from '../constants';
import { pxKeys } from '../queries';
import { formatValueSafe } from '../utils';

import EnpsBarChart from './EnpsBarChart';
import SegmentSelect from './SegmentSelect';
import SemiCircularProgress from './SemiCircularProgress';

const EnpsSummary = () => {
  const surveyId = useSurveyId();
  const { t } = useLokaliseTranslation('people_experience');
  const { state } = useResultsFilters();
  const comparedSurvey = state.comparisionSurvey?.id;

  const items = [
    {
      id: 'promoters',
      label: t('PROMOTERS'),
      valueKey: StatKey.PROMOTERS,
      color: 'success',
    },
    {
      id: 'neutral',
      label: t('NEUTRAL'),
      valueKey: StatKey.NEUTRALS,
      color: 'warning',
    },
    {
      id: 'detractors',
      label: t('DETRACTORS'),
      valueKey: StatKey.DETRACTORS,
      color: 'error',
    },
  ] as const;

  const { data, isLoading } = useQuery(
    pxKeys.eNpsScores({ surveyId: Number(surveyId) }),
    () => getEnpsScores({ surveyId }),
    {
      select: response => response.data,
    },
  );

  const { data: scoreDiffData } = useQuery(
    pxKeys.eNpsScoresDiff(Number(surveyId), comparedSurvey),
    () => getEnpsScoresDifference(surveyId, comparedSurvey),
    {
      select: response => response.data,
      enabled: !!comparedSurvey,
    },
  );

  const scoreDifference = scoreDiffData
    ? (
        (scoreDiffData.score ?? 0) -
        (scoreDiffData.differenceStats?.[0]?.score ?? 0)
      ).toFixed(0)
    : 0;

  const scores: Partial<EnpsScoresResponse> = data ?? {
    count: 0,
    stats: {
      [StatKey.PROMOTERS]: 0,
      [StatKey.NEUTRALS]: 0,
      [StatKey.DETRACTORS]: 0,
    },
  };

  /******* eNPS *******/

  const [parentID, setParentID] = useState(0);
  const [segmentFilter, setSegmentFilter] = useState<SegmentFilter>();

  const isSegmentation =
    segmentFilter?.type === SegmentType.SEGMENTATION_GROUPS;

  const baseSegments = getBaseSegments(t);

  const [breadcrumb, setBreadcrumb] = useState<
    { label: string; value: number }[]
  >([
    {
      label: baseSegments[0].title,
      value: null,
    },
  ]);

  const [filteredBreadcrumb, setFilteredBreadcrumb] = useState<
    { label: string; value: number }[]
  >([
    {
      label: baseSegments[0].title,
      value: null,
    },
  ]);

  const handlePushFiltered = subSegment =>
    setFilteredBreadcrumb(prev => [...prev, subSegment]);

  const handlePushSegment = subSegment =>
    setBreadcrumb(prev => [...prev, subSegment]);

  const handlePopSegment = (index: number, id: number) => () => {
    if (index < filteredBreadcrumb.length - 1) {
      setBreadcrumb(prev => prev.slice(0, index + 1));
      setFilteredBreadcrumb(prev => prev.slice(0, index + 1));
      setParentID(id);
    }
  };

  const { data: npsChart, isLoading: npsLoading } = useQuery(
    pxKeys.eNpsChart({
      surveyId,
      dimension: segmentFilter?.type,
      parentId: (isSegmentation ? segmentFilter?.id : parentID) as
        | number
        | null,
    }),
    () =>
      getEnpsChart({
        surveyId,
        dimension: segmentFilter?.type,
        parentId: (isSegmentation ? segmentFilter.id : parentID) as
          | number
          | null,
      }),
    {
      select: response => response.data,
      enabled: !!segmentFilter?.id,
      onSuccess: response => {
        response.hierarchy.forEach(stat => {
          if (!breadcrumb.map(b => b.value).includes(stat.id)) {
            handlePushSegment({
              value: stat.id,
              label: stat.title,
            });
          }
        });
      },
    },
  );

  const { data: npsChartComparedData } = useQuery(
    pxKeys.eNpsChartCompared(
      Number(surveyId),
      segmentFilter?.type,
      comparedSurvey,
      isSegmentation ? segmentFilter?.id : parentID,
    ),
    () =>
      getEnpsComparedChart(
        surveyId,
        segmentFilter?.type,
        comparedSurvey,
        isSegmentation ? Number(segmentFilter.id) : parentID,
      ),
    {
      select: r => r.data,
      enabled: !!segmentFilter?.id && !!comparedSurvey,
    },
  );

  const npsDiffParents = npsChartComparedData?.hierarchy?.map(
    ({ parentId, ...rest }) => rest,
  );
  const npsDiffStats =
    npsChartComparedData && npsDiffParents
      ? npsDiffParents.concat(npsChartComparedData.stats)
      : [];

  const theme = useTheme();
  const barColor = theme.palette.new.graphics.brand[500];
  const npsParents = npsChart?.hierarchy?.map(({ parentId, ...rest }) => rest);
  const npsStats =
    npsChart && npsParents ? npsParents.concat(npsChart.stats) : [];

  const { data: surveyName } = useQuery(
    pxKeys.surveyDetail(surveyId),
    () => getManagerSurveyDetail(surveyId),
    { select: response => response.data.name },
  );

  const handleChangeSegmentFilter = (newSegment: SegmentFilter) => {
    setBreadcrumb([
      {
        label: newSegment.title,
        value: null,
      },
    ]);
    handlePopSegment(0, 0)();
    setParentID(null);
    setSegmentFilter(newSegment);
  };

  const handleDimensionClick = (title: string, parentId: number) => {
    setParentID(parentId);
    if (!parentId) {
      handlePopSegment(0, null)();
      return;
    }

    const breadcrumbIds = breadcrumb.map(d => d.value);
    if (!breadcrumbIds.includes(parentId)) {
      /* If not in list, add it */
      handlePushSegment({
        value: parentId,
        label: title,
      });
    } else {
      /* If already in list, remove all children */
      const idx = npsStats.map(c => c.id).indexOf(parentId);
      if (idx < breadcrumbIds.length - 1) {
        handlePopSegment(idx, parentId)();
      }
    }

    handlePushFiltered({ value: parentId, label: title });
  };

  /** Adjust minWidth when stats are more than threshold */
  const minWidth = npsStats.length * 150;

  const canCompare = (stat, idx) =>
    stat.passedThreshold &&
    npsDiffStats?.[idx]?.stats?.[0]?.missingComparison &&
    !!comparedSurvey;

  const canBeClicked = (stat: EnpsSegment) =>
    stat.hasChildren && !breadcrumb.map(b => b.value).includes(stat.id);

  const getColor = (stat: EnpsSegment) => {
    if (!stat.passedThreshold) return 'textSecondary';
    if (canBeClicked(stat)) return 'primary';
    return 'textPrimary';
  };

  const getChipColor = () => {
    if (
      !scores?.passedThreshold ||
      !scoreDiffData?.differenceStats?.[0]?.passedThreshold ||
      Number(scoreDifference) === 0
    )
      return 'secondary';
    if (Number(scoreDifference) < 0) return 'error';
    return 'success';
  };

  return (
    <>
      <Stack>
        <Typography variant="h6">{t('TOTES')}</Typography>
        <Tooltip
          placement="top"
          title={!scores.passedThreshold ? t('NO_DATA') : ''}
        >
          <Stack sx={{ flexDirection: 'row', gap: 2, p: 1, pb: 0, mt: 1 }}>
            <Paper
              component={Stack}
              sx={{ p: 2, alignItems: 'center', flexGrow: 0.2 }}
              elevation={2}
            >
              <SemiCircularProgress
                size={150}
                value={formatValueSafe(
                  (scores.stats.PROMOTERS - scores.stats.DETRACTORS) *
                    (100 / scores.count),
                )}
                from={-100}
                label={t('NPS_TOTAL')}
                isLoading={isLoading}
                hideValue={!scores.passedThreshold}
              />
            </Paper>
            {items.map(({ id, valueKey, label, color }) => (
              <Paper
                key={id}
                sx={{ p: 3, flex: 1, alignItems: 'center' }}
                elevation={2}
                component={Stack}
              >
                {isLoading && (
                  <Stack sx={{ gap: 2, alignItems: 'center' }}>
                    <Skeleton
                      width="80px"
                      height="20px"
                    />
                    <Skeleton
                      width="3rem"
                      height="32px"
                    />
                  </Stack>
                )}
                {!isLoading && (
                  <>
                    <Stack
                      sx={{
                        flexDirection: 'row',
                        alignItems: 'center',
                        gap: 1,
                      }}
                    >
                      <Circle
                        color={color}
                        sx={{ fontSize: '8px' }}
                      />
                      <Typography
                        sx={theme => ({
                          color: theme.palette.new.text.neutral.lighter,
                        })}
                        fontSize="14px"
                        fontWeight={500}
                      >
                        {label}
                      </Typography>
                    </Stack>
                    <Typography
                      fontSize="32px"
                      fontWeight={500}
                    >
                      {scores.passedThreshold
                        ? formatValueSafe(
                            (scores.stats[valueKey] / scores.count) * 100,
                          )
                        : '--'}
                      %
                    </Typography>
                  </>
                )}
              </Paper>
            ))}
          </Stack>
        </Tooltip>
        {!!comparedSurvey && (
          <Stack
            sx={{
              height: '50px',
              flexDirection: 'row',
              alignItems: 'center',
              backgroundColor: theme =>
                theme.palette.new.background.feedback.info,
              borderBottomRightRadius: '10px',
              borderBottomLeftRadius: '10px',
              py: 1,
              px: 2,
              gap: 1,
              mx: 1,
            }}
          >
            <InfoOutlined
              sx={theme => ({
                fontSize: '14px',
                color: theme.palette.new.icon.feedback.info,
              })}
            />
            <Typography
              variant="subtitle2"
              sx={theme => ({ color: theme.palette.new.text.feedback.info })}
            >
              {t('DIFFERENCE')}:
            </Typography>
            <Chip
              label={
                scores?.passedThreshold &&
                scoreDiffData?.differenceStats?.[0]?.passedThreshold
                  ? (Number(scoreDifference) >= 0 ? '+' : '') + scoreDifference
                  : '--'
              }
              color={getChipColor()}
              sx={{ py: 0 }}
            />
          </Stack>
        )}
      </Stack>
      <Stack sx={{ mt: 4, gap: 1 }}>
        <Stack sx={{ flexDirection: 'row', alignItems: 'center', gap: 2 }}>
          <Typography
            variant="h6"
            sx={{ ml: 2 }}
          >
            {t('ENPS_BY')}
          </Typography>
          <SegmentSelect
            disabled={isLoading}
            value={segmentFilter}
            onChange={handleChangeSegmentFilter}
            showLabel={false}
          />
        </Stack>
        <Stack sx={{ ml: 2 }}>
          {!npsLoading && filteredBreadcrumb.length > 1 && (
            <Breadcrumbs aria-label={t('BREADCRUMB_ALT') as string}>
              {filteredBreadcrumb.map(({ label, value }, index) => (
                <Link
                  key={String(value)}
                  component="button"
                  underline="hover"
                  onClick={handlePopSegment(index, value)}
                >
                  {label}
                </Link>
              ))}
            </Breadcrumbs>
          )}
        </Stack>
        <Card
          sx={{ p: 2, m: 1, pb: 0 }}
          elevation={2}
        >
          <Box sx={{ overflowX: 'auto', overflowY: 'none' }}>
            <Box sx={{ minWidth }}>
              <EnpsBarChart
                npsDiffStats={npsDiffStats}
                comparisionSurvey={state.comparisionSurvey}
                npsChart={npsChart}
                surveyName={surveyName}
              />
              <Stack
                sx={{
                  flexDirection: 'row',
                  alignItems: 'center',
                  justifyContent: 'space-between',
                  paddingLeft: 6,
                  paddingRight: 1,
                  pt: 0,
                  display: { xs: 'none', sm: 'none', md: 'flex' }, // Hide on xs, show on sm and above
                }}
              >
                {npsStats.map((stat, index) => (
                  <Stack
                    key={stat.id}
                    sx={{
                      py: 0,
                      my: 0,
                      textAlign: 'center',
                      alignItems: 'center',
                      justifyContent: 'center',
                      cursor: canBeClicked(stat) ? 'pointer' : 'default',
                      width: '100%',
                      minWidth: '100px',
                    }}
                    onClick={() =>
                      canBeClicked(stat)
                        ? handleDimensionClick(stat.title, stat.id)
                        : null
                    }
                  >
                    <Stack
                      sx={{
                        flexDirection: 'row',
                        alignItems: 'center',
                      }}
                    >
                      <Typography
                        sx={{
                          textDecoration: canBeClicked(stat)
                            ? 'underline'
                            : 'none',
                        }}
                        color={getColor(stat)}
                        variant="subtitle2"
                      >
                        {!stat.id ? t('TOTAL') : stat.title}
                      </Typography>
                      {!stat.passedThreshold && (
                        <Tooltip
                          placement="top-end"
                          title={t('NO_DATA')}
                        >
                          <InfoOutlined sx={{ fontSize: '12px', ml: '3px' }} />
                        </Tooltip>
                      )}
                      {canCompare(stat, index) && (
                        <Tooltip
                          placement="top-end"
                          title={t('NO_COMPARISON')}
                        >
                          <InfoOutlined sx={{ fontSize: '12px', ml: '3px' }} />
                        </Tooltip>
                      )}
                    </Stack>
                    <Typography
                      variant="body2"
                      sx={theme => ({
                        color: theme.palette.new.text.neutral.lighter,
                        minHeight: 32,
                      })}
                    >
                      {!stat.id ? t('GLOBAL') : stat.subtitle}
                    </Typography>
                  </Stack>
                ))}
              </Stack>
              <Stack
                sx={{
                  flexDirection: 'row',
                  alignItems: 'center',
                  justifyContent: 'space-between',
                  paddingLeft: 6,
                  paddingRight: 1,
                  pt: 0,
                  minWidth: '100px',
                }}
              >
                {npsStats.map(({ id }) => (
                  <Box
                    key={id}
                    sx={{
                      mt: '3px',
                      width: '100%',
                      height: '3px',
                      backgroundColor:
                        breadcrumb.map(b => b.value).includes(id) && id
                          ? barColor
                          : 'transparent',
                    }}
                  />
                ))}
              </Stack>
            </Box>
          </Box>
        </Card>
      </Stack>
    </>
  );
};

export default EnpsSummary;
