package ru.yandex.canvas.controllers;

import java.io.IOException;
import java.util.Objects;
import java.util.Optional;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import ru.yandex.canvas.configs.auth.AuthorizeBy;
import ru.yandex.canvas.exceptions.InternalServerError;
import ru.yandex.canvas.exceptions.NotFoundException;
import ru.yandex.canvas.model.direct.Privileges;
import ru.yandex.canvas.model.video.vc.feed.VideoConstructorFeed;
import ru.yandex.canvas.model.video.vc.feed.VideoConstructorFeedRow;
import ru.yandex.canvas.model.video.vc.feed.VideoConstructorFeeds;
import ru.yandex.canvas.service.AuthService;
import ru.yandex.canvas.service.video.VideoConstructorFeedsService;

@RestController
@RequestMapping(value = "/video/constructor-feeds")
public class VideoConstructorFeedsController {
    private final AuthService authService;
    private final VideoConstructorFeedsService videoConstructorFeedsService;

    public VideoConstructorFeedsController(AuthService authService,
                                           VideoConstructorFeedsService videoConstructorFeedsService) {
        this.authService = authService;
        this.videoConstructorFeedsService = videoConstructorFeedsService;
    }

    @PostMapping
    public VideoConstructorFeed uploadFeedFile(@RequestParam("client_id") final long clientId,
                                               @RequestParam("file") final MultipartFile file) {
        authService.requirePermission(Privileges.Permission.CREATIVE_CREATE);
        try {
            return videoConstructorFeedsService.upload(
                    file.getBytes(),
                    Objects.requireNonNull(file.getOriginalFilename()),
                    clientId,
                    authService.getUserId());
        } catch (IOException e) {
            throw new InternalServerError(e);
        }
    }

    @GetMapping(value = "my")
    public VideoConstructorFeeds getMyFiles(@RequestParam("client_id") final long clientId,
                                            @RequestParam(value = "sort_order", defaultValue = "desc",
                                                    required = false) final String sortOrder) {
        authService.requirePermission(Privileges.Permission.CREATIVE_GET);
        return videoConstructorFeedsService.find(clientId, "desc".equalsIgnoreCase(sortOrder));
    }

    @GetMapping(value = "{id}")
    public VideoConstructorFeed getById(@PathVariable("id") final String id,
                                        @RequestParam("client_id") final long clientId) {
        authService.requirePermission(Privileges.Permission.CREATIVE_GET);
        return Optional.ofNullable(videoConstructorFeedsService.getById(id, clientId)).orElseThrow(NotFoundException::new);
    }

    @AuthorizeBy({AuthorizeBy.AuthType.TRUSTED_QUERY_STRING})
    @GetMapping
    public VideoConstructorFeedRow getRowById(@RequestParam("id") final String id,
                                              @RequestParam("row_num") final int rowNum) {
        authService.requirePermission(Privileges.Permission.CREATIVE_GET);
        return Optional.ofNullable(videoConstructorFeedsService.getRowById(id, rowNum)).orElseThrow(NotFoundException::new);
    }

    @DeleteMapping(value = "{id}")
    public ResponseEntity<Void> delete(@PathVariable("id") final String id,
                                       @RequestParam("client_id") final long clientId) {
        authService.requirePermission(Privileges.Permission.CREATIVE_CREATE);
        videoConstructorFeedsService.delete(id, clientId);
        return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
    }
}
