package ru.yandex.canvas.service;

import java.util.ArrayList;
import java.util.Map;

import ru.yandex.canvas.model.CreativeDocument;
import ru.yandex.canvas.model.MediaSet;
import ru.yandex.canvas.model.MediaSetItem;
import ru.yandex.canvas.model.MediaSetSubItem;
import ru.yandex.canvas.model.elements.Element;
import ru.yandex.canvas.model.html_builder.ImageGeoPinCreativeHtmlWriter;
import ru.yandex.canvas.model.html_builder.LogoGeoPinCreativeHtmlWriter;
import ru.yandex.canvas.service.preview.CreativePreviewBuilder;
import ru.yandex.canvas.service.screenshooters.CreativesScreenshooterHelperService;

public class GeoPinCreativeDocumentModifierImpl extends AbstractCreativeDocumentModifierImpl {
    private final ImageGeoPinCreativeHtmlWriter imageGeoPinCreativeHtmlWriter;
    private final LogoGeoPinCreativeHtmlWriter logoGeoPinCreativeHtmlWriter;

    public GeoPinCreativeDocumentModifierImpl(CreativePreviewBuilder creativePreviewBuilder,
                                              ScreenshooterService screenshooterService,
                                              StillageService stillageService,
                                              ImageGeoPinCreativeHtmlWriter imageGeoPinCreativeHtmlWriter,
                                              LogoGeoPinCreativeHtmlWriter logoGeoPinCreativeHtmlWriter,
                                              CreativesScreenshooterHelperService screenshooterHelperService,
                                              PreviewUrlBuilder previewUrlBuilder,
                                              PresetsService presetsService) {
        super(creativePreviewBuilder, previewUrlBuilder, presetsService, screenshooterService, stillageService,
                screenshooterHelperService);
        this.imageGeoPinCreativeHtmlWriter = imageGeoPinCreativeHtmlWriter;
        this.logoGeoPinCreativeHtmlWriter = logoGeoPinCreativeHtmlWriter;
    }

    @Override
    public void processCreativeDocument(String batchName, CreativeDocument item, long clientId) {
        updateGeoPinImages(item);
        super.processCreativeDocument(batchName, item, clientId);
    }

    /**
     * Подменяем исходные картинки на модифицированные.
     * Исходные сохраняем рядом для функциональности создания нового креатива на основе существующего.
     */
    private void updateGeoPinImages(CreativeDocument creative) {
        Map<String, String> urls = Map.of(
                "logo", getBorderLogoUrl(creative),
                "image", getImageWithTextsUrl(creative));
        Map<String, MediaSet> mediaSets = creative.getData().getMediaSets();
        if (mediaSets == null) {
            return;
        }
        for (Element e : creative.getData().getElements()) {
            String mediaSetKey = e.getMediaSet();
            if (mediaSetKey == null) {
                continue;
            }
            String url = urls.get(e.getType());
            MediaSet mediaSet = mediaSets.get(mediaSetKey);
            if (url == null || mediaSet == null || mediaSet.getItems() == null) {
                continue;
            }
            MediaSet copyMediaSet = new MediaSet();
            copyMediaSet.setItems(new ArrayList<>());
            for (MediaSetItem mediaSetItem : mediaSet.getItems()) {
                if (mediaSetItem.getItems() == null) {
                    continue;
                }
                MediaSetItem copyMediaSetItem = new MediaSetItem();
                copyMediaSetItem.setType(mediaSetItem.getType());
                copyMediaSet.getItems().add(copyMediaSetItem);
                copyMediaSetItem.setItems(new ArrayList<>());
                for (MediaSetSubItem mediaSetSubItem : mediaSetItem.getItems()) {
                    MediaSetSubItem copy = new MediaSetSubItem();
                    copyMediaSetItem.getItems().add(copy);
                    copy.setHeight(mediaSetSubItem.getHeight());
                    copy.setWidth(mediaSetSubItem.getWidth());
                    copy.setAlias(mediaSetSubItem.getAlias());
                    copy.setSmartCenters(mediaSetSubItem.getSmartCenters());
                    copy.setFileId(mediaSetSubItem.getFileId());
                    copy.setCroppedFileId(mediaSetSubItem.getCroppedFileId());
                    copy.getAdditionalProperties().putAll(mediaSetSubItem.getAdditionalProperties());
                    copy.setUrl(url);
                }
            }
            mediaSets.put(mediaSetKey, copyMediaSet);
            mediaSets.put(getBackupOrigMediaSetKey(mediaSetKey), mediaSet);
        }
    }

    private String getBackupOrigMediaSetKey(String mediaSetKey) {
        return mediaSetKey + "_orig";
    }

    /**
     * Модификация картинки банера:
     * добавляем возрастное ограничение
     * добавляем дисклеймер
     */
    private String getImageWithTextsUrl(CreativeDocument creative) {
        String html = imageGeoPinCreativeHtmlWriter.composeCreativeHTML(creative);
        String htmlUrl = uploadToStillage("Image", html);
        return screenshooterService.getScreenshotFromUrl(htmlUrl, 900, 300).getUrl();
    }

    /**
     * Модификация логотипа:
     * вырезаем круг
     * добавляем обводку
     */
    private String getBorderLogoUrl(CreativeDocument creative) {
        String html = logoGeoPinCreativeHtmlWriter.composeCreativeHTML(creative);
        String htmlUrl = uploadToStillage("Logo", html);
        return screenshooterService.getScreenshotFromUrl(htmlUrl, 200, 200).getUrl();
    }
}
