import {
  Body,
  ClassSerializerInterceptor,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  Query,
  UseInterceptors,
} from '@nestjs/common';
import { MealsService } from './meals.service';
import { ApiTags } from '@nestjs/swagger';
import {
  RetrieveMealsForTheWeekQueryParamsDto,
  RetrieveMealsForTheWeekResponseDto,
} from './dtos/retrieve-meals-for-the-week.dto';
import { AcceptLanguage } from '../../../../shared/decorators/headers/accept-language.decorator';
import { IUser, User } from '../../../../shared/decorators/auth/user.decorator';
import {
  ApiDefaultResponseStatus,
  ApiResponseStatuses,
} from '../../../../shared/decorators/swagger/api-response-statuses.decorator';
import { SingleIdParamsDto } from '../../../../shared/dtos/params/single-id-params.dto';
import { RetrieveMealResponseDto } from './dtos/retrieve-meal.dto';
import { CreateMealDto } from './dtos/create-meal.dto';
import {
  RetrieveMealsTimesQueryParamsDto,
  RetrieveMealsTimesResponseDto,
} from './dtos/retrieve-meals-times.dto';
import { UpdateMealDto } from './dtos/update-meal.dto';

@ApiTags('Meals')
@Controller('meals')
export class MealsController {
  constructor(private readonly _mealsService: MealsService) {}

  @Get('week')
  @ApiDefaultResponseStatus(200, RetrieveMealsForTheWeekResponseDto)
  @ApiResponseStatuses(400, 401, 431, 502)
  @UseInterceptors(ClassSerializerInterceptor)
  async retrieveMealsForTheWeek(
    @AcceptLanguage() locale: string,
    @Query() queryParams: RetrieveMealsForTheWeekQueryParamsDto,
    @User() user: IUser,
  ): Promise<RetrieveMealsForTheWeekResponseDto> {
    return this._mealsService.retrieveMealsForTheWeek(
      queryParams,
      locale,
      user,
    );
  }

  @Get('times')
  @ApiDefaultResponseStatus(200, RetrieveMealsTimesResponseDto)
  @ApiResponseStatuses(400, 502)
  async retrieveMealsTimes(
    @Query() queryParams: RetrieveMealsTimesQueryParamsDto,
  ): Promise<RetrieveMealsTimesResponseDto> {
    return this._mealsService.retrieveMealsTimes(queryParams);
  }

  @Get(':id')
  @ApiDefaultResponseStatus(200, RetrieveMealResponseDto)
  @ApiResponseStatuses(400, 401, 404, 502)
  @UseInterceptors(ClassSerializerInterceptor)
  async retrieveMeal(
    @Param() params: SingleIdParamsDto,
    @User() user: IUser,
  ): Promise<RetrieveMealResponseDto> {
    return this._mealsService.retrieveMeal(params, user);
  }

  @Post()
  @ApiDefaultResponseStatus(200, RetrieveMealResponseDto)
  @ApiResponseStatuses(400, 401, 409, 500, 502)
  @UseInterceptors(ClassSerializerInterceptor)
  async createMeal(
    @Body() meal: CreateMealDto,
    @User() user: IUser,
  ): Promise<RetrieveMealResponseDto> {
    return this._mealsService.createMeal(meal, user);
  }

  @Patch(':id')
  @ApiDefaultResponseStatus(200, RetrieveMealResponseDto)
  @ApiResponseStatuses(400, 401, 403, 404, 409, 502)
  @UseInterceptors(ClassSerializerInterceptor)
  async updateMeal(
    @Param() params: SingleIdParamsDto,
    @Body() meal: UpdateMealDto,
    @User() user: IUser,
  ): Promise<RetrieveMealResponseDto> {
    return this._mealsService.updateMeal(params, meal, user);
  }

  @Delete(':id')
  @ApiDefaultResponseStatus(200, RetrieveMealResponseDto)
  @ApiResponseStatuses(400, 401, 404, 502)
  @UseInterceptors(ClassSerializerInterceptor)
  async deleteMeal(
    @Param() params: SingleIdParamsDto,
    @User() user: IUser,
  ): Promise<RetrieveMealResponseDto> {
    return this._mealsService.deleteMeal(params, user);
  }
}
