package dev.fyloz.trial.colorrecipesexplorer.rest

import dev.fyloz.trial.colorrecipesexplorer.model.*
import dev.fyloz.trial.colorrecipesexplorer.service.MixService
import dev.fyloz.trial.colorrecipesexplorer.service.RecipeImageService
import dev.fyloz.trial.colorrecipesexplorer.service.RecipeService
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile
import java.net.URI
import javax.validation.Valid


private const val RECIPE_CONTROLLER_PATH = "api/recipe"
private const val MIX_CONTROLLER_PATH = "api/recipe/mix"

@RestController
@RequestMapping(RECIPE_CONTROLLER_PATH)
class RecipeController(recipeService: RecipeService) :
    AbstractModelRestApiController<Recipe, RecipeSaveDto, RecipeUpdateDto, RecipeService>(
        recipeService,
        RECIPE_CONTROLLER_PATH
    ) {

    @PutMapping("public")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    fun updatePublicData(@Valid @RequestBody publicDataDto: RecipePublicDataDto): ResponseEntity<Void> {
        service.updatePublicData(publicDataDto)
        return ResponseEntity.noContent().build()
    }
}

@RestController
@RequestMapping(RECIPE_CONTROLLER_PATH)
class RecipeImageController(val recipeImageService: RecipeImageService) {
    @GetMapping("{recipeId}/image")
    @ResponseStatus(HttpStatus.OK)
    fun getAllIdsForRecipe(@PathVariable recipeId: Long): ResponseEntity<Collection<Long>> =
        ResponseEntity.ok(recipeImageService.getAllIdsForRecipe(recipeId))

    @GetMapping("{recipeId}/image/{id}", produces = [MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE])
    @ResponseStatus(HttpStatus.OK)
    fun getById(@PathVariable recipeId: Long, @PathVariable id: Long): ResponseEntity<ByteArray> =
        ResponseEntity.ok(recipeImageService.getByIdForRecipe(id, recipeId))

    @PostMapping("{recipeId}/image", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
    @ResponseStatus(HttpStatus.CREATED)
    fun save(@PathVariable recipeId: Long, image: MultipartFile): ResponseEntity<Void> {
        val id = recipeImageService.save(image, recipeId)
        return ResponseEntity.created(URI.create("/$RECIPE_CONTROLLER_PATH/$recipeId/image/$id")).build()
    }

    @DeleteMapping("{recipeId}/image/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    fun delete(@PathVariable recipeId: Long, @PathVariable id: Long): ResponseEntity<Void> {
        recipeImageService.delete(id, recipeId)
        return ResponseEntity.noContent().build()
    }
}

@RestController
@RequestMapping(MIX_CONTROLLER_PATH)
class MixController(val mixService: MixService) :
    AbstractModelRestApiController<Mix, MixSaveDto, MixUpdateDto, MixService>(mixService, MIX_CONTROLLER_PATH)
