import {
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Param,
  Delete,
  UseGuards,
  Req,
  Res,
  Query,
} from "@nestjs/common";
import { ApiBearerAuth, ApiQuery, ApiTags } from "@nestjs/swagger";
import { Request, Response } from "express";
import { StrengthService } from "./strength.service";
import { CreateManualPerformanceDto } from "./dto/create-manual-performance.dto";
import { UpdateManualPerformanceDto } from "./dto/update-manual-performance.dto";
import { UserAuthGuard } from "src/common/guards/jwt-auth.guard";
import { UserDecorator } from "src/common/decorator/user.decorator";

@ApiTags("Strength")
@ApiBearerAuth()
@Controller("strength")
export class StrengthController {
  constructor(private readonly strengthService: StrengthService) {}

  // POST /strength/manual-performance — log one or more exercises for a date (upsert)
  @UseGuards(UserAuthGuard)
  @Post("manual-performance")
  async create(
    @Body() dto: CreateManualPerformanceDto,
    @Req() req: Request,
    @Res() res: Response,
    @UserDecorator() user: any,
  ) {
    return this.strengthService.create(dto, req, res, user);
  }

  // GET /strength/graph/:exerciseId?period=7d|30d|3m|6m|all — strength progression chart
  @UseGuards(UserAuthGuard)
  @Get("graph/:exerciseId")
  @ApiQuery({
    name: "period",
    required: false,
    enum: ["7d", "30d", "3m", "6m", "all"],
    example: "7d",
  })
  async getStrengthGraph(
    @Param("exerciseId") exerciseId: string,
    @Query("period") period = "7d",
    @Req() req: Request,
    @Res() res: Response,
    @UserDecorator() user: any,
  ) {
    const allowed = ["7d", "30d", "3m", "6m", "all"];
    const safePeriod = (allowed.includes(period) ? period : "7d") as any;
    return this.strengthService.getStrengthGraph(
      exerciseId,
      safePeriod,
      req,
      res,
      user,
    );
  }

  // GET /strength/entries/:exerciseId?period=7d|30d|3m|6m|all
  // All entries for one exercise (Top Set per day) across workout sessions,
  // manual performances and PRs, honouring the period filter.
  @UseGuards(UserAuthGuard)
  @Get("entries/:exerciseId")
  @ApiQuery({
    name: "period",
    required: false,
    enum: ["7d", "30d", "3m", "6m", "all"],
    example: "30d",
  })
  
  async getExerciseEntries(
    @Param("exerciseId") exerciseId: string,
    @Query("period") period = "30d",
    @Req() req: Request,
    @Res() res: Response,
    @UserDecorator() user: any,
  ) {
    const allowed = ["7d", "30d", "3m", "6m", "all"];
    const safePeriod = (allowed.includes(period) ? period : "30d") as any;
    return this.strengthService.getExerciseEntries(
      exerciseId,
      safePeriod,
      req,
      res,
      user,
    );
  }

  // GET /strength/manual-performance/personal-records — best set per exercise across all sessions
  @UseGuards(UserAuthGuard)
  @Get("personal-records")
  async getPersonalRecords(
    @Req() req: Request,
    @Res() res: Response,
    @UserDecorator() user: any,
  ) {
    return this.strengthService.getPersonalRecords(req, res, user);
  }

  // GET /strength/manual-performance/personal-records/:exerciseId — PR progression for one exercise
  @UseGuards(UserAuthGuard)
  @Get("personal-records/:exerciseId")
  async getPersonalRecordHistory(
    @Param("exerciseId") exerciseId: string,
    @Req() req: Request,
    @Res() res: Response,
    @UserDecorator() user: any,
  ) {
    return this.strengthService.getPersonalRecordHistory(
      exerciseId,
      req,
      res,
      user,
    );
  }

  // GET /strength/manual-performance/history/:exerciseId — full history for one exercise (All entries screen)
  @UseGuards(UserAuthGuard)
  @Get("history/:exerciseId")
  @ApiQuery({ name: "page", required: false, example: 1 })
  @ApiQuery({ name: "limit", required: false, example: 10 })
  async getExerciseHistory(
    @Param("exerciseId") exerciseId: string,
    @Query("page") page = "1",
    @Query("limit") limit = "10",
    @Req() req: Request,
    @Res() res: Response,
    @UserDecorator() user: any,
  ) {
    return this.strengthService.getExerciseHistory(
      exerciseId,
      +page,
      +limit,
      res,
      req,
      user,
    );
  }

  // GET /strength/manual-performance?date=YYYY-MM-DD — all exercises logged on a specific date
  @UseGuards(UserAuthGuard)
  @Get()
  @ApiQuery({ name: "date", required: true, example: "2025-06-29" })
  async getByDate(
    @Query("date") date: string,
    @Req() req: Request,
    @Res() res: Response,
    @UserDecorator() user: any,
  ) {
    return this.strengthService.getByDate(date, req, res, user);
  }

  // PATCH /strength/manual-performance/:id — update sets for a specific exercise log
  @UseGuards(UserAuthGuard)
  @Patch("/manual-performance/:id")
  async update(
    @Param("id") id: string,
    @Body() dto: UpdateManualPerformanceDto,
    @Req() req: Request,
    @Res() res: Response,
    @UserDecorator() user: any,
  ) {
    return this.strengthService.update(id, dto, req, res, user);
  }

  // DELETE /strength/manual-performance/:id — soft delete one exercise log
  @UseGuards(UserAuthGuard)
  @Delete("/manual-performance/:id")
  async remove(
    @Param("id") id: string,
    @Req() req: Request,
    @Res() res: Response,
    @UserDecorator() user: any,
  ) {
    return this.strengthService.remove(id, req, res, user);
  }
}
