import { Trans } from 'react-i18next';

import { IconCheck } from '@material-hu/icons/tabler';
import Divider from '@material-hu/mui/Divider';
import Stack from '@material-hu/mui/Stack';
import { type Theme, useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import CardContainer from '@material-hu/components/design-system/CardContainer';
import Box from '@material-hu/mui/Box';
import {
  type Match,
  type MatchInPrediction,
  type Prediction,
} from 'src/types/prode';
import { useLokaliseTranslation } from 'src/utils/i18n';

import {
  type MatchCardVariant,
  matchCardScoreBoxSx,
  matchCardScoreBoxWithPredictionSx,
  matchCardVariantSx,
  matchPointsPillPositiveSx,
  matchPointsPillZeroSx,
  matchPredictionBadgeStyles,
  matchPredictionPillSx,
  matchScoreContainerSx,
  matchScoreLargeSx,
} from '../constants';
import { getMatchLocalTime } from '../utils';
import TeamFlag from './TeamFlag';

type MatchCardProps = {
  match: Match | MatchInPrediction;
  prediction?: Prediction | null;
  isPredictionOpen?: boolean;
  onClick?: () => void;
};

const MatchCard = ({
  match,
  prediction,
  isPredictionOpen,
  onClick,
}: MatchCardProps) => {
  const { t } = useLokaliseTranslation('sportsPool');
  const theme = useTheme();

  const isFinished = match.status === 'FINISHED';
  const isLive = match.status === 'LIVE';
  const hasScore = match.homeScore !== null && match.awayScore !== null;
  const hasPrediction = !!prediction;
  // Check if both teams are defined (no placeholders)
  const hasBothTeams = !!match.homeTeam && !!match.awayTeam;
  const isClickable =
    hasBothTeams &&
    !!onClick &&
    !(isFinished && !hasPrediction) &&
    (isPredictionOpen || hasPrediction);

  const getCardVariant = (): MatchCardVariant => {
    if (isFinished || isLive) return 'finished';
    if (hasPrediction) return 'withPrediction';
    if (isPredictionOpen) return 'pendingPrediction';
    return 'default';
  };
  const cardVariant = getCardVariant();

  const variantSx = matchCardVariantSx[cardVariant];
  const resolvedVariantSx =
    typeof variantSx === 'function' ? variantSx(theme) : variantSx;

  // Get points earned (for finished matches)
  const pointsEarned = prediction?.pointsEarned ?? 0;
  const hasPositivePoints = pointsEarned > 0;

  // Render prediction status pills for finished/live matches
  const renderStatusPills = () => {
    if (!isFinished && !isLive) return null;
    if (isLive && !hasPrediction) return null;

    return (
      <Stack
        sx={{
          flexDirection: 'row',
          alignItems: 'center',
          justifyContent: 'center',
          gap: 1,
          mb: 1,
        }}
      >
        {/* Prediction pill */}
        <Stack sx={matchPredictionPillSx}>
          <Typography
            variant="globalXS"
            fontWeight="fontWeightSemiBold"
            sx={{ color: theme.palette.new.text.neutral.lighter }}
          >
            {hasPrediction
              ? `${t('matches.prediction_label')}: ${prediction.predictedHomeScore}-${prediction.predictedAwayScore}`
              : `${t('matches.prediction_label')}: -`}
          </Typography>
        </Stack>

        {/* Points pill — only for finished matches */}
        {isFinished && (
          <Stack
            sx={
              hasPositivePoints
                ? matchPointsPillPositiveSx
                : matchPointsPillZeroSx
            }
          >
            <Typography
              variant="globalXS"
              fontWeight="fontWeightSemiBold"
              sx={{
                color: hasPositivePoints
                  ? theme.palette.new.text.feedback.success
                  : theme.palette.new.text.feedback.warning,
              }}
            >
              {t('matches.points_label')}: +{pointsEarned}
            </Typography>
          </Stack>
        )}
      </Stack>
    );
  };

  // Render score area based on match state
  const renderScoreArea = () => {
    if (isFinished && hasScore) {
      // Finished match: show final scores with hyphen separator
      return (
        <Stack
          sx={{
            flexDirection: 'row',
            alignItems: 'center',
            gap: 1,
          }}
        >
          <Typography
            variant="globalL"
            fontWeight="fontWeightSemiBold"
            sx={matchScoreLargeSx}
          >
            {match.homeScore}
          </Typography>
          <Typography
            variant="globalXS"
            sx={{ color: theme.palette.new.text.neutral.lighter }}
          >
            -
          </Typography>
          <Typography
            variant="globalL"
            fontWeight="fontWeightSemiBold"
            sx={matchScoreLargeSx}
          >
            {match.awayScore}
          </Typography>
        </Stack>
      );
    }

    if (isLive) {
      return (
        <Typography
          variant="globalXS"
          fontWeight="fontWeightSemiBold"
          sx={{ color: theme.palette.new.text.neutral.lighter }}
        >
          {t('matches.live')}
        </Typography>
      );
    }

    if (hasPrediction && !isFinished) {
      // Upcoming with prediction: show scores in green-bordered boxes
      return (
        <Stack
          sx={{
            flexDirection: 'row',
            alignItems: 'center',
            gap: 1,
          }}
        >
          <Stack sx={matchCardScoreBoxWithPredictionSx}>
            <Typography
              variant="globalL"
              fontWeight="fontWeightSemiBold"
              sx={matchScoreLargeSx}
            >
              {prediction.predictedHomeScore}
            </Typography>
          </Stack>
          <Typography
            variant="globalXS"
            fontWeight="fontWeightSemiBold"
          >
            {getMatchLocalTime(match.matchDate, match.matchTime)}
          </Typography>
          <Stack sx={matchCardScoreBoxWithPredictionSx}>
            <Typography
              variant="globalL"
              fontWeight="fontWeightSemiBold"
              sx={matchScoreLargeSx}
            >
              {prediction.predictedAwayScore}
            </Typography>
          </Stack>
        </Stack>
      );
    }

    // Upcoming without prediction: show empty gray-bordered boxes
    const scoreBoxStyles = !isPredictionOpen
      ? (theme: Theme) => ({
          ...matchCardScoreBoxSx(theme),
          backgroundColor: theme.palette.newBase?.grey[200],
        })
      : matchCardScoreBoxSx;

    return (
      <Stack
        sx={{
          flexDirection: 'row',
          alignItems: 'center',
          gap: 1,
        }}
      >
        <Stack sx={scoreBoxStyles} />
        <Typography
          variant="globalXS"
          fontWeight="fontWeightSemiBold"
        >
          {getMatchLocalTime(match.matchDate, match.matchTime)}
        </Typography>
        <Stack sx={scoreBoxStyles} />
      </Stack>
    );
  };

  return (
    <CardContainer
      onClick={isClickable ? onClick : undefined}
      fullWidth
      sx={{
        ...resolvedVariantSx,
        position: 'relative',
        overflow: 'visible',
      }}
    >
      {/* Checkmark badge for upcoming with prediction — sits on the card border corner */}
      {hasPrediction && !isFinished && !isLive && (
        <Stack
          sx={{
            ...matchPredictionBadgeStyles,
            top: { xs: 8, md: 16 },
            right: { xs: 8, md: 24 },
            width: { xs: 16, md: 24 },
            height: { xs: 16, md: 24 },
          }}
        >
          <IconCheck
            size={16}
            color={theme.palette.new.text.feedback.success}
          />
        </Stack>
      )}

      <Stack
        sx={{
          flexDirection: 'column',
          alignItems: 'center',
          gap: 1,
        }}
      >
        {/* Status pills for finished matches */}
        {renderStatusPills()}

        {/* Main match row */}
        <Box
          sx={{
            width: '100%',
            display: 'grid',
            gridTemplateColumns: '1fr 1fr 1fr',
            gap: 2,
            pb: 3,
          }}
        >
          <Stack
            sx={{
              flexDirection: 'column',
              alignItems: 'center',
              justifyContent: 'center',
              gap: 0.5,
              position: 'relative',
            }}
          >
            <Box sx={{ position: 'relative' }}>
              <TeamFlag
                countryCode={match.homeTeam?.countryCode}
                flagUrl={match.homeTeam?.flagUrl}
                name={match.homeTeam?.name}
                emoji={match.homeTeam?.emoji}
                size={40}
              />
              <Typography
                variant="globalXXS"
                sx={{
                  position: 'absolute',
                  top: `calc(100% + 4px)`,
                  left: '50%',
                  transform: 'translateX(-50%)',
                  textAlign: 'center',
                  wordBreak: 'break-word',
                  width: '56px',
                  fontSize: '10px',
                }}
              >
                {match.homeTeam?.localizedName ??
                  match.homeTeam?.name ??
                  match.homeTeamPlaceholder ??
                  t('matches.tbd')}
              </Typography>
            </Box>
          </Stack>

          {/* Score or Time */}
          <Stack sx={matchScoreContainerSx}>{renderScoreArea()}</Stack>

          <Stack
            sx={{
              flexDirection: 'column',
              alignItems: 'center',
              justifyContent: 'center',
              gap: 0.5,
            }}
          >
            <Box sx={{ position: 'relative' }}>
              <TeamFlag
                countryCode={match.awayTeam?.countryCode}
                flagUrl={match.awayTeam?.flagUrl}
                name={match.awayTeam?.name}
                emoji={match.awayTeam?.emoji}
                size={40}
              />
              <Typography
                variant="globalXXS"
                sx={{
                  position: 'absolute',
                  top: `calc(100% + 4px)`,
                  left: '50%',
                  transform: 'translateX(-50%)',
                  textAlign: 'center',
                  wordBreak: 'break-word',
                  width: '56px',
                  fontSize: '10px',
                }}
              >
                {match.awayTeam?.localizedName ??
                  match.awayTeam?.name ??
                  match.awayTeamPlaceholder ??
                  t('matches.tbd')}
              </Typography>
            </Box>
          </Stack>
        </Box>

        {/* Penalty winner prediction text (for draw predictions) */}
        {hasPrediction &&
          prediction.predictedHomeScore === prediction.predictedAwayScore &&
          prediction.predictedQualifierId && (
            <Typography
              variant="globalXS"
              sx={{
                textAlign: 'center',
                color: theme.palette.new.text.neutral.lighter,
              }}
            >
              <Trans
                i18nKey="matches.penalty_winner"
                ns="sportsPool"
                values={{
                  team:
                    prediction.predictedQualifierId === match.homeTeam?.id
                      ? (match.homeTeam?.localizedName ?? match.homeTeam?.name)
                      : (match.awayTeam?.localizedName ?? match.awayTeam?.name),
                }}
                components={{
                  bold: (
                    <Typography
                      component="span"
                      variant="globalXS"
                      fontWeight="fontWeightSemiBold"
                      sx={{ color: theme.palette.new.text.neutral.lighter }}
                    />
                  ),
                }}
              />
            </Typography>
          )}

        <Divider
          sx={{
            width: '100%',
            borderColor: theme.palette.new.border.neutral.divider,
          }}
        />

        {/* Stadium Info: Group/Stage · Venue, City, Country */}
        <Typography
          variant="globalXS"
          sx={{
            textAlign: 'center',
            color: theme.palette.new.text.neutral.default,
            fontSize: theme.typography.globalXS.fontSize,
            lineHeight: '140%',
            letterSpacing: '0.002em',
          }}
        >
          <Typography
            component="span"
            fontWeight="fontWeightSemiBold"
            variant="globalXS"
          >
            {match.groupName || match.stageName}
          </Typography>
          {match.venue && (
            <Typography
              component="span"
              sx={{
                fontWeight: 400,
                fontSize: theme.typography.globalXS.fontSize,
              }}
            >
              {` · ${match.venue.name}, ${match.venue.city}, ${match.venue.country}`}
            </Typography>
          )}
        </Typography>
      </Stack>
    </CardContainer>
  );
};

export default MatchCard;
