"use client";

import {
  Badge,
  Box,
  Card,
  Flex,
  Grid,
  HStack,
  Icon,
  IconButton,
  Separator,
  SimpleGrid,
  Text,
  VStack,
} from "@chakra-ui/react";
import { useMessages, useTranslations } from "next-intl";
import {
  LuBadgeCheck,
  LuBrain,
  LuChartColumn,
  LuChartNoAxesCombined,
  LuCircleHelp,
  LuFlame,
  LuGauge,
  LuShieldAlert,
  LuSparkles,
  LuTarget,
  LuTriangleAlert,
  LuTrendingUp,
} from "react-icons/lu";
import { useColorModeValue } from "@/components/ui/color-mode";
import { Tooltip } from "@/components/ui/overlays/tooltip";
import type {
  MarketBoardEntryDto,
  MatchBetSummaryItemDto,
  MatchPickDto,
  MatchPredictionDto,
  SignalTier,
  V27EngineDto,
} from "@/lib/api/predictions/types";
import type { SportType } from "@/lib/api/matches/types";
import V28OddsBandPanel from "@/components/matches/v28-odds-band-panel";

interface PredictionCardProps {
  prediction: MatchPredictionDto;
}

function formatReasonFallback(reason: string): string {
  if (reason.startsWith("risk:")) return formatReasonFallback(reason.slice(5));
  const evMatch = reason.match(/^ev_edge_([+\-][\d.]+%)_grade_(\w)$/);
  if (evMatch) return `Beklenen avantaj ${evMatch[1]} (Not ${evMatch[2]})`;
  const negMatch = reason.match(/^negative_model_edge_([+\-][\d.]+)$/);
  if (negMatch) return `Model avantajı negatif (${negMatch[1]})`;
  const thresholdMatch = reason.match(/^below_market_edge_threshold_([+\-]?[\d.]+)$/);
  if (thresholdMatch) return `Piyasa avantaj eşiğinin altında (${thresholdMatch[1]})`;
  if (reason === "confidence_interval_too_wide") return "Güven aralığı fazla geniş.";
  if (reason === "confidence_band_low") return "Güven bandı düşük.";
  if (reason === "draw_probability_elevated") return "Beraberlik olasılığı yükselmiş görünüyor.";
  if (reason === "balanced_match_risk") return "Maç dengeli görünüyor, sürpriz riski var.";
  if (reason === "high_total_goal_volatility") return "Yüksek gol temposu sürpriz riskini artırıyor.";
  if (reason === "mutual_goal_pressure") return "İki takım da gol tehdidi üretiyor.";
  if (reason === "late_goal_swing_risk") return "Geç gol veya skor kırılması riski yüksek.";
  if (reason === "live_match_open_state") return "Canlı maç tamamen açık oyuna dönmüş durumda.";
  if (reason === "live_match_active_state") return "Canlı maç beklenenden daha hareketli ilerliyor.";
  if (reason === "live_state_impossible_market") return "Canlı maç durumu bu marketi geçersiz kılıyor.";
  if (reason === "live_score_exceeds_under_line") return "Canlı skor, alt seçeneğinin üst sınırına çok yaklaştı veya geçti.";
  if (reason === "score_model_conflicts_with_under_pick") return "Skor ve xG modeli bu alt seçeneğiyle çelişiyor.";
  if (reason === "score_model_conflicts_with_over_pick") return "Skor ve xG modeli bu üst seçeneğiyle çelişiyor.";
  if (reason === "market_stack_conflict_over25") return "2.5 üst sinyali bu marketle çelişiyor.";
  if (reason === "market_stack_conflict_btts") return "KG Var sinyali bu marketle çelişiyor.";
  if (reason === "live_total_goals_close_to_line") return "Canlı toplam gol sayısı bu çizgiye fazla yaklaştı.";
  if (reason === "score_model_conflicts_with_btts_no") return "Skor ve xG modeli KG Yok seçeneğiyle çelişiyor.";
  if (reason === "score_model_conflicts_with_draw_pick") return "Skor modeli beraberlik seçeneğini desteklemiyor.";
  if (reason === "score_model_conflicts_with_home_pick") return "Skor modeli ev sahibi seçeneğini desteklemiyor.";
  if (reason === "score_model_conflicts_with_away_pick") return "Skor modeli deplasman seçeneğini desteklemiyor.";
  if (/^[a-z0-9_]+$/i.test(reason)) {
    return reason.replace(/_/g, " ").replace(/^\w/, (char) => char.toUpperCase());
  }
  return reason;
}

function formatPercent(value?: number, digits = 0): string {
  if (value === undefined || value === null || Number.isNaN(value)) return "-";
  return `${value.toFixed(digits)}%`;
}

function formatProbability(value?: number, digits = 1): string {
  if (value === undefined || value === null || Number.isNaN(value)) return "-";
  return `${(value * 100).toFixed(digits)}%`;
}

function formatOdds(value?: number | null): string {
  if (!value || value <= 1.01) return "-";
  return value.toFixed(2);
}

function formatUnits(value?: number): string {
  if (!value || value <= 0) return "-";
  return `${value.toFixed(1)}u`;
}

function getRiskPalette(level: string) {
  switch (level.toUpperCase()) {
    case "LOW":
      return "green";
    case "MEDIUM":
      return "yellow";
    case "HIGH":
      return "orange";
    case "EXTREME":
      return "red";
    default:
      return "gray";
  }
}

function getQualityPalette(label: string) {
  switch (label.toUpperCase()) {
    case "HIGH":
      return "green";
    case "MEDIUM":
      return "yellow";
    case "LOW":
      return "red";
    default:
      return "gray";
  }
}

function getConfidenceBandPalette(band?: string) {
  switch ((band || "").toUpperCase()) {
    case "HIGH":
      return "green";
    case "MEDIUM":
      return "yellow";
    case "LOW":
      return "red";
    default:
      return "gray";
  }
}

function getConfidenceBandLabel(band?: string) {
  switch ((band || "").toUpperCase()) {
    case "HIGH":
      return "Yüksek";
    case "MEDIUM":
      return "Orta";
    case "LOW":
      return "Düşük";
    default:
      return "Belirsiz";
  }
}

function getLineupSourceLabel(source?: string): string {
  if (source === "confirmed_live") return "Onayli ilk 11";
  if (source === "probable_xi") return "Muhtemel ilk 11";
  return source ? formatReasonFallback(source) : "Bilinmiyor";
}

function formatInterval(
  interval?: { lower?: number; upper?: number },
  digits = 0,
): string {
  if (
    !interval ||
    interval.lower === undefined ||
    interval.upper === undefined ||
    Number.isNaN(interval.lower) ||
    Number.isNaN(interval.upper)
  ) {
    return "-";
  }
  return `${interval.lower.toFixed(digits)}-${interval.upper.toFixed(digits)}%`;
}

function getPredictionReasonText(
  reason: string,
  reasonMessages?: Record<string, string>,
): string {
  if (
    reasonMessages &&
    Object.prototype.hasOwnProperty.call(reasonMessages, reason)
  ) {
    return reasonMessages[reason];
  }
  return formatReasonFallback(reason);
}

function getMarketLabel(
  market: string,
  marketLabels?: Record<string, string>,
): string {
  if (marketLabels && Object.prototype.hasOwnProperty.call(marketLabels, market)) {
    return marketLabels[market];
  }

  const fallbackLabels: Record<string, string> = {
    ML: "Moneyline",
    MS: "Maç Sonucu",
    DC: "Çifte Şans",
    TOTAL: "Toplam Sayı",
    SPREAD: "Handikap",
    OU15: "Toplam Gol 1.5",
    OU25: "Toplam Gol 2.5",
    OU35: "Toplam Gol 3.5",
    BTTS: "Karşılıklı Gol",
    HT: "İlk Yarı Sonucu",
    HT_OU05: "İlk Yarı 0.5 Gol",
    HT_OU15: "İlk Yarı 1.5 Gol",
    HTFT: "İlk Yarı / Maç Sonu",
    "HT/FT": "İlk Yarı / Maç Sonu",
    OE: "Tek / Çift",
    CARDS: "Kartlar 4.5",
    HCAP: "Handikap Sonucu",
  };
  if (fallbackLabels[market]) {
    return fallbackLabels[market];
  }

  return market;
}

const MARKET_ORDER = [
  "ML",
  "TOTAL",
  "SPREAD",
  "MS",
  "DC",
  "OU15",
  "OU25",
  "OU35",
  "BTTS",
  "HT",
  "HT_OU05",
  "HT_OU15",
  "HTFT",
  "OE",
  "CARDS",
  "HCAP",
];

function getPredictionSport(prediction: MatchPredictionDto): SportType {
  const explicitSport = prediction.match_info?.sport;
  if (explicitSport === "basketball" || explicitSport === "football") {
    return explicitSport;
  }

  if (
    prediction.model_version?.toLowerCase().includes("basketball") ||
    Object.keys(prediction.market_board || {}).some((market) =>
      ["ML", "TOTAL", "SPREAD"].includes(market),
    )
  ) {
    return "basketball";
  }

  return "football";
}

const SIGNAL_TIER_ORDER: SignalTier[] = ["CORE", "VALUE", "LEAN", "LONGSHOT", "PASS"];

function getSignalTierPalette(tier?: SignalTier) {
  switch (tier) {
    case "CORE":
      return "green";
    case "VALUE":
      return "blue";
    case "LEAN":
      return "orange";
    case "LONGSHOT":
      return "pink";
    default:
      return "gray";
  }
}

function getSignalTierLabel(tier?: SignalTier) {
  switch (tier) {
    case "CORE":
      return "Çekirdek";
    case "VALUE":
      return "Değer";
    case "LEAN":
      return "Yorum";
    case "LONGSHOT":
      return "Sürpriz";
    default:
      return "Pas";
  }
}

function TooltipIcon({ content }: { content: string }) {
  return (
    <Tooltip
      content={content}
      showArrow
      positioning={{ placement: "top" }}
      contentProps={{ maxW: "260px", fontSize: "xs", px: 3, py: 2 }}
    >
      <IconButton aria-label="Bilgi" variant="ghost" size="2xs" colorPalette="gray">
        <LuCircleHelp />
      </IconButton>
    </Tooltip>
  );
}

function SectionTitle({
  icon,
  title,
  info,
}: {
  icon: React.ElementType;
  title: string;
  info?: string;
}) {
  return (
    <HStack justify="space-between" w="full">
      <HStack gap={2}>
        <Icon as={icon} boxSize={4.5} color="fg.muted" />
        <Text fontSize="lg" fontWeight="semibold">
          {title}
        </Text>
      </HStack>
      {info ? <TooltipIcon content={info} /> : null}
    </HStack>
  );
}

function MetricTile({
  label,
  value,
  helper,
  accent,
}: {
  label: string;
  value: string;
  helper?: string;
  accent?: string;
}) {
  const bg = useColorModeValue("gray.50", "whiteAlpha.50");
  const borderColor = useColorModeValue("gray.200", "gray.700");
  return (
    <Box p={3.5} bg={bg} borderWidth="1px" borderColor={borderColor} borderRadius="xl">
      <HStack justify="space-between" mb={1.5}>
        <Text fontSize="xs" color="fg.muted" fontWeight="medium">
          {label}
        </Text>
        {helper ? <TooltipIcon content={helper} /> : null}
      </HStack>
      <Text fontSize="xl" fontWeight="bold" color={accent}>
        {value}
      </Text>
    </Box>
  );
}

function Bar({
  value,
  color,
  trackBg,
  height = "8px",
}: {
  value: number;
  color: string;
  trackBg: string;
  height?: string;
}) {
  return (
    <Box h={height} w="full" bg={trackBg} borderRadius="full" overflow="hidden">
      <Box h="full" w={`${Math.max(0, Math.min(100, value))}%`} bg={color} borderRadius="full" />
    </Box>
  );
}

function ReasonList({
  items,
  resolveReason,
}: {
  items?: string[];
  resolveReason: (reason: string) => string;
}) {
  if (!items?.length) return null;
  return (
    <VStack align="stretch" gap={1.5}>
      {items.map((item, index) => (
        <HStack key={`${item}-${index}`} align="start" gap={2}>
          <Box mt="7px" boxSize="5px" bg="primary.400" borderRadius="full" />
          <Text fontSize="sm" color="fg.muted" lineHeight="tall">
            {resolveReason(item)}
          </Text>
        </HStack>
      ))}
    </VStack>
  );
}

function ProbabilitySplit({
  modelProb,
  impliedProb,
}: {
  modelProb: number;
  impliedProb: number;
}) {
  const trackBg = useColorModeValue("gray.100", "gray.700");
  if (!impliedProb || impliedProb <= 0) return null;
  return (
    <VStack align="stretch" gap={2}>
      <Flex justify="space-between">
        <Text fontSize="xs" color="blue.600" fontWeight="semibold">
          Model {formatProbability(modelProb, 0)}
        </Text>
        <Text fontSize="xs" color="orange.500" fontWeight="semibold">
          Piyasa {formatProbability(impliedProb, 0)}
        </Text>
      </Flex>
      <Box position="relative">
        <Bar value={modelProb * 100} color="blue.400" trackBg={trackBg} />
        <Box
          position="absolute"
          top="-2px"
          left={`calc(${Math.min(impliedProb * 100, 100)}% - 1px)`}
          h="12px"
          w="2px"
          bg="orange.500"
          borderRadius="full"
        />
      </Box>
    </VStack>
  );
}

function PickCard({
  pick,
  stakeFallback,
  title,
  resolveReason,
  palette,
  marketLabels,
  labels,
}: {
  pick: MatchPickDto;
  stakeFallback?: number;
  title: string;
  resolveReason: (reason: string) => string;
  palette: string;
  marketLabels?: Record<string, string>;
  labels: {
    confidence: string;
    odds: string;
    recommendedStake: string;
    playScore: string;
    playability: string;
  };
}) {
  const bg = useColorModeValue(`${palette}.50`, `${palette}.950`);
  const borderColor = useColorModeValue(`${palette}.200`, `${palette}.800`);
  const trackBg = useColorModeValue("gray.100", "gray.700");
  const intervalWarningBg = useColorModeValue("orange.50", "orange.950");
  const intervalWarningBorder = useColorModeValue("orange.200", "orange.800");
  const confidenceBandPalette = getConfidenceBandPalette(
    pick.confidence_interval?.band,
  );
  return (
    <Card.Root bg={bg} borderColor={borderColor} borderRadius="2xl">
      <Card.Body gap={4}>
        <Flex justify="space-between" align={{ base: "start", md: "center" }} direction={{ base: "column", md: "row" }} gap={3}>
          <VStack align="start" gap={2}>
            <Badge colorPalette={palette} variant="solid" borderRadius="full">
              {title}
            </Badge>
            <Text fontSize="2xl" fontWeight="bold">
              {pick.pick}
            </Text>
            <HStack gap={2} flexWrap="wrap">
              <Badge variant="subtle">{getMarketLabel(pick.market, marketLabels)}</Badge>
              <Badge colorPalette={pick.playable ? "green" : "gray"} variant="subtle">
                {pick.bet_grade}
              </Badge>
              <Badge colorPalette={getSignalTierPalette(pick.signal_tier)} variant="subtle">
                {getSignalTierLabel(pick.signal_tier)}
              </Badge>
              <Badge colorPalette={confidenceBandPalette} variant="subtle">
                {getConfidenceBandLabel(pick.confidence_interval?.band)}
              </Badge>
              <Badge colorPalette={pick.ev_edge > 0 ? "green" : "red"} variant="subtle">
                EV {pick.ev_edge > 0 ? "+" : ""}
                {formatPercent(pick.ev_edge * 100, 1)}
              </Badge>
            </HStack>
          </VStack>
          <SimpleGrid columns={2} gap={3} minW={{ base: "full", md: "320px" }}>
            <MetricTile label={labels.confidence} value={formatPercent(pick.calibrated_confidence, 0)} />
            <MetricTile label={labels.odds} value={formatOdds(pick.odds)} />
            <MetricTile
              label={labels.recommendedStake}
              value={formatUnits(pick.stake_units || stakeFallback)}
            />
            <MetricTile label={labels.playScore} value={formatPercent(pick.play_score, 0)} />
            <MetricTile label="Guven Araligi" value={formatInterval(pick.confidence_interval)} />
            <MetricTile
              label="Band"
              value={getConfidenceBandLabel(pick.confidence_interval?.band)}
              accent={`${confidenceBandPalette}.500`}
            />
          </SimpleGrid>
        </Flex>
        <ProbabilitySplit modelProb={pick.probability} impliedProb={pick.implied_prob} />
        <Box>
          <HStack justify="space-between" mb={1.5}>
            <Text fontSize="sm" fontWeight="semibold">
              {labels.playability}
            </Text>
            <Text fontSize="sm" color="fg.muted">
              {formatPercent(pick.play_score, 1)}
            </Text>
          </HStack>
          <Bar
            value={pick.play_score}
            color={pick.ev_edge > 0 ? "green.400" : "orange.400"}
            trackBg={trackBg}
          />
        </Box>
        <ReasonList items={pick.decision_reasons} resolveReason={resolveReason} />
        {pick.confidence_interval && !pick.confidence_interval.threshold_met ? (
          <Box
            p={3}
            borderRadius="xl"
            bg={intervalWarningBg}
            borderWidth="1px"
            borderColor={intervalWarningBorder}
          >
            <Text fontSize="sm" color="fg.muted">
              Guven araligi genis. Sinyal olsa bile tek basina oynanmasi onerilmez.
            </Text>
          </Box>
        ) : null}
      </Card.Body>
    </Card.Root>
  );
}

function SummaryTable({
  items,
  marketLabels,
  title,
  info,
}: {
  items: MatchBetSummaryItemDto[];
  marketLabels?: Record<string, string>;
  title: string;
  info: string;
}) {
  const cardBg = useColorModeValue("white", "gray.800");
  const borderColor = useColorModeValue("gray.200", "gray.700");
  const highlightBg = useColorModeValue("green.50", "green.950");
  if (!items.length) return null;
  return (
    <Card.Root bg={cardBg} borderColor={borderColor} borderRadius="2xl">
      <Card.Body gap={4}>
        <SectionTitle icon={LuChartColumn} title={title} info={info} />
        <VStack align="stretch" gap={2}>
          {items
            .slice()
            .sort((left, right) => {
              const leftIndex = SIGNAL_TIER_ORDER.indexOf(left.signal_tier || "PASS");
              const rightIndex = SIGNAL_TIER_ORDER.indexOf(right.signal_tier || "PASS");
              if (leftIndex !== rightIndex) return leftIndex - rightIndex;
              return right.calibrated_confidence - left.calibrated_confidence;
            })
            .map((item) => (
            <Flex
              key={`${item.market}-${item.pick}`}
              justify="space-between"
              align={{ base: "start", md: "center" }}
              direction={{ base: "column", md: "row" }}
              gap={3}
              px={3}
              py={3}
              borderRadius="xl"
              bg={item.playable ? highlightBg : "transparent"}
              borderWidth="1px"
              borderColor={item.playable ? "green.200" : borderColor}
            >
              <HStack gap={2} flexWrap="wrap">
                <Badge colorPalette={item.playable ? "green" : "gray"} variant="subtle">
                  {item.bet_grade}
                </Badge>
                <Badge colorPalette={getSignalTierPalette(item.signal_tier)} variant="subtle">
                  {getSignalTierLabel(item.signal_tier)}
                </Badge>
                <Text fontWeight="semibold">{getMarketLabel(item.market, marketLabels)}</Text>
                <Text color="fg.muted">{item.pick}</Text>
              </HStack>
              <HStack gap={5} fontSize="sm">
                <Text minW="48px">{formatOdds(item.odds)}</Text>
                <Text minW="68px" color={item.ev_edge > 0 ? "green.500" : "red.500"} fontWeight="semibold">
                  {item.ev_edge > 0 ? "+" : ""}
                  {formatPercent(item.ev_edge * 100, 1)}
                </Text>
                <Text minW="48px">{formatPercent(item.calibrated_confidence, 0)}</Text>
                <Badge colorPalette={getConfidenceBandPalette(item.confidence_interval?.band)} variant="subtle">
                  {getConfidenceBandLabel(item.confidence_interval?.band)}
                </Badge>
                <Badge variant="surface">{formatUnits(item.stake_units)}</Badge>
              </HStack>
            </Flex>
          ))}
        </VStack>
      </Card.Body>
    </Card.Root>
  );
}

function MarketBoardSection({
  marketBoard,
  betSummary,
  marketLabels,
  title,
  info,
}: {
  marketBoard?: Record<string, MarketBoardEntryDto>;
  betSummary?: MatchBetSummaryItemDto[];
  marketLabels?: Record<string, string>;
  title: string;
  info: string;
}) {
  const cardBg = useColorModeValue("white", "gray.800");
  const borderColor = useColorModeValue("gray.200", "gray.700");
  const trackBg = useColorModeValue("gray.100", "gray.700");
  const innerBg = useColorModeValue("gray.50", "whiteAlpha.50");

  if (!marketBoard || !Object.keys(marketBoard).length) return null;

  const summaryByMarket = new Map((betSummary || []).map((item) => [item.market, item]));
  const orderedEntries = Object.entries(marketBoard).sort(([left], [right]) => {
    const leftIndex = MARKET_ORDER.indexOf(left);
    const rightIndex = MARKET_ORDER.indexOf(right);
    const safeLeft = leftIndex === -1 ? Number.MAX_SAFE_INTEGER : leftIndex;
    const safeRight = rightIndex === -1 ? Number.MAX_SAFE_INTEGER : rightIndex;
    return safeLeft - safeRight;
  });

  return (
    <Card.Root bg={cardBg} borderColor={borderColor} borderRadius="2xl">
      <Card.Body gap={4}>
        <SectionTitle
          icon={LuChartNoAxesCombined}
          title={title}
          info={info}
        />
        <SimpleGrid columns={{ base: 1, xl: 2 }} gap={4}>
          {orderedEntries.map(([market, entry]) => {
            if (!entry?.probs) return null;
            const summary = summaryByMarket.get(market);
            const interval =
              summary?.confidence_interval || entry.confidence_interval;
            return (
              <Box
                key={market}
                p={4}
                bg={innerBg}
                borderWidth="1px"
                borderColor={borderColor}
                borderRadius="xl"
              >
                <Flex justify="space-between" align="start" mb={3}>
                  <VStack align="start" gap={1}>
                    <Text fontWeight="semibold">{market}</Text>
                    <Text fontSize="sm" color="fg.muted">
                      {getMarketLabel(market, marketLabels)}
                    </Text>
                    <HStack gap={2} flexWrap="wrap">
                      {summary ? (
                        <Badge colorPalette={summary.playable ? "green" : "gray"} variant="subtle">
                          {summary.playable ? "Oynanabilir" : "Riskli"}
                        </Badge>
                      ) : null}
                      {summary?.signal_tier ? (
                        <Badge colorPalette={getSignalTierPalette(summary.signal_tier)} variant="subtle">
                          {getSignalTierLabel(summary.signal_tier)}
                        </Badge>
                      ) : null}
                      {summary?.bet_grade ? <Badge variant="outline">{summary.bet_grade}</Badge> : null}
                    </HStack>
                  </VStack>
                  {entry.pick ? (
                    <Badge
                      colorPalette={getConfidenceBandPalette(entry.confidence_band || interval?.band)}
                      variant="subtle"
                      borderRadius="full"
                    >
                      {entry.pick} ({formatPercent(entry.confidence, 0)})
                    </Badge>
                  ) : null}
                </Flex>
                <SimpleGrid columns={3} gap={2} mb={3}>
                  <MetricTile
                    label="Tutma Olasiligi"
                    value={formatPercent(entry.confidence, 0)}
                    accent="green.500"
                  />
                  <MetricTile
                    label="Kalibre Guven"
                    value={summary ? formatPercent(summary.calibrated_confidence, 0) : "-"}
                    accent={summary?.playable ? "green.500" : "orange.500"}
                  />
                  <MetricTile
                    label="Oran"
                    value={summary ? formatOdds(summary.odds) : "-"}
                  />
                </SimpleGrid>
                {interval ? (
                  <Text fontSize="xs" color="fg.muted" mb={3}>
                    Guven araligi: {formatInterval(interval)}
                  </Text>
                ) : null}
                <VStack align="stretch" gap={2.5}>
                  {Object.entries(entry.probs).map(([outcome, probability]) => (
                    <Box key={`${market}-${outcome}`}>
                      <Flex justify="space-between" mb={1}>
                        <Text fontSize="sm" color="fg.muted">
                          {outcome.toUpperCase()}
                        </Text>
                        <Text fontSize="sm" fontWeight="semibold">
                          {formatProbability(probability, 1)}
                        </Text>
                      </Flex>
                      <Bar
                        value={probability * 100}
                        color={
                          entry.pick === outcome ||
                          entry.pick?.toUpperCase() === outcome.toUpperCase()
                            ? "green.400"
                            : "blue.400"
                        }
                        trackBg={trackBg}
                        height="6px"
                      />
                    </Box>
                  ))}
                </VStack>
              </Box>
            );
          })}
        </SimpleGrid>
      </Card.Body>
    </Card.Root>
  );
}

function ScoreCard({
  prediction,
  sport,
}: {
  prediction: MatchPredictionDto;
  sport: SportType;
}) {
  const cardBg = useColorModeValue("white", "gray.800");
  const borderColor = useColorModeValue("gray.200", "gray.700");
  const subBg = useColorModeValue("gray.50", "whiteAlpha.50");
  const isBasketball = sport === "basketball";

  return (
    <Card.Root bg={cardBg} borderColor={borderColor} borderRadius="2xl">
      <Card.Body gap={4}>
        <SectionTitle
          icon={LuTarget}
          title={isBasketball ? "Sayi Senaryosu" : "Skor Senaryosu"}
          info={
            isBasketball
              ? "Beklenen sayi dagilimi ve en olasi mac senaryolari."
              : "Beklenen skor ve en olasi senaryolar."
          }
        />
        <SimpleGrid columns={{ base: 1, md: 3 }} gap={3}>
          <MetricTile
            label={isBasketball ? "Mac Sonu Sayi" : "Mac Sonu"}
            value={prediction.score_prediction.ft}
          />
          <MetricTile
            label={isBasketball ? "Ilk Yari Sayi" : "Ilk Yari"}
            value={prediction.score_prediction.ht}
          />
          <MetricTile
            label={isBasketball ? "Beklenen Toplam Sayi" : "Toplam xG"}
            value={prediction.score_prediction.xg_total.toFixed(2)}
          />
        </SimpleGrid>
        <SimpleGrid columns={{ base: 2, md: 5 }} gap={2}>
          {prediction.scenario_top5.map((scenario) => (
            <Box key={`${scenario.score}-${scenario.prob}`} p={3} bg={subBg} borderWidth="1px" borderColor={borderColor} borderRadius="xl">
              <Text fontSize="lg" fontWeight="bold">
                {scenario.score}
              </Text>
              <Text fontSize="sm" color="fg.muted">
                {formatProbability(scenario.prob, 1)}
              </Text>
            </Box>
          ))}
        </SimpleGrid>
      </Card.Body>
    </Card.Root>
  );
}

export default function PredictionCard({ prediction }: PredictionCardProps) {
  const t = useTranslations("predictions");
  const messages = useMessages() as {
    predictions?: {
      "prediction-reasons"?: Record<string, string>;
      "market-labels"?: Record<string, string>;
      ui?: Record<string, string>;
    };
  };
  const marketLabels = messages.predictions?.["market-labels"];
  const ui = messages.predictions?.ui;
  const uiText = (key: string, fallback: string) => ui?.[key] || fallback;
  const resolveReason = (reason: string) =>
    getPredictionReasonText(reason, messages.predictions?.["prediction-reasons"]);

  const pageBg = useColorModeValue("gray.50", "gray.900");
  const cardBg = useColorModeValue("white", "gray.800");
  const borderColor = useColorModeValue("gray.200", "gray.700");
  const riskPalette = getRiskPalette(prediction.risk.level);
  const qualityPalette = getQualityPalette(prediction.data_quality.label);
  const recommendedPick = prediction.main_pick;
  const mainBandPalette = getConfidenceBandPalette(
    prediction.bet_advice.confidence_band,
  );
  const sport = getPredictionSport(prediction);
  const isBasketball = sport === "basketball";

  const engineItems = [
    {
      key: "team",
      icon: LuGauge,
      label: isBasketball ? "Takim Formu" : "Takim Gucu",
      value: prediction.engine_breakdown.team,
      color: "blue.400",
    },
    {
      key: "player",
      icon: LuSparkles,
      label: isBasketball ? "Kadro Etkisi" : "Oyuncu Etkisi",
      value: prediction.engine_breakdown.player,
      color: "green.400",
    },
    { key: "odds", icon: LuTrendingUp, label: "Oran Analizi", value: prediction.engine_breakdown.odds, color: "orange.400" },
    {
      key: "referee",
      icon: LuShieldAlert,
      label: isBasketball ? "Yardimci Sinyaller" : "Hakem Etkisi",
      value: prediction.engine_breakdown.referee,
      color: "purple.400",
    },
  ];

  return (
    <VStack align="stretch" gap={5}>
      <Card.Root bg={pageBg} borderColor={borderColor} borderRadius="2xl">
        <Card.Body gap={5}>
          <SectionTitle
            icon={LuBrain}
            title={uiText("summary-title", "Tahmin Ozeti")}
            info={uiText(
              "summary-info",
              "Kullanicinin once neyi oynayacagini, sonra nedenini anlamasi icin sade ozet.",
            )}
          />

          {recommendedPick ? (
            <Grid templateColumns={{ base: "1fr", xl: "1.4fr 1fr" }} gap={4}>
              <Box p={4} bg={useColorModeValue("green.50", "green.950")} borderWidth="1px" borderColor={useColorModeValue("green.200", "green.800")} borderRadius="2xl">
                <HStack justify="space-between" align="start" mb={4}>
                  <VStack align="start" gap={2}>
                    <Badge colorPalette="green" variant="solid" borderRadius="full">
                      {uiText("main-recommendation", "Ana Oneri")}
                    </Badge>
                    <Text fontSize="2xl" fontWeight="bold">
                      {recommendedPick.pick}
                    </Text>
                    <Text fontSize="sm" color="fg.muted">
                      {getMarketLabel(recommendedPick.market, marketLabels)} {uiText("best-market-copy", "marketinde en guclu secim.")}
                    </Text>
                    <HStack gap={2} flexWrap="wrap">
                      <Badge colorPalette={mainBandPalette} variant="subtle">
                        {getConfidenceBandLabel(prediction.bet_advice.confidence_band)}
                      </Badge>
                      {recommendedPick.confidence_interval ? (
                        <Badge variant="outline">
                          {formatInterval(recommendedPick.confidence_interval)}
                        </Badge>
                      ) : null}
                    </HStack>
                  </VStack>
                  <Icon as={LuBadgeCheck} boxSize={8} color="green.500" />
                </HStack>
                <SimpleGrid columns={{ base: 2, md: 4 }} gap={3}>
                  <MetricTile label={uiText("confidence-label", "Guven")} value={formatPercent(recommendedPick.calibrated_confidence, 0)} />
                  <MetricTile label={uiText("odds-label", "Oran")} value={formatOdds(recommendedPick.odds)} />
                  <MetricTile label="Guven Araligi" value={formatInterval(recommendedPick.confidence_interval)} />
                  <MetricTile
                    label={uiText("edge-label", "Beklenen Avantaj (Edge)")}
                    value={`${recommendedPick.ev_edge > 0 ? "+" : ""}${formatPercent(recommendedPick.ev_edge * 100, 1)}`}
                    helper={uiText(
                      "edge-info",
                      "Edge, model olasiligi ile piyasa olasiligi arasindaki farktir. Pozitifse model bu orani avantajli buluyor demektir.",
                    )}
                    accent={recommendedPick.ev_edge > 0 ? "green.500" : "red.500"}
                  />
                  <MetricTile
                    label={uiText("stake-label", "Onerilen Miktar (Stake)")}
                    value={formatUnits(
                      recommendedPick.stake_units ||
                        prediction.bet_advice.suggested_stake_units,
                    )}
                    helper={uiText(
                      "stake-info",
                      "Stake, bu bahis icin onerilen bahis birimidir. 2.0u demek, kendi bankroll planinizdaki 2 birimlik bahis anlamina gelir.",
                    )}
                  />
                </SimpleGrid>
              </Box>

              <Box p={4} bg={cardBg} borderWidth="1px" borderColor={borderColor} borderRadius="2xl">
                <Text fontSize="sm" fontWeight="semibold" mb={3}>
                  {uiText("quick-read", "Hizli yorum")}
                </Text>
                <ReasonList
                  items={[
                    ...prediction.reasoning_factors.slice(0, 2),
                    prediction.risk.surprise_type || "",
                  ].filter(Boolean)}
                  resolveReason={resolveReason}
                />
              </Box>
            </Grid>
          ) : null}

          <SimpleGrid columns={{ base: 1, md: 2, xl: 4 }} gap={3}>
            <MetricTile
              label="Veri Kalitesi"
              value={formatPercent(prediction.data_quality.score * 100, 0)}
              helper="Kadro, oran ve mac verisinin ne kadar guvenilir oldugu."
              accent={`${qualityPalette}.500`}
            />
            <MetricTile
              label={t("risk-level")}
              value={`${prediction.risk.level} (${prediction.risk.score}/100)`}
              helper="Surpriz ihtimali ve belirsizlik seviyesi."
              accent={`${riskPalette}.500`}
            />
            <MetricTile
              label={uiText("lineup-source", "Lineup Kaynagi")}
              value={getLineupSourceLabel(prediction.data_quality.lineup_source)}
            />
            <MetricTile label={uiText("model-label", "Model")} value={prediction.model_version} />
          </SimpleGrid>

          {prediction.risk.is_surprise_risk || prediction.risk.warnings?.length ? (
            <Box
              p={4}
              bg={useColorModeValue("orange.50", "orange.950")}
              borderWidth="1px"
              borderColor={useColorModeValue("orange.200", "orange.800")}
              borderRadius="2xl"
            >
              <HStack align="start" gap={3}>
                <Icon as={LuTriangleAlert} boxSize={5} color="orange.500" mt={0.5} />
                <VStack align="start" gap={1.5}>
                  <Text fontWeight="semibold">Risk Yorumu</Text>
                  <Text fontSize="sm" color="fg.muted">
                    {prediction.risk.surprise_comment ||
                      (prediction.risk.surprise_type
                        ? `${resolveReason(prediction.risk.surprise_type)}`
                        : "Model bu maçta ekstra dikkat istiyor.")}
                  </Text>
                  {prediction.risk.surprise_score !== undefined ? (
                    <Text fontSize="sm" fontWeight="semibold" color="orange.600">
                      Sürpriz skoru: {formatPercent(prediction.risk.surprise_score, 0)}
                    </Text>
                  ) : null}
                  <ReasonList
                    items={[
                      ...(prediction.risk.surprise_reasons || []),
                      ...prediction.risk.warnings,
                    ]}
                    resolveReason={resolveReason}
                  />
                </VStack>
              </HStack>
            </Box>
          ) : null}
        </Card.Body>
      </Card.Root>

      <Card.Root bg={cardBg} borderColor={borderColor} borderRadius="2xl">
        <Card.Body gap={4}>
          <SectionTitle
            icon={LuChartColumn}
            title={t("engine-breakdown-title")}
            info={uiText("engine-info", "Tahmini en cok hangi bilesenlerin etkiledigini gosterir.")}
          />
          <SimpleGrid columns={{ base: 1, md: 2 }} gap={4}>
            {engineItems.map((item) => (
              <Box key={item.key} p={4} bg={useColorModeValue("gray.50", "whiteAlpha.50")} borderWidth="1px" borderColor={borderColor} borderRadius="xl">
                <HStack justify="space-between" mb={2}>
                  <HStack gap={2}>
                    <Icon as={item.icon} boxSize={4} color={item.color} />
                    <Text fontSize="sm" fontWeight="semibold">
                      {item.label}
                    </Text>
                  </HStack>
                  <Text fontSize="sm" fontWeight="bold">
                    +{item.value.toFixed(1)}
                  </Text>
                </HStack>
                <Bar value={Math.min(item.value, 100)} color={item.color} trackBg={useColorModeValue("gray.100", "gray.700")} />
              </Box>
            ))}
          </SimpleGrid>
        </Card.Body>
      </Card.Root>

      {recommendedPick ? (
        <PickCard
          pick={recommendedPick}
          title={uiText("best-single-pick", "En iyi tekli secim")}
          resolveReason={resolveReason}
          palette="green"
          stakeFallback={prediction.bet_advice.suggested_stake_units}
          marketLabels={marketLabels}
          labels={{
            confidence: uiText("confidence-label", "Guven"),
            odds: uiText("odds-label", "Oran"),
            recommendedStake: uiText("stake-label-short", "Stake"),
            playScore: uiText("play-score-label", "Play Score"),
            playability: uiText("playability-label", "Oynanabilirlik"),
          }}
        />
      ) : null}

      {prediction.supporting_picks?.length ? (
        <Card.Root bg={cardBg} borderColor={borderColor} borderRadius="2xl">
          <Card.Body gap={4}>
            <SectionTitle
              icon={LuFlame}
              title={uiText("alternative-markets", "Alternatif Marketler")}
              info={uiText("alternative-markets-info", "Ana tahmin disindaki secenekler.")}
            />
            <SimpleGrid columns={{ base: 1, xl: 2 }} gap={4}>
              {prediction.supporting_picks.map((pick) => (
                <PickCard
                  key={`${pick.market}-${pick.pick}`}
                  pick={pick}
                  title={pick.playable ? uiText("alternative", "Alternatif") : uiText("pass-market", "PASS market")}
                  resolveReason={resolveReason}
                  palette={pick.ev_edge > 0 ? "blue" : "orange"}
                  marketLabels={marketLabels}
                  labels={{
                    confidence: uiText("confidence-label", "Guven"),
                    odds: uiText("odds-label", "Oran"),
                    recommendedStake: uiText("stake-label-short", "Stake"),
                    playScore: uiText("play-score-label", "Play Score"),
                    playability: uiText("playability-label", "Oynanabilirlik"),
                  }}
                />
              ))}
            </SimpleGrid>
          </Card.Body>
        </Card.Root>
      ) : null}

      <SummaryTable
        items={prediction.bet_summary || []}
        marketLabels={marketLabels}
        title={uiText("all-markets-title", "Tum Marketler")}
        info={uiText("all-markets-info", "Butun secenekleri tek tabloda karsilastir.")}
      />
      <ScoreCard prediction={prediction} sport={sport} />
      <MarketBoardSection
        marketBoard={prediction.market_board}
        betSummary={prediction.bet_summary || []}
        marketLabels={marketLabels}
        title={t("market-board")}
        info={uiText("market-board-info", "Modelin her markette gordugu olasilik dagilimi.")}
      />

      {prediction.v27_engine ? (
        <V28OddsBandPanel engine={prediction.v27_engine as V27EngineDto} />
      ) : null}

      <Card.Root bg={cardBg} borderColor={borderColor} borderRadius="2xl">
        <Card.Body gap={4}>
          <SectionTitle
            icon={LuSparkles}
            title={t("bet-advice")}
            info={uiText("bet-advice-info", "Modelin nihai aksiyon onerisi.")}
          />
          <HStack justify="space-between" align={{ base: "start", md: "center" }} flexDir={{ base: "column", md: "row" }} gap={3}>
            <HStack gap={3}>
              <Badge colorPalette={prediction.bet_advice.playable ? "green" : "red"} variant="solid" borderRadius="full" fontSize="sm" px={3} py={1}>
                {prediction.bet_advice.playable ? "OYNA" : "OYNAMA"}
              </Badge>
              <Badge colorPalette={mainBandPalette} variant="subtle" borderRadius="full" fontSize="sm" px={3} py={1}>
                {getConfidenceBandLabel(prediction.bet_advice.confidence_band)}
              </Badge>
              <Badge
                colorPalette={getSignalTierPalette(prediction.bet_advice.signal_tier)}
                variant="subtle"
                borderRadius="full"
                fontSize="sm"
                px={3}
                py={1}
              >
                {getSignalTierLabel(prediction.bet_advice.signal_tier)}
              </Badge>
              <Text color="fg.muted">{resolveReason(prediction.bet_advice.reason)}</Text>
            </HStack>
            <Badge variant="surface" fontSize="sm" px={3} py={1}>
              {uiText("recommended-stake-inline", "Onerilen miktar")}: {formatUnits(prediction.bet_advice.suggested_stake_units)}
            </Badge>
          </HStack>
          <Separator />
          <SectionTitle icon={LuBrain} title={t("reasoning")} info="Modelin bu maci neden bu sekilde okudugunun ust seviye ozeti." />
          <ReasonList items={prediction.reasoning_factors} resolveReason={resolveReason} />
        </Card.Body>
      </Card.Root>
    </VStack>
  );
}
