import { Body, Controller, Delete, Get, HttpCode, Param, ParseIntPipe, Post, Patch } from '@nestjs/common';
import { IsString } from 'class-validator';
import { RecipesService } from './recipes.service';
import { CreateRecipeDto } from './dto/create-recipe.dto';
import { ParseMarkdownDto } from './dto/parse-markdown.dto';
import { CurrentUser } from '../auth/decorators/current-user.decorator';
import { ShareRecipeDto } from './dto/share-recipe.dto';
import { SetRecipeVisibilityDto } from './dto/set-recipe-visibility.dto';

class UpdateImageDto {
  @IsString()
  sourceUrl!: string;
}

@Controller('recipes')
export class RecipesController {
  constructor(private readonly recipesService: RecipesService) {}

  @Post('parse-markdown')
  parseMarkdown(@Body() dto: ParseMarkdownDto) {
    return this.recipesService.parseMarkdown(dto);
  }

  @Get()
  findAll(@CurrentUser() user: { userId: number }) {
    return this.recipesService.findAll(user.userId);
  }

  @Get(':id/inventory-preview')
  getInventoryPreview(
    @Param('id', ParseIntPipe) id: number,
    @CurrentUser() user: { userId: number },
  ) {
    return this.recipesService.getInventoryPreview(id, user.userId);
  }

  @Get(':id')
  findOne(
    @Param('id', ParseIntPipe) id: number,
    @CurrentUser() user: { userId: number },
  ) {
    return this.recipesService.findOne(id, user.userId);
  }

  @Post()
  async create(
    @Body() createRecipeDto: CreateRecipeDto,
    @CurrentUser() user: { userId: number },
  ) {
    return this.recipesService.create(createRecipeDto, user.userId);
  }

  @Patch(':id')
  async update(
    @Param('id', ParseIntPipe) id: number,
    @Body() createRecipeDto: CreateRecipeDto,
    @CurrentUser() user: { userId: number },
  ) {
    return this.recipesService.update(id, createRecipeDto, user.userId);
  }

  @Delete(':id')
  @HttpCode(204)
  async remove(
    @Param('id', ParseIntPipe) id: number,
    @CurrentUser() user: { userId: number },
  ) {
    return this.recipesService.remove(id, user.userId);
  }

  @Post(':id/image')
  async updateImage(
    @Param('id', ParseIntPipe) id: number,
    @Body() dto: UpdateImageDto,
    @CurrentUser() user: { userId: number },
  ) {
    return this.recipesService.updateImage(id, dto.sourceUrl, user.userId);
  }

  @Patch(':id/visibility')
  async setVisibility(
    @Param('id', ParseIntPipe) id: number,
    @Body() dto: SetRecipeVisibilityDto,
    @CurrentUser() user: { userId: number },
  ) {
    return this.recipesService.setVisibility(id, user.userId, dto.isPublic);
  }

  @Post(':id/share')
  async shareRecipe(
    @Param('id', ParseIntPipe) id: number,
    @Body() dto: ShareRecipeDto,
    @CurrentUser() user: { userId: number },
  ) {
    return this.recipesService.shareWithUser(id, user.userId, dto.username.trim());
  }

  @Delete(':id/share/:username')
  async unshareRecipe(
    @Param('id', ParseIntPipe) id: number,
    @Param('username') username: string,
    @CurrentUser() user: { userId: number },
  ) {
    return this.recipesService.unshareWithUser(id, user.userId, username.trim());
  }
}