import { type FC } from 'react';

import { type TFunction, Trans } from 'react-i18next';
import { useQuery } from 'react-query';

import { IconArrowNarrowRight } from '@material-hu/icons/tabler';
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 from '@material-hu/components/design-system/Dialog';
import Pill from '@material-hu/components/design-system/Pills';
import Skeleton from '@material-hu/components/design-system/Skeleton';

import { getMatchBreakdown, prodeKeys } from 'src/services/prode';
import {
  type Match,
  type Prediction,
  type BreakdownReason,
} from 'src/types/prode';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { matchDetailHeaderSx, matchDetailPointsListSx } from '../constants';
import {
  formatBreakdownPoints,
  formatScorePoints,
  getScorePointsPillType,
} from '../utils';
import TeamFlag from './TeamFlag';
import MobileDialog from './MobileDialog';

type MatchDetailModalProps = {
  open: boolean;
  onClose: () => void;
  competitionId: number;
  match: Match | null;
  prediction: Prediction | null;
};

const MatchDetailModal: FC<MatchDetailModalProps> = ({
  open,
  onClose,
  competitionId,
  match,
  prediction,
}) => {
  const { t } = useLokaliseTranslation('sportsPool');
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));

  // Fetch breakdown only for finished matches with predictions
  const isFinishedWithPrediction = match?.status === 'FINISHED' && !!prediction;

  const { data: breakdownData, isLoading: isBreakdownLoading } = useQuery(
    prodeKeys.matchBreakdown(competitionId, match?.id ?? 0),
    () => getMatchBreakdown(competitionId, match!.id),
    {
      enabled: open && isFinishedWithPrediction && !!match,
      select: data => data.data,
    },
  );

  if (!match) return null;

  const homeName =
    match.homeTeam?.localizedName ??
    match.homeTeam?.name ??
    match.homeTeamPlaceholder ??
    t('matches.tbd');
  const awayName =
    match.awayTeam?.localizedName ??
    match.awayTeam?.name ??
    match.awayTeamPlaceholder ??
    t('matches.tbd');
  const isFinished = match.status === 'FINISHED';
  const isLive = match.status === 'LIVE';
  const finalScore = isFinished
    ? `${match.homeScore ?? 0} - ${match.awayScore ?? 0}`
    : isLive
      ? t('matches.live')
      : t('matches.vs');
  const predictionScore = prediction
    ? `${prediction.predictedHomeScore}-${prediction.predictedAwayScore}`
    : null;

  const pointsEarned =
    breakdownData?.totalPoints ?? prediction?.pointsEarned ?? 0;
  const breakdownItems = breakdownData?.items ?? [];

  const getBreakdownText = (reason: BreakdownReason): string => {
    return t(`prediction.breakdown.${reason}`) as string;
  };

  const title = t('prediction.detail_title') as string;

  const content = (
    <Stack sx={{ px: { xs: 3, sm: 0 }, pb: { xs: 3, sm: 0 } }}>
      {/* Match Result Header */}
      <Stack sx={matchDetailHeaderSx}>
        <Stack
          sx={{
            flexDirection: 'row',
            alignItems: 'center',
            gap: 1,
          }}
        >
          {match.homeTeam && (
            <TeamFlag
              countryCode={match.homeTeam.countryCode}
              flagUrl={match.homeTeam.flagUrl}
              name={match.homeTeam.name}
              emoji={match.homeTeam.emoji}
              size={22}
            />
          )}
          <Typography
            variant="globalM"
            fontWeight={600}
          >
            {homeName} {finalScore} {awayName}
          </Typography>
          {match.awayTeam && (
            <TeamFlag
              countryCode={match.awayTeam.countryCode}
              flagUrl={match.awayTeam.flagUrl}
              name={match.awayTeam.name}
              emoji={match.awayTeam.emoji}
              size={22}
            />
          )}
        </Stack>
      </Stack>

      {/* Prediction Row */}
      {prediction && (
        <Stack
          sx={{
            py: 2,
            gap: 2,
          }}
        >
          <Stack
            sx={{
              flexDirection: 'row',
              alignItems: 'center',
              gap: 2,
            }}
          >
            <Pill
              hasIcon={false}
              size="small"
              label={t('prediction.my_prediction', {
                score: predictionScore,
              })}
              type="neutral"
            />
            <IconArrowNarrowRight
              size={20}
              color={theme.palette.new.text.neutral.default}
            />
            <Pill
              hasIcon={false}
              size="small"
              label={t('prediction.points_earned', {
                points: formatScorePoints(pointsEarned),
              })}
              type={getScorePointsPillType(pointsEarned)}
            />
          </Stack>
          {prediction.predictedHomeScore === prediction.predictedAwayScore &&
            prediction.predictedQualifierId && (
              <Stack
                component="ul"
                sx={{ m: 0, pl: 2 }}
              >
                <Typography
                  component="li"
                  variant="globalXS"
                >
                  <Trans
                    i18nKey="matches.penalty_winner"
                    t={t as TFunction}
                    values={{
                      team:
                        prediction.predictedQualifierId === match.homeTeam?.id
                          ? (match.homeTeam?.localizedName ??
                            match.homeTeam?.name)
                          : (match.awayTeam?.localizedName ??
                            match.awayTeam?.name),
                    }}
                    components={{
                      bold: <strong />,
                    }}
                  />
                </Typography>
              </Stack>
            )}
        </Stack>
      )}

      {isFinishedWithPrediction && <Divider />}

      {/* Points Breakdown */}
      {isFinishedWithPrediction && (
        <Stack sx={matchDetailPointsListSx}>
          {isBreakdownLoading && (
            <>
              <Skeleton
                variant="text"
                width="80%"
                height={20}
              />
              <Skeleton
                variant="text"
                width="60%"
                height={20}
              />
            </>
          )}
          {!isBreakdownLoading && breakdownItems.length > 0 && (
            <Stack
              component="ul"
              sx={{ m: 0, pl: 2 }}
            >
              {breakdownItems.map((item, index) => (
                <Typography
                  key={index}
                  component="li"
                  variant="globalXS"
                >
                  {`${getBreakdownText(item.reason)}: `}
                  <Typography
                    component="span"
                    variant="globalXS"
                    fontWeight={600}
                  >
                    {`${formatBreakdownPoints(item.points, item.reason)} ${t('prediction.breakdown.point', { count: item.points })}`}
                  </Typography>
                </Typography>
              ))}
            </Stack>
          )}
          {!isBreakdownLoading && breakdownItems.length === 0 && (
            <Stack
              component="ul"
              sx={{ m: 0, pl: 2 }}
            >
              <Typography
                component="li"
                variant="globalXS"
              >
                {t('prediction.incorrect')}
              </Typography>
            </Stack>
          )}
        </Stack>
      )}
    </Stack>
  );

  if (isMobile) {
    return (
      <MobileDialog
        open={open}
        onClose={onClose}
        title={title}
      >
        {content}
      </MobileDialog>
    );
  }

  return (
    <DialogWrapper
      open={open}
      onClose={onClose}
      maxWidth="xs"
      fullWidth
      PaperProps={{
        sx: {
          maxHeight: '90vh',
          maxWidth: 600,
          width: '100%',
        },
      }}
    >
      <Dialog
        onClose={onClose}
        title={title}
        body={content}
      />
    </DialogWrapper>
  );
};

export default MatchDetailModal;
