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

import { IconBallFootball, IconTargetArrow } from '@material-hu/icons/tabler';
import Avatar from '@material-hu/mui/Avatar';
import DialogWrapper from '@material-hu/mui/Dialog';
import Divider from '@material-hu/mui/Divider';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';
import useMediaQuery from '@material-hu/mui/useMediaQuery';

import Dialog, {
  DialogBody,
  DialogHeader,
} from '@material-hu/components/design-system/Dialog';
import Pill from '@material-hu/components/design-system/Pills';

import { getUserStats, prodeKeys } from 'src/services/prode';
import { type RankingEntry } from 'src/types/prode';
import { useLokaliseTranslation } from 'src/utils/i18n';

import MobileDialog from './MobileDialog';
import UserStatsDialogSkeleton from './UserStatsDialogSkeleton';
import UserStatsDialogStatItem from './UserStatsDialogStatItem';

type UserStatsDialogProps = {
  open: boolean;
  onClose: () => void;
  entry: RankingEntry | null;
  competitionId: number;
};

const UserStatsDialog = ({
  open,
  onClose,
  entry,
  competitionId,
}: UserStatsDialogProps) => {
  const { t } = useLokaliseTranslation('sportsPool');
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));

  const brandColor = theme.palette.newBase?.brand[900];
  const borderDefault = theme.palette.new.border.neutral.default;

  // Preserves last non-null entry so content stays visible during close animation.
  const displayEntryRef = useRef<RankingEntry | null>(null);
  if (entry) displayEntryRef.current = entry;
  const displayEntry = displayEntryRef.current;

  const { data: stats, isFetching } = useQuery(
    prodeKeys.userStats(competitionId, displayEntry?.userId ?? 0),
    () => getUserStats(competitionId, displayEntry!.userId),
    {
      enabled: open && !!displayEntry,
      select: res => res.data,
    },
  );

  const isLoading = isFetching && !stats;
  const title = t('general:detail') as string;

  const content = (
    <Stack sx={{ gap: 2 }}>
      {isLoading ? (
        <UserStatsDialogSkeleton />
      ) : (
        <>
          <Stack sx={{ flexDirection: 'row', alignItems: 'center', gap: 1 }}>
            <Avatar
              src={displayEntry?.userAvatarUrl ?? undefined}
              sx={{ width: 40, height: 40, fontSize: 16 }}
            >
              {displayEntry?.userName?.charAt(0)}
            </Avatar>
            <Typography
              variant="globalXS"
              fontWeight="fontWeightSemiBold"
              sx={{
                flex: 1,
                overflow: 'hidden',
                textOverflow: 'ellipsis',
                whiteSpace: 'nowrap',
              }}
            >
              {displayEntry?.userName}
            </Typography>
            <Stack sx={{ flexDirection: 'row', alignItems: 'center', gap: 2 }}>
              <Pill
                hasIcon={false}
                size="small"
                label={
                  (stats?.ranking.position ?? displayEntry?.position) != null
                    ? t('ranking_page.position', {
                        position:
                          stats?.ranking.position ?? displayEntry?.position,
                      })
                    : t('ranking.no_position')
                }
                type="highlight"
              />
              <Stack sx={{ alignItems: 'flex-end' }}>
                <Typography
                  variant="globalXXS"
                  sx={{ color: theme.palette.new.text.neutral.lighter }}
                >
                  {t('ranking_page.points_header')}
                </Typography>
                <Typography
                  variant="globalL"
                  fontWeight="fontWeightSemiBold"
                  sx={{ color: brandColor }}
                >
                  {stats?.ranking.totalPoints ??
                    displayEntry?.totalPoints ??
                    '-'}
                </Typography>
              </Stack>
            </Stack>
          </Stack>

          <Divider sx={{ borderColor: borderDefault }} />

          <Stack sx={{ flexDirection: 'row', alignItems: 'center', gap: 2 }}>
            <UserStatsDialogStatItem
              icon={
                <IconBallFootball
                  size={20}
                  color={brandColor}
                />
              }
              label={t('ranking_page.results_label')}
              title={t('ranking_page.positive_title')}
              count={stats?.ranking.correctResults ?? 0}
            />
            <Divider
              orientation="vertical"
              flexItem
              sx={{ borderColor: borderDefault }}
            />
            <UserStatsDialogStatItem
              icon={
                <IconTargetArrow
                  size={20}
                  color={brandColor}
                />
              }
              label={t('ranking_page.results_label')}
              title={t('ranking_page.exact_title')}
              count={stats?.ranking.exactResults ?? 0}
            />
          </Stack>
        </>
      )}
    </Stack>
  );

  if (isMobile) {
    return (
      <MobileDialog
        open={open}
        onClose={onClose}
        title={title}
      >
        <Stack sx={{ px: 3, pb: 4 }}>{content}</Stack>
      </MobileDialog>
    );
  }

  return (
    <DialogWrapper
      open={open}
      onClose={onClose}
      maxWidth="xs"
      fullWidth
    >
      <DialogHeader
        title={title}
        onClose={onClose}
        sx={{
          pb: 1,
        }}
      />
      <DialogBody sx={{ pb: 3 }}>{content}</DialogBody>
    </DialogWrapper>
  );
};

export default UserStatsDialog;
