package ru.yandex.canvas.model.validation.presetbased.creative;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.springframework.validation.Errors;

import ru.yandex.canvas.model.CreativeData;
import ru.yandex.canvas.model.MediaSet;
import ru.yandex.canvas.model.MediaSetSubItem;
import ru.yandex.canvas.model.elements.Element;
import ru.yandex.canvas.model.elements.Image;
import ru.yandex.canvas.model.validation.InBannerVideoContainer;
import ru.yandex.canvas.model.video.files.InBannerVideo;
import ru.yandex.canvas.repository.video.VideoFilesRepository;
import ru.yandex.canvas.service.video.InBannerVideoFilesService;

import static ru.yandex.canvas.model.elements.ElementType.VIDEO;

/**
 * Validates {@link Image}s and {@link ru.yandex.canvas.model.elements.Logo}s of a {@link CreativeData} for integrity
 * <p>
 * Checks that each image:
 * <li> has a proper <b>mediaSet</b> defined
 * <li> that such a <b>mediaSet</b> exists
 * <li> all of it's subItems have an {@link MediaSetSubItem#getEffectiveFileId()} not null
 */
public class ValidInBannerVideoValidator extends MediaSetValidator<Element> implements InBannerVideoContainer {

    public static final String MESSAGE = "{video_not_uploaded}";

    private InBannerVideoFilesService inBannerVideoFilesService;

    @Override
    public void validate(CreativeData target, @NonNull Errors errors) {
        super.validate(target, errors);

        var element = target.getElements().stream().filter(e -> e.getType().equals(VIDEO)).findFirst().orElse(null);

        if (element == null) {
            errors.rejectValue(null, "video.not.uploaded", MESSAGE);
        }

    }

    @Override
    protected void validate(Element element, MediaSet mediaSet, CreativeData creativeData, @NonNull Errors errors) {

        if (!element.getType().equals(VIDEO)) {
            throw new IllegalStateException("Unknown element type "+element.getType());
        }

        if (element.getMediaSet() == null
                || creativeData.getMediaSets() == null
                || !creativeData.getMediaSets().containsKey(element.getMediaSet())) {
            errors.rejectValue(null, "video.not.uploaded", MESSAGE);
            return;
        }

        if (mediaSet != null && mediaSet.getItems().size() == 1 &&
                mediaSet.getItems().get(0).getItems().size() == 1) {

            MediaSetSubItem videoItem = mediaSet.getItems().get(0).getItems().get(0);

            if (videoItem.isDefaultValue()) {
                return;
            }

            InBannerVideo file = inBannerVideoFilesService.lookupMovie(videoItem.getFileId(),
                    new VideoFilesRepository.QueryBuilder());

            if (file != null) {
                if (!"16:9".equals(file.getRatio())) {
                    errors.rejectValue(null, "video.has.incorrect.ratio", "{video_has_incorrect_ratio}");
                }
                return;
            }

        }

        errors.rejectValue(null, "video.not.uploaded", MESSAGE);
    }

    @Override
    public void setVideoInBannerService(InBannerVideoFilesService fileService) {
        inBannerVideoFilesService = fileService;
    }

    @Override
    protected boolean isSupported(Element element, MediaSet mediaSet) {
        return element.getType().equals(VIDEO);
    }

    @Override
    public boolean isSupported(CreativeData target) {
        return super.isSupported(target);
    }
}
