package ru.yandex.canvas.controllers.video;

import java.io.IOException;
import java.net.URISyntaxException;

import javax.validation.Valid;

import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import ru.yandex.canvas.configs.auth.AuthorizeBy;
import ru.yandex.canvas.exceptions.InternalServerError;
import ru.yandex.canvas.exceptions.NotFoundException;
import ru.yandex.canvas.model.stillage.StillageFileInfo;
import ru.yandex.canvas.model.video.Addition;
import ru.yandex.canvas.service.AuthService;
import ru.yandex.canvas.service.ScreenshooterService;
import ru.yandex.canvas.service.StillageService;
import ru.yandex.canvas.service.screenshooters.VideoAdditionScreenshooterHelperService;
import ru.yandex.canvas.service.video.StaticPreviewService;
import ru.yandex.canvas.service.video.VideoAdditionsService;
import ru.yandex.canvas.service.video.VideoCreativesService;
import ru.yandex.direct.screenshooter.client.model.ScreenShooterScreenshot;

@RestController
@RequestMapping(path = "/video/creatives")
@Validated
public class VideoCreativesController {

    private final VideoAdditionsService videoAdditionsService;
    private final VideoCreativesService videoCreativesService;
    private final StillageService stillageService;
    private final VideoAdditionScreenshooterHelperService videoAdditionScreenshooterHelperService;
    private final ScreenshooterService screenshooterService;
    private final StaticPreviewService staticPreviewService;
    private final AuthService authService;

    public VideoCreativesController(VideoAdditionsService videoAdditionsService,
                                    VideoCreativesService videoCreativesService,
                                    StillageService stillageService,
                                    VideoAdditionScreenshooterHelperService videoAdditionScreenshooterHelperService,
                                    ScreenshooterService screenshooterService,
                                    StaticPreviewService staticPreviewService,
                                    AuthService authService) {
        this.videoAdditionsService = videoAdditionsService;
        this.videoCreativesService = videoCreativesService;
        this.stillageService = stillageService;
        this.videoAdditionScreenshooterHelperService = videoAdditionScreenshooterHelperService;
        this.screenshooterService = screenshooterService;
        this.staticPreviewService = staticPreviewService;
        this.authService = authService;
    }

    @GetMapping(path = "/{id}/addition")
    public ResponseEntity<Addition> getAdditionByCreativeId(@PathVariable(value = "id") Long id,
                                                            @RequestParam("client_id") Long clientId) {
        Addition addition = videoAdditionsService.getAdditionByCreativeId(id, clientId);

        if (addition == null) {
            throw new NotFoundException();
        }

        return ResponseEntity.ok(addition);
    }

    @AuthorizeBy({AuthorizeBy.AuthType.DIRECT_TOKEN})
    @PostMapping(path = "{id}/addition/staticPreview")
    public ResponseEntity<VideoAdditionsController.StaticPreviewEntity> getStaticPreview(
            @PathVariable(value = "id") Long id,
            @Valid @RequestBody PreviewRequestEntity previewRequest) {

        Addition addition = videoAdditionsService.getAdditionByCreativeIdArchivedAlso(id);

        if (addition == null) {
            throw new NotFoundException();
        }

        try {
            String result = staticPreviewService.getStaticPreview(addition, previewRequest.getPreviewData());
            StillageFileInfo stillageFileInfo = stillageService.uploadFile("preview.html", result.getBytes());
            return ResponseEntity.ok(new VideoAdditionsController.StaticPreviewEntity(stillageFileInfo.getUrl()));
        } catch (IOException | URISyntaxException e) {
            throw new InternalServerError(e.getMessage(), e);
        }
    }

    @GetMapping(value = "getScreenshot/{id}")
    public ResponseEntity<byte[]> getScreenshot(@PathVariable("id") Long id) {
        return getScreenshotOld(id, authService.getUserId());
    }

    @GetMapping(value = "{id}/getScreenshot")
    public ResponseEntity<byte[]> getScreenshotOld(@PathVariable("id") Long id, @RequestParam("user_id") long userId) {
        /* Проверяем, что у юзера есть доступ к превью на данном клиенте, чтобы нельзя было
         * смотреть скриншоты чужих креативов.
         * TODO: временно! выключаем проверку прав, подробности в тикете DIRECT-117603
         */
        // authService.requirePermissionDifferentClient(clientId, Privileges.Permission.PREVIEW);
        var creative = videoCreativesService.getCreativeWithClientIdOrThrow(id);
        ScreenShooterScreenshot screenshot = videoAdditionScreenshooterHelperService.getScreenshot(
                creative.getCreative(), userId, creative.getClientId());
        return screenshooterService.prepareScreenshotForResponse(screenshot);
    }

}
