import { ApiProperty } from "@nestjs/swagger";

export type SignalTier = "CORE" | "VALUE" | "LEAN" | "LONGSHOT" | "PASS";

export class MatchInfoDto {
  @ApiProperty()
  match_id: string;

  @ApiProperty()
  match_name: string;

  @ApiProperty()
  home_team: string;

  @ApiProperty()
  away_team: string;

  @ApiProperty()
  league: string;

  @ApiProperty()
  match_date_ms: number;

  @ApiProperty({ required: false, nullable: true })
  league_id?: string | null;

  @ApiProperty({ required: false, default: false })
  is_top_league?: boolean;

  @ApiProperty({
    required: false,
    nullable: true,
    description:
      "Backtest-derived per-league confidence (ROI + sample size). " +
      "null when the league has too little data to judge.",
  })
  league_confidence?: {
    label: "high" | "medium" | "low";
    bet_roi: number;
    bet_n: number;
    hit: number;
  } | null;

  @ApiProperty({
    required: false,
    enum: ["football", "basketball"],
  })
  sport?: "football" | "basketball";
}

export class DataQualityDto {
  @ApiProperty({ enum: ["HIGH", "MEDIUM", "LOW"] })
  label: "HIGH" | "MEDIUM" | "LOW";

  @ApiProperty()
  score: number;

  @ApiProperty()
  home_lineup_count: number;

  @ApiProperty()
  away_lineup_count: number;

  @ApiProperty({ required: false, default: "none" })
  lineup_source?: string;

  @ApiProperty({ type: [String] })
  flags: string[];
}

export class ConfidenceIntervalDto {
  @ApiProperty()
  lower: number;

  @ApiProperty()
  upper: number;

  @ApiProperty()
  width: number;

  @ApiProperty({ enum: ["HIGH", "MEDIUM", "LOW"] })
  band: "HIGH" | "MEDIUM" | "LOW";

  @ApiProperty()
  threshold_met: boolean;
}

export class RiskDto {
  @ApiProperty({ enum: ["LOW", "MEDIUM", "HIGH", "EXTREME"] })
  level: "LOW" | "MEDIUM" | "HIGH" | "EXTREME";

  @ApiProperty()
  score: number;

  @ApiProperty()
  is_surprise_risk: boolean;

  @ApiProperty({ nullable: true })
  surprise_type: string | null;

  @ApiProperty({ required: false, default: 0 })
  surprise_score?: number;

  @ApiProperty({ required: false, nullable: true })
  surprise_comment?: string | null;

  @ApiProperty({ type: [String], required: false })
  surprise_reasons?: string[];

  @ApiProperty({ type: [String] })
  warnings: string[];
}

export class EngineBreakdownDto {
  @ApiProperty()
  team: number;

  @ApiProperty()
  player: number;

  @ApiProperty()
  odds: number;

  @ApiProperty()
  referee: number;
}

export class MatchPickDto {
  @ApiProperty()
  market: string;

  @ApiProperty({ required: false, default: "standard" })
  strategy_channel?: string;

  @ApiProperty()
  pick: string;

  @ApiProperty()
  probability: number;

  @ApiProperty()
  confidence: number;

  @ApiProperty()
  odds: number;

  @ApiProperty()
  raw_confidence: number;

  @ApiProperty()
  calibrated_confidence: number;

  @ApiProperty()
  min_required_confidence: number;

  @ApiProperty()
  edge: number;

  @ApiProperty({ required: false, default: 0 })
  ev_edge?: number;

  @ApiProperty({ required: false, default: 0 })
  implied_prob?: number;

  @ApiProperty({ required: false, default: 0 })
  model_probability?: number;

  @ApiProperty({ required: false, default: 0 })
  model_edge?: number;

  @ApiProperty({ required: false, default: 0 })
  calibrated_probability?: number;

  @ApiProperty({ required: false, default: 0 })
  odds_band_probability?: number;

  @ApiProperty({ required: false, default: 0 })
  odds_band_sample?: number;

  @ApiProperty({ required: false, default: 0 })
  odds_band_edge?: number;

  @ApiProperty({ required: false, default: false })
  odds_band_aligned?: boolean;

  @ApiProperty()
  play_score: number;

  @ApiProperty()
  playable: boolean;

  @ApiProperty({ enum: ["A", "B", "C", "PASS"] })
  bet_grade: "A" | "B" | "C" | "PASS";

  @ApiProperty()
  stake_units: number;

  @ApiProperty({ type: [String] })
  decision_reasons: string[];

  @ApiProperty({ type: ConfidenceIntervalDto, required: false })
  confidence_interval?: ConfidenceIntervalDto;

  @ApiProperty({
    required: false,
    enum: ["CORE", "VALUE", "LEAN", "LONGSHOT", "PASS"],
  })
  signal_tier?: SignalTier;

  @ApiProperty({ required: false, default: false })
  is_guaranteed?: boolean;
}

export class MatchBetAdviceDto {
  @ApiProperty()
  playable: boolean;

  @ApiProperty()
  suggested_stake_units: number;

  @ApiProperty()
  reason: string;

  @ApiProperty({ required: false, enum: ["HIGH", "MEDIUM", "LOW"] })
  confidence_band?: "HIGH" | "MEDIUM" | "LOW";

  @ApiProperty({ required: false })
  min_confidence_for_play?: number;

  @ApiProperty({
    required: false,
    enum: ["CORE", "VALUE", "LEAN", "LONGSHOT", "PASS"],
  })
  signal_tier?: SignalTier;
}

export class MatchBetSummaryItemDto {
  @ApiProperty()
  market: string;

  @ApiProperty()
  pick: string;

  @ApiProperty()
  raw_confidence: number;

  @ApiProperty()
  calibrated_confidence: number;

  @ApiProperty({ enum: ["A", "B", "C", "PASS"] })
  bet_grade: "A" | "B" | "C" | "PASS";

  @ApiProperty()
  playable: boolean;

  @ApiProperty()
  stake_units: number;

  @ApiProperty()
  play_score: number;

  @ApiProperty({ required: false, default: 0 })
  ev_edge?: number;

  @ApiProperty({ required: false, default: 0 })
  implied_prob?: number;

  @ApiProperty({ required: false, default: 0 })
  model_probability?: number;

  @ApiProperty({ required: false, default: 0 })
  model_edge?: number;

  @ApiProperty({ required: false, default: 0 })
  calibrated_probability?: number;

  @ApiProperty({ required: false, default: 0 })
  odds_band_probability?: number;

  @ApiProperty({ required: false, default: 0 })
  odds_band_sample?: number;

  @ApiProperty({ required: false, default: 0 })
  odds_band_edge?: number;

  @ApiProperty({ required: false, default: false })
  odds_band_aligned?: boolean;

  @ApiProperty({ required: false, default: 0 })
  odds?: number;

  @ApiProperty({ type: [String] })
  reasons: string[];

  @ApiProperty({ type: ConfidenceIntervalDto, required: false })
  confidence_interval?: ConfidenceIntervalDto;

  @ApiProperty({
    required: false,
    enum: ["CORE", "VALUE", "LEAN", "LONGSHOT", "PASS"],
  })
  signal_tier?: SignalTier;
}

export class HtFtPredictionDto {
  @ApiProperty()
  "1/1": number;
  @ApiProperty()
  "1/X": number;
  @ApiProperty()
  "1/2": number;
  @ApiProperty()
  "X/1": number;
  @ApiProperty()
  "X/X": number;
  @ApiProperty()
  "X/2": number;
  @ApiProperty()
  "2/1": number;
  @ApiProperty()
  "2/X": number;
  @ApiProperty()
  "2/2": number;
  @ApiProperty()
  pick: string;
  @ApiProperty()
  confidence: number;
}

export class AggressivePickDto {
  @ApiProperty()
  market: string;

  @ApiProperty()
  pick: string;

  @ApiProperty()
  probability: number;

  @ApiProperty()
  confidence: number;

  @ApiProperty()
  odds: number;

  @ApiProperty()
  raw_confidence: number;

  @ApiProperty()
  calibrated_confidence: number;

  @ApiProperty()
  min_required_confidence: number;

  @ApiProperty()
  edge: number;

  @ApiProperty({ required: false, default: 0 })
  ev_edge?: number;

  @ApiProperty({ required: false, default: 0 })
  implied_prob?: number;

  @ApiProperty()
  play_score: number;

  @ApiProperty()
  playable: boolean;

  @ApiProperty({ enum: ["A", "B", "C", "PASS"] })
  bet_grade: "A" | "B" | "C" | "PASS";

  @ApiProperty()
  stake_units: number;

  @ApiProperty({ type: [String] })
  decision_reasons: string[];

  @ApiProperty({ type: ConfidenceIntervalDto, required: false })
  confidence_interval?: ConfidenceIntervalDto;
}

export class ScenarioTop5ItemDto {
  @ApiProperty()
  scenario: string;

  @ApiProperty()
  score: number;

  @ApiProperty()
  probability: number;
}

export class ScorePredictionDto {
  @ApiProperty()
  ft: string;

  @ApiProperty()
  ht: string;

  @ApiProperty()
  xg_home: number;

  @ApiProperty()
  xg_away: number;

  @ApiProperty()
  xg_total: number;
}

export class MatchPredictionDto {
  @ApiProperty()
  model_version: string;

  @ApiProperty({ required: false, nullable: true })
  calibration_version?: string | null;

  @ApiProperty({ required: false, nullable: true })
  shadow_engine_version?: string | null;

  @ApiProperty({ required: false, nullable: true })
  decision_trace_id?: string | null;

  @ApiProperty({ type: MatchInfoDto })
  match_info: MatchInfoDto;

  @ApiProperty({ type: DataQualityDto })
  data_quality: DataQualityDto;

  @ApiProperty({ type: RiskDto })
  risk: RiskDto;

  @ApiProperty({ type: EngineBreakdownDto })
  engine_breakdown: EngineBreakdownDto;

  @ApiProperty({ type: MatchPickDto, nullable: true })
  main_pick: MatchPickDto | null;

  @ApiProperty({ type: MatchPickDto, nullable: true })
  value_pick: MatchPickDto | null;

  @ApiProperty({ type: MatchPickDto, nullable: true, required: false })
  surprise_pick?: MatchPickDto | null;

  @ApiProperty({ type: MatchBetAdviceDto })
  bet_advice: MatchBetAdviceDto;

  @ApiProperty({ type: [MatchBetSummaryItemDto] })
  bet_summary: MatchBetSummaryItemDto[];

  @ApiProperty({ type: [MatchPickDto] })
  supporting_picks: MatchPickDto[];

  @ApiProperty({ type: AggressivePickDto, nullable: true })
  aggressive_pick: AggressivePickDto | null;

  @ApiProperty({ type: HtFtPredictionDto, required: false })
  htft?: HtFtPredictionDto;

  @ApiProperty({ type: [ScenarioTop5ItemDto] })
  scenario_top5: ScenarioTop5ItemDto[];

  @ApiProperty({ type: ScorePredictionDto })
  score_prediction: ScorePredictionDto;

  @ApiProperty({ type: Object })
  market_board: Record<string, unknown>;

  @ApiProperty({ type: [String] })
  reasoning_factors: string[];

  @ApiProperty({ type: Object, required: false })
  market_reliability?: Record<string, number>;

  @ApiProperty({ type: Object, required: false })
  shadow_engine?: Record<string, unknown>;

  @ApiProperty({ type: Object, required: false })
  surprise_hunter?: Record<string, unknown>;

  @ApiProperty({
    type: Object,
    required: false,
    description:
      "V28 Odds-Band engine output: historical band analytics, triple-value detection, cards profiling, and HTFT 9-combo analysis",
  })
  v27_engine?: Record<string, unknown>;
}

export class ValueBetDto {
  @ApiProperty()
  matchId: string;

  @ApiProperty()
  matchName: string;

  @ApiProperty()
  betType: string;

  @ApiProperty()
  prediction: string;

  @ApiProperty()
  confidence: number;

  @ApiProperty()
  odd: number;

  @ApiProperty()
  expectedValue: number;
}

export class PredictionHistoryStatsDto {
  @ApiProperty()
  totalPredictions: number;

  @ApiProperty()
  totalResolved: number;

  @ApiProperty()
  correctPredictions: number;

  @ApiProperty()
  accuracyRate: number;
}

export class PredictionHistoryResponseDto {
  @ApiProperty({ type: PredictionHistoryStatsDto })
  stats: PredictionHistoryStatsDto;

  @ApiProperty({ type: [Object] })
  history: Record<string, unknown>[];
}

export class UpcomingPredictionsDto {
  @ApiProperty()
  count: number;

  @ApiProperty({ type: [MatchPredictionDto] })
  matches: MatchPredictionDto[];

  @ApiProperty()
  modelVersion: string;
}

export class AIHealthDto {
  @ApiProperty()
  status: string;

  @ApiProperty()
  modelLoaded: boolean;

  @ApiProperty()
  predictionServiceReady: boolean;

  @ApiProperty({ required: false, default: true })
  aiEngineReachable?: boolean;

  @ApiProperty({ required: false, enum: ["closed", "open"] })
  circuitState?: "closed" | "open";

  @ApiProperty({ required: false, default: 0 })
  consecutiveFailures?: number;

  @ApiProperty({ required: false })
  endpoint?: string;

  @ApiProperty({ required: false, nullable: true })
  detail?: string | null;

  @ApiProperty({ required: false, nullable: true })
  mode?: string | null;
}

export * from "./smart-coupon.dto";
