import {
  Controller,
  Get,
  Post,
  Body,
  Param,
  HttpCode,
  HttpStatus,
  NotFoundException,
} from "@nestjs/common";
import { ApiTags, ApiOperation, ApiResponse, ApiParam } from "@nestjs/swagger";
import { PredictionsService } from "./predictions.service";
import {
  MatchPredictionDto,
  PredictionHistoryResponseDto,
  UpcomingPredictionsDto,
  ValueBetDto,
  AIHealthDto,
} from "./dto";
import {
  GeneratePredictionDto,
  SmartCouponRequestDto,
} from "./dto/predictions-request.dto";
import { Public } from "src/common/decorators";

@ApiTags("Predictions")
@Controller("predictions")
export class PredictionsController {
  constructor(private readonly predictionsService: PredictionsService) {}

  /**
   * GET /predictions/health
   * Check AI Engine health status
   */
  @Get("health")
  @ApiOperation({ summary: "Check AI Engine health status" })
  @ApiResponse({ status: 200, type: AIHealthDto })
  async checkHealth(): Promise<AIHealthDto> {
    return this.predictionsService.checkHealth();
  }

  /**
   * GET /predictions/upcoming
   * Get predictions for upcoming matches
   */
  @Get("upcoming")
  @ApiOperation({ summary: "Get predictions for upcoming matches" })
  @ApiResponse({ status: 200, type: UpcomingPredictionsDto })
  async getUpcoming(): Promise<UpcomingPredictionsDto> {
    return this.predictionsService.getUpcomingPredictions();
  }

  /**
   * GET /predictions/test/:id
   * Refetch match data and get prediction
   */
  @Get("test/:id")
  @ApiOperation({ summary: "Refetch match data and get prediction" })
  @ApiResponse({
    status: 200,
    description: "Prediction details",
    schema: { type: "object" },
  })
  @ApiParam({ name: "id", description: "Match ID" })
  async getTestPrediction(@Param("id") id: string) {
    return this.predictionsService.testPrediction(id);
  }

  /**
   * GET /predictions/value-bets
   * Get EV+ betting opportunities
   */
  @Get("value-bets")
  @ApiOperation({ summary: "Get value betting opportunities (EV+)" })
  @ApiResponse({ status: 200, type: [ValueBetDto] })
  async getValueBets(): Promise<ValueBetDto[]> {
    return this.predictionsService.getValueBets();
  }

  /**
   * GET /predictions/history
   * Get prediction history and accuracy stats
   */
  @Get("history")
  @ApiOperation({ summary: "Get prediction history and accuracy statistics" })
  @ApiResponse({ status: 200, type: PredictionHistoryResponseDto })
  async getHistory(): Promise<PredictionHistoryResponseDto> {
    return this.predictionsService.getPredictionHistory();
  }

  /**
   * GET /predictions/:matchId
   * Get prediction for a specific match
   */
  @Get(":matchId")
  @Public()
  @ApiOperation({ summary: "Get prediction for a specific match" })
  @ApiParam({ name: "matchId", description: "Match ID" })
  @ApiResponse({
    status: 200,
    description: "Match prediction",
    schema: { type: "object" },
    type: MatchPredictionDto,
  })
  @ApiResponse({ status: 404, description: "Match not found" })
  async getPrediction(
    @Param("matchId") matchId: string,
  ): Promise<MatchPredictionDto> {
    const cached = await this.predictionsService.getCachedPrediction(matchId);
    if (cached) {
      return cached;
    }

    // Get from AI Engine
    const prediction = await this.predictionsService.getPredictionById(matchId);

    if (!prediction) {
      throw new NotFoundException(`Match not found: ${matchId}`);
    }

    return prediction;
  }

  /**
   * POST /predictions/generate
   * Generate prediction with provided match data
   */
  @Post("generate")
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: "Generate prediction with provided match data" })
  @ApiResponse({ status: 200, type: MatchPredictionDto })
  async generatePrediction(
    @Body() dto: GeneratePredictionDto,
  ): Promise<MatchPredictionDto> {
    const prediction = await this.predictionsService.getPredictionWithData({
      matchId: dto.matchId,
    });

    if (!prediction) {
      throw new NotFoundException("Failed to generate prediction");
    }

    return prediction;
  }

  /**
   * POST /predictions/smart-coupon
   * Generate Smart Coupon using AI Engine V20
   */
  @Post("smart-coupon")
  @HttpCode(HttpStatus.OK)
  @ApiOperation({
    summary: "Generate Smart Coupon with V20 AI recommendations",
  })
  @ApiResponse({
    status: 200,
    description: "Smart coupon generated successfully",
    schema: { type: "object" },
  })
  async generateSmartCoupon(@Body() dto: SmartCouponRequestDto): Promise<any> {
    const coupon = await this.predictionsService.getSmartCoupon(
      dto.matchIds,
      dto.strategy || "BALANCED",
      {
        maxMatches: dto.maxMatches,
        minConfidence: dto.minConfidence,
      },
    );

    if (!coupon) {
      throw new NotFoundException("Failed to generate Smart Coupon");
    }

    return coupon;
  }
}
