import {
  Controller,
  Post,
  Get,
  Body,
  Query,
  HttpCode,
  HttpStatus,
  UseGuards,
  Req,
  Logger,
} from "@nestjs/common";
import {
  ApiTags,
  ApiBearerAuth,
  ApiOperation,
  ApiResponse,
} from "@nestjs/swagger";
import { CouponsService } from "./coupons.service";
import { MatchesService } from "../matches/matches.service";
import { SmartCouponService } from "./services/smart-coupon.service";
import {
  UserCouponService,
  CreateCouponDto,
} from "./services/user-coupon.service";
import {
  AnalyzeMatchDto,
  DailyBankoDto,
  SuggestCouponDto,
  FrequencyCouponDto,
} from "./dto/coupons-request.dto";
import { Public } from "../../common/decorators";
import { JwtAuthGuard } from "../auth/guards/auth.guards"; // Assuming standard guard
import { Sport } from "../matches/dto";

@ApiTags("Coupon")
@Controller("coupon")
export class CouponsController {
  private readonly logger = new Logger(CouponsController.name);

  constructor(
    private readonly couponsService: CouponsService,
    private readonly smartCouponService: SmartCouponService,
    private readonly userCouponService: UserCouponService,
    private readonly matchesService: MatchesService,
  ) {}

  /**
   * POST /coupon/analyze-match
   * Analyze a single match with V20+ single-match package
   */
  @Post("analyze-match")
  @Public()
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: "Analyze single match with V20 model" })
  @ApiResponse({
    status: 200,
    description: "Match analysis",
    schema: {
      type: "object",
      properties: {
        success: { type: "boolean" },
        data: { type: "object" },
        message: { type: "string" },
      },
    },
  })
  async analyzeMatch(@Body() dto: AnalyzeMatchDto) {
    const analysis = await this.smartCouponService.analyzeMatch(dto.matchId);
    if (!analysis) {
      return { success: false, message: "Analiz yapılamadı." };
    }
    return { success: true, data: analysis };
  }

  /**
   * POST /coupon/analyze (alias for /analyze-match - frontend compatibility)
   */
  @Post("analyze")
  @Public()
  @HttpCode(HttpStatus.OK)
  @ApiOperation({
    summary: "Analyze single match with V20 model (alias)",
    deprecated: true,
  })
  async analyzeMatchAlias(@Body() dto: AnalyzeMatchDto) {
    return this.analyzeMatch(dto);
  }

  /**
   * POST /coupon
   * Alias for /coupon/create - frontend compatibility
   */
  @Post()
  @UseGuards(JwtAuthGuard)
  @ApiBearerAuth()
  @HttpCode(HttpStatus.CREATED)
  @ApiOperation({ summary: "Create and save a user coupon (alias)" })
  async createCouponAlias(@Body() dto: CreateCouponDto, @Req() req: any) {
    return this.createCoupon(dto, req);
  }

  /**
   * POST /coupon/daily-banko
   * Generate a high-confidence banko combo (2 matches)
   */
  @Post("daily-banko")
  @Public()
  @HttpCode(HttpStatus.OK)
  @ApiOperation({
    summary: "Generate a high-confidence banko combo (2 matches)",
  })
  @ApiResponse({
    status: 200,
    description: "Daily banko coupon",
    schema: {
      type: "object",
      properties: {
        success: { type: "boolean" },
        data: { type: "object" },
        message: { type: "string" },
      },
    },
  })
  async getDailyBanko(@Body() dto: DailyBankoDto) {
    // If no match IDs provided, fetch from system (top 50 upcoming)
    let candidateMatches = dto.matchIds || [];
    if (candidateMatches.length === 0) {
      candidateMatches = await this.matchesService.findUpcomingMatches(
        Sport.FOOTBALL,
        20,
      );
      this.logger.debug(
        `Auto-fetched ${candidateMatches.length} matches for daily-banko`,
      );
    } else {
      candidateMatches = await this.matchesService.filterUpcomingMatchIds(
        candidateMatches,
        Sport.FOOTBALL,
      );
      this.logger.debug(
        `Sanitized candidate matches for daily-banko: ${candidateMatches.length}`,
      );
    }

    if (candidateMatches.length === 0) {
      return {
        success: false,
        message: "Kupon iÃ§in uygun, henÃ¼z baÅŸlamamÄ±ÅŸ maÃ§ bulunamadÄ±.",
      };
    }

    const coupon =
      await this.smartCouponService.generateDailyBankoCoupon(candidateMatches);
    if (!coupon) {
      return {
        success: false,
        message: "Kriterlere uygun (80%+ güvenli) yeterli maç bulunamadı.",
      };
    }
    return { success: true, data: coupon };
  }

  /**
   * POST /coupon/suggest
   * Generate Smart Coupon
   */
  @Post("suggest")
  @Public()
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: "Suggest Smart Coupon" })
  @ApiResponse({
    status: 200,
    description: "Smart Coupon generated",
    schema: {
      type: "object",
      properties: {
        success: { type: "boolean" },
        data: { type: "object" },
        message: { type: "string" },
      },
    },
  })
  async suggestCoupon(@Body() dto: SuggestCouponDto) {
    // If no match IDs provided, fetch from system (top 50 upcoming)
    let candidateMatches = dto.matchIds || [];
    if (candidateMatches.length === 0) {
      candidateMatches = await this.matchesService.findUpcomingMatches(
        Sport.FOOTBALL,
        20,
      );
      this.logger.debug(
        `Auto-fetched ${candidateMatches.length} matches for suggest`,
      );
    } else {
      candidateMatches = await this.matchesService.filterUpcomingMatchIds(
        candidateMatches,
        Sport.FOOTBALL,
      );
      this.logger.debug(
        `Sanitized candidate matches for suggest: ${candidateMatches.length}`,
      );
    }

    if (candidateMatches.length === 0) {
      return {
        success: false,
        message: "Tahmin iÃ§in uygun, henÃ¼z baÅŸlamamÄ±ÅŸ maÃ§ bulunamadÄ±.",
      };
    }

    const coupon = await this.smartCouponService.getSmartCoupon(
      candidateMatches,
      dto.strategy,
      {
        maxMatches: dto.maxMatches,
        minConfidence: dto.minConfidence,
      },
    );
    if (!coupon) {
      return { success: false, message: "Kupon oluşturulamadı." };
    }
    return { success: true, data: coupon };
  }

  /**
   * POST /coupon/frequency-coupon
   * Generate a frequency-based parlay coupon (Conditional Frequency Engine)
   */
  @Post("frequency-coupon")
  @Public()
  @HttpCode(HttpStatus.OK)
  @ApiOperation({
    summary: "Generate frequency-based parlay coupon",
    description:
      "Scans upcoming matches, applies conditional frequency analysis " +
      "(team odds-band performance), and builds 2-5 match combos with +EV calculation.",
  })
  @ApiResponse({ status: 200, description: "Frequency coupon generated" })
  async getFrequencyCoupon(@Body() dto: FrequencyCouponDto) {
    const coupon = await this.smartCouponService.generateFrequencyBasedCoupon({
      matchIds: dto.matchIds,
      maxMatches: dto.maxMatches,
      minSignal: dto.minSignal,
      markets: dto.markets,
    });

    if (!coupon || coupon.bets.length === 0) {
      return {
        success: false,
        message:
          "Frekans analizine uygun yeterli maç bulunamadı. " +
          "minSignal değerini düşürmeyi veya daha fazla maç beklemeyi deneyin.",
        data: coupon,
      };
    }

    return { success: true, data: coupon };
  }

  // ============================================
  // USER COUPON ENDPOINTS
  // ============================================

  /**
   * POST /coupon/create
   * Save a user generated coupon
   */
  @Post("create")
  @UseGuards(JwtAuthGuard)
  @ApiBearerAuth()
  @HttpCode(HttpStatus.CREATED)
  @ApiOperation({ summary: "Create and save a user coupon" })
  @ApiResponse({
    status: 201,
    description: "Coupon created",
    schema: {
      type: "object",
      properties: {
        success: { type: "boolean" },
        data: { type: "object" },
        message: { type: "string" },
      },
    },
  })
  async createCoupon(@Body() dto: CreateCouponDto, @Req() req: any) {
    // req.user is populated by JwtAuthGuard
    const coupon = await this.userCouponService.createCoupon(req.user, dto);
    return { success: true, data: coupon };
  }

  /**
   * GET /coupon/my-stats
   * Get user betting statistics (ROI, Win Rate)
   */
  @Get("my-stats")
  @UseGuards(JwtAuthGuard)
  @ApiBearerAuth()
  @ApiOperation({ summary: "Get user betting statistics" })
  @ApiResponse({
    status: 200,
    description: "User statistics",
    schema: {
      type: "object",
      properties: {
        success: { type: "boolean" },
        data: { type: "object" },
        message: { type: "string" },
      },
    },
  })
  async getUserStats(@Req() req: any) {
    const stats = await this.userCouponService.getUserStatistics(req.user.id);
    return { success: true, data: stats };
  }

  /**
   * GET /coupon/history
   * Get coupon history (Public/System coupons)
   */
  @Get("history")
  @ApiBearerAuth()
  @ApiOperation({ summary: "Get coupon history" })
  @ApiResponse({
    status: 200,
    description: "History retrieved",
    schema: {
      type: "object",
      properties: {
        success: { type: "boolean" },
        data: { type: "array", items: { type: "object" } },
        message: { type: "string" },
      },
    },
  })
  async getHistory(@Query("limit") limit?: string) {
    // eslint-disable-next-line @typescript-eslint/await-thenable
    const results = await this.couponsService.getCouponHistory(
      Number(limit) || 10,
    );
    return { success: true, data: results };
  }
}
