import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  Query,
  Req,
  Res,
  UseGuards,
} from "@nestjs/common";
import { Request, Response } from "express";
import { ParseObjectIdPipe } from "@nestjs/mongoose";
import { ExerciseService } from "./exercise.service";
import { UserAuthGuard } from "src/common/guards/jwt-auth.guard";
import { RolesGuard } from "src/common/guards/roles.guard";
import { Roles } from "src/common/decorator/roles.decorator";
import { RoleEnum } from "src/common/enums/constant.enum";
import { CreateExerciseDto } from "./dto/create-exercise.dto";
import { UpdateExerciseDto } from "./dto/update-exercise.dto";
import { CreateExerciseCategoryDto } from "./dto/create-exercise-category.dto";
import { UpdateExerciseCategoryDto } from "./dto/update-exercise-category.dto";
import { ApiBearerAuth, ApiTags } from "@nestjs/swagger";

@ApiTags("Exercise")
@ApiBearerAuth()
@Controller("exercise")
export class ExerciseController {
  constructor(private readonly exerciseService: ExerciseService) {}

  // ─── Category routes (must be before /:id routes) ────────────────────────

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN)
  @Post("category")
  createCategory(
    @Body() body: CreateExerciseCategoryDto,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    return this.exerciseService.createCategory(body, req, res);
  }

  @UseGuards(UserAuthGuard)
  @Roles(RoleEnum.ADMIN)
  @Get("category")
  getAllCategories(@Req() req: Request, @Res() res: Response) {
    return this.exerciseService.getAllCategories(req, res);
  }

  @UseGuards(UserAuthGuard)
  @Get("category/:id")
  getCategoryById(
    @Param("id", new ParseObjectIdPipe()) id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    return this.exerciseService.getCategoryById(id, req, res);
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN)
  @Patch("category/:id")
  updateCategory(
    @Param("id", new ParseObjectIdPipe()) id: string,
    @Body() body: UpdateExerciseCategoryDto,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    return this.exerciseService.updateCategory(id, body, req, res);
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN)
  @Delete("category/:id")
  deleteCategory(
    @Param("id", new ParseObjectIdPipe()) id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    return this.exerciseService.deleteCategory(id, req, res);
  }

  // ─── Exercise routes ──────────────────────────────────────────────────────

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN)
  @Post("create")
  createExercise(
    @Body() body: CreateExerciseDto,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    return this.exerciseService.createExercise(body, req, res);
  }

  @UseGuards(UserAuthGuard , RolesGuard)
  @Roles(RoleEnum.ADMIN , RoleEnum.USER)
  @Get("all")
  getAllExercisesNoPagination(
    @Req() req: Request,
    @Res() res: Response,
    @Query("categoryId") categoryId: string,
  ) {
    return this.exerciseService.getAllExercisesNoPagination(
      req,
      res,
      categoryId,
    );
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN , RoleEnum.USER)
  @Get()
  getAllExercises(
    @Req() req: Request,
    @Res() res: Response,
    @Query("page") page: number,
    @Query("limit") limit: number,
    @Query("search") search: string,
    @Query("status") status: string,
    @Query("categoryId") categoryId: string,
  ) {
    return this.exerciseService.getAllExercises(
      req,
      res,
      page,
      limit,
      search,
      status,
      categoryId,
    );
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN)
  @Get(":id")
  getExerciseById(
    @Param("id", new ParseObjectIdPipe()) id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    return this.exerciseService.getExerciseById(id, req, res);
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN)
  @Patch(":id")
  updateExercise(
    @Param("id", new ParseObjectIdPipe()) id: string,
    @Body() body: UpdateExerciseDto,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    return this.exerciseService.updateExercise(id, body, req, res);
  }

  @UseGuards(UserAuthGuard, RolesGuard)
  @Roles(RoleEnum.ADMIN)
  @Delete(":id")
  deleteExercise(
    @Param("id", new ParseObjectIdPipe()) id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    return this.exerciseService.deleteExercise(id, req, res);
  }
}
