package app.mealsmadeeasy.api.recipe;

import app.mealsmadeeasy.api.file.File;
import app.mealsmadeeasy.api.file.FileService;
import app.mealsmadeeasy.api.recipe.body.RecipeDraftUpdateBody;
import app.mealsmadeeasy.api.recipe.converter.RecipeDraftToViewConverter;
import app.mealsmadeeasy.api.recipe.converter.RecipeDraftUpdateBodyToSpecConverter;
import app.mealsmadeeasy.api.recipe.converter.RecipeToFullViewConverter;
import app.mealsmadeeasy.api.recipe.spec.RecipeDraftUpdateSpec;
import app.mealsmadeeasy.api.recipe.view.FullRecipeView;
import app.mealsmadeeasy.api.recipe.view.RecipeDraftView;
import app.mealsmadeeasy.api.user.User;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/recipe-drafts")
@RequiredArgsConstructor
public class RecipeDraftsController {

    private final RecipeService recipeService;
    private final FileService fileService;
    private final RecipeDraftUpdateBodyToSpecConverter updateBodyToSpecConverter;
    private final RecipeDraftToViewConverter draftToViewConverter;
    private final RecipeToFullViewConverter recipeToFullViewConverter;

    @GetMapping
    public ResponseEntity<List<RecipeDraftView>> getAllDraftsForUser(@AuthenticationPrincipal User user) {
        final List<RecipeDraft> recipeDrafts = this.recipeService.getDrafts(user);
        return ResponseEntity.ok(recipeDrafts.stream()
                .map(recipeDraft -> this.draftToViewConverter.convert(recipeDraft, user))
                .toList()
        );
    }

    @GetMapping("/{id}")
    public ResponseEntity<RecipeDraftView> getRecipeDraft(
            @PathVariable UUID id,
            @AuthenticationPrincipal User viewer
    ) {
        final RecipeDraft recipeDraft = this.recipeService.getDraftByIdWithViewer(id, viewer);
        return ResponseEntity.ok(this.draftToViewConverter.convert(recipeDraft, viewer));
    }

    @PostMapping("/manual")
    public ResponseEntity<RecipeDraftView> createManualDraft(@AuthenticationPrincipal User owner) {
        final RecipeDraft recipeDraft = this.recipeService.createDraft(owner);
        return ResponseEntity.status(HttpStatus.CREATED).body(this.draftToViewConverter.convert(recipeDraft, owner));
    }

    @PostMapping("/ai")
    public ResponseEntity<RecipeDraftView> createAiDraft(
            @AuthenticationPrincipal User owner,
            @RequestParam MultipartFile sourceFile,
            @RequestParam String sourceFileName
    ) throws IOException {
        final File file = this.fileService.create(
                sourceFile.getInputStream(),
                sourceFileName,
                sourceFile.getSize(),
                owner
        );
        final RecipeDraft recipeDraft = this.recipeService.createAiDraft(file, owner);
        return ResponseEntity.status(HttpStatus.CREATED).body(this.draftToViewConverter.convert(recipeDraft, owner));
    }

    @PutMapping("/{id}")
    public ResponseEntity<RecipeDraftView> updateRecipeDraft(
            @AuthenticationPrincipal User modifier,
            @PathVariable UUID id,
            @RequestBody RecipeDraftUpdateBody updateBody
    ) {
        final RecipeDraftUpdateSpec spec = this.updateBodyToSpecConverter.convert(updateBody, modifier);
        final RecipeDraft updated = this.recipeService.updateDraft(id, spec, modifier);
        return ResponseEntity.ok(this.draftToViewConverter.convert(updated, modifier));
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteRecipeDraft(
            @AuthenticationPrincipal User modifier,
            @PathVariable UUID id
    ) {
        this.recipeService.deleteDraft(id, modifier);
        return ResponseEntity.noContent().build();
    }

    @PostMapping("/{id}/publish")
    public ResponseEntity<FullRecipeView> publishRecipeDraft(
            @AuthenticationPrincipal User modifier,
            @PathVariable UUID id
    ) {
        final Recipe recipe = this.recipeService.publishDraft(id, modifier);
        final FullRecipeView view = this.recipeToFullViewConverter.convert(recipe, false, modifier);
        return ResponseEntity.status(HttpStatus.CREATED).body(view);
    }

}
