import {
  isForecastNotReadyResponse,
  type PublicForecastInputQuality,
  type PublicInsightAvailability,
  type PublicForecastLegacyPayloadV1,
  type PublicForecastModelSignals,
  type PublicForecastNotReadyResponseV1,
  type PublicForecastResponseV1,
} from '@/contracts/forecast-public';

export interface ForecastOdds {
  moneyline: { home: number | null; away: number | null };
  spread: { home: { line: number; odds: number | null } | null; away: { line: number; odds: number | null } | null };
  total: { over: { line: number; odds: number | null } | null; under: { line: number; odds: number | null } | null };
}

export interface ForecastOpeningLines {
  moneyline?: { home: number | null; away: number | null } | null;
  spread?: { home: { line: number; odds: number | null } | null; away: { line: number; odds: number | null } | null } | null;
  total?: { over: { line: number; odds: number | null } | null; under: { line: number; odds: number | null } | null } | null;
}

export interface ForecastModelLines {
  moneyline?: { home: number | null; away: number | null } | null;
  spread?: { home: number | null; away: number | null } | null;
  total?: number | null;
}

export interface ForecastMaterialChange {
  detected_at: string;
  refresh_type: string;
  changes: Array<{ type: string; market?: string; old: number; new: number; delta: number }>;
  banner_text: string;
}

export interface ForecastRieSignal {
  signalId?: string;
  score?: number | null;
  available?: boolean;
  weight?: number | null;
  metadata?: { source?: string } | null;
}

export interface ForecastRagInsight {
  query?: string;
  applicableTheory?: string;
  topChunks?: Array<{ source?: string }>;
}

export interface ForecastBasemonSummary {
  available?: boolean;
  totalLockCount?: number;
  totalPlayCount?: number;
  markets?: Array<{
    market: string;
    lockCount: number;
    playCount: number;
    leanCount: number;
    skipCount: number;
  }>;
  topPicks?: Array<{
    market: string;
    player: string;
    line: number;
    direction: string;
    verdict: string;
    edge?: number | null;
    modelProb?: number | null;
    impliedProb?: number | null;
    note?: string | null;
  }>;
}

export interface ForecastModalState {
  eventId: string;
  isFreePick?: boolean;
  notReady?: boolean;
  forecast: PublicForecastLegacyPayloadV1 | Record<string, unknown>;
  confidence: number;
  homeTeam: string;
  awayTeam: string;
  homeShort?: string;
  awayShort?: string;
  league: string;
  alreadyOwned?: boolean;
  odds?: ForecastOdds | null;
  openingLines?: ForecastOpeningLines | null;
  modelLines?: ForecastModelLines | null;
  compositeConfidence?: PublicForecastResponseV1['compositeConfidence'];
  forecastVersion?: PublicForecastResponseV1['forecastVersion'];
  staticCommit?: PublicForecastResponseV1['staticCommit'];
  generatedAt?: PublicForecastResponseV1['generatedAt'];
  lastRefreshAt?: PublicForecastResponseV1['lastRefreshAt'];
  lastRefreshType?: PublicForecastResponseV1['lastRefreshType'];
  materialChange?: ForecastMaterialChange | null;
  insightAvailability?: PublicForecastResponseV1['insightAvailability'] | PublicForecastNotReadyResponseV1['insightAvailability'];
  unlockedInsights?: PublicForecastResponseV1['unlockedInsights'] | PublicForecastNotReadyResponseV1['unlockedInsights'];
  unlockedInsightData?: PublicForecastResponseV1['unlockedInsightData'] | PublicForecastNotReadyResponseV1['unlockedInsightData'];
  basemonSummary?: ForecastBasemonSummary | null;
  modelSignals?: PublicForecastModelSignals | null;
  inputQuality?: PublicForecastInputQuality | null;
  rieSignals?: ForecastRieSignal[] | null;
  ragInsights?: ForecastRagInsight[] | null;
  strategyId?: PublicForecastResponseV1['strategyId'];
  mlbPhaseContext?: PublicForecastResponseV1['mlbPhaseContext'];
  mlbMatchupContext?: PublicForecastResponseV1['mlbMatchupContext'];
  forecastBalance?: PublicForecastResponseV1['forecastBalance'];
  forecast_balance?: PublicForecastResponseV1['forecast_balance'];
}

export interface ForecastPreviewModalState {
  eventId: string;
  league: string;
  winnerPick: string | null;
  forecastSide: string | null;
  projectedWinner: string | null;
  confidence: number;
  summaryPreview: string | null;
  odds: ForecastOdds | null;
  modelEdge: number | null;
  homeTeam: string;
  awayTeam: string;
  homeShort: string;
  awayShort: string;
  valueRating: number | null;
  insightAvailability: PublicInsightAvailability;
  basemonSummary: ForecastBasemonSummary | null;
}

export function toForecastModalState(
  data: PublicForecastResponseV1 | PublicForecastNotReadyResponseV1,
  eventId: string,
  extras?: { isFreePick?: boolean },
): ForecastModalState {
  if (isForecastNotReadyResponse(data)) {
    return {
      eventId,
      isFreePick: extras?.isFreePick,
      notReady: true,
      forecast: { status: 'not_ready' },
      confidence: 0,
      homeTeam: data.homeTeam,
      awayTeam: data.awayTeam,
      homeShort: data.homeShort,
      awayShort: data.awayShort,
      league: data.league,
      odds: (data.odds ?? null) as ForecastOdds | null,
      insightAvailability: data.insightAvailability,
      unlockedInsights: data.unlockedInsights,
      unlockedInsightData: data.unlockedInsightData,
    };
  }

  return {
    ...data,
    eventId,
    isFreePick: extras?.isFreePick,
    notReady: false,
    forecast: data.forecast,
    odds: (data.odds ?? null) as ForecastOdds | null,
    openingLines: (data.openingLines ?? null) as ForecastOpeningLines | null,
    modelLines: (data.modelLines ?? null) as ForecastModelLines | null,
    materialChange: (data.materialChange ?? null) as ForecastMaterialChange | null,
    basemonSummary: (data.basemonSummary ?? null) as ForecastBasemonSummary | null,
    modelSignals: (data.modelSignals ?? null) as PublicForecastModelSignals | null,
    inputQuality: (data.inputQuality ?? null) as PublicForecastInputQuality | null,
    rieSignals: (data.rieSignals ?? null) as ForecastRieSignal[] | null,
    ragInsights: (data.ragInsights ?? null) as ForecastRagInsight[] | null,
    confidence: data.confidence ?? 0,
  };
}

export function toForecastPreviewModalState(
  data: {
    winnerPick?: string | null;
    forecastSide?: string | null;
    projectedWinner?: string | null;
    confidence?: number | null;
    summaryPreview?: string | null;
    odds?: ForecastOdds | null;
    modelEdge?: number | null;
    homeTeam?: string | null;
    awayTeam?: string | null;
    homeShort?: string | null;
    awayShort?: string | null;
    valueRating?: number | null;
    insightAvailability?: PublicInsightAvailability | null;
    basemonSummary?: ForecastBasemonSummary | null;
  },
  eventId: string,
  league: string,
): ForecastPreviewModalState {
  return {
    eventId,
    league,
    winnerPick: data.winnerPick ?? null,
    forecastSide: data.forecastSide ?? null,
    projectedWinner: data.projectedWinner ?? null,
    confidence: data.confidence ?? 0,
    summaryPreview: data.summaryPreview ?? null,
    odds: data.odds ?? null,
    modelEdge: data.modelEdge ?? null,
    homeTeam: data.homeTeam ?? '',
    awayTeam: data.awayTeam ?? '',
    homeShort: data.homeShort ?? '',
    awayShort: data.awayShort ?? '',
    valueRating: data.valueRating ?? null,
    insightAvailability: data.insightAvailability ?? {
      steam: false,
      sharp: false,
      dvp: false,
      hcw: false,
    },
    basemonSummary: data.basemonSummary ?? null,
  };
}
