package ru.yandex.webmaster3.core.turbo.model.desktop;

import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;

import ru.yandex.webmaster3.core.turbo.model.TurboDisplaySettings;
import ru.yandex.webmaster3.core.turbo.model.TurboHostHeader;
import ru.yandex.webmaster3.core.turbo.model.advertising.AdvertisingPlacement;
import ru.yandex.webmaster3.core.turbo.model.advertising.AdvertisingSettings;

/**
 * Created by Oleg Bazdyrev on 18/02/2019.
 */
@Getter
public class TurboDesktopSettings {

    private final Boolean enabled;
    private final Set<TurboDesktopColumn> columns;
    private final TurboHostHeader header;
    private final Map<AdvertisingPlacement, List<AdvertisingSettings>> advertisingSettings;
    private final String css;
    private final String minifiedCss;
    private final Boolean aabEnabled;
    private final Boolean antiItpEnabled;
    private final TurboDisplaySettings displaySettings;

    public TurboDesktopSettings(Boolean enabled, Set<TurboDesktopColumn> columns, TurboHostHeader header,
                                List<AdvertisingSettings> advertisingSettings, String css, String minifiedCss,
                                Boolean aabEnabled, Boolean antiItpEnabled, TurboDisplaySettings displaySettings) {
        this(enabled, columns, header, AdvertisingSettings.adsMapFromList(advertisingSettings), css, minifiedCss, aabEnabled, antiItpEnabled, displaySettings);
    }

    @JsonCreator
    public TurboDesktopSettings(@JsonProperty("enabled") Boolean enabled,
                                @JsonProperty("columns") Set<TurboDesktopColumn> columns,
                                @JsonProperty("header") TurboHostHeader header,
                                @JsonProperty("advertisingSettings")
                                        Map<AdvertisingPlacement, List<AdvertisingSettings>> advertisingSettings,
                                @JsonProperty("css") String css,
                                @JsonProperty("minifiedCss") String minifiedCss,
                                @JsonProperty("aabEnabled") Boolean aabEnabled,
                                @JsonProperty("antiItpEnabled") Boolean antiItpEnabled,
                                @JsonProperty("displaySettings") TurboDisplaySettings displaySettings) {
        this.enabled = enabled;
        this.columns = columns == null ? Collections.emptySet() : columns;
        this.header = header == null ? new TurboHostHeader() : header;
        this.advertisingSettings = advertisingSettings == null ? Collections.emptyMap() : advertisingSettings;
        this.css = css;
        this.minifiedCss = minifiedCss;
        this.aabEnabled = aabEnabled;
        this.antiItpEnabled = antiItpEnabled;
        this.displaySettings = displaySettings;
    }

    @JsonIgnore
    public List<AdvertisingSettings> getAdvertisingSettingsList() {
        if (advertisingSettings == null) {
            return Collections.emptyList();
        }
        return advertisingSettings.entrySet().stream()
                .flatMap(entry -> entry.getValue().stream().map(as -> as.withPlacement(entry.getKey())))
                .collect(Collectors.toList());
    }

    public static final class TurboDesktopSettingsBuilder {
        private Boolean enabled;
        private Set<TurboDesktopColumn> columns;
        private TurboHostHeader header;
        private Map<AdvertisingPlacement, List<AdvertisingSettings>> advertisingSettings;
        @Getter
        private Set<AdvertisingPlacement> changedAdvertisingPlacements = EnumSet.noneOf(AdvertisingPlacement.class);
        private String css;
        private String minifiedCss;
        private Boolean aabEnabled;
        private Boolean antiItpEnabled;
        private TurboDisplaySettings displaySettings;

        public TurboDesktopSettingsBuilder() {
            // default values
            columns = EnumSet.allOf(TurboDesktopColumn.class);
        }

        public TurboDesktopSettingsBuilder(TurboDesktopSettings settings) {
            this.enabled = settings.enabled;
            this.columns = settings.columns;
            this.header = settings.header;
            this.advertisingSettings = settings.advertisingSettings;
            this.css = settings.css;
            this.minifiedCss = settings.minifiedCss;
            this.aabEnabled = settings.aabEnabled;
            this.antiItpEnabled = settings.antiItpEnabled;
        }

        public TurboDesktopSettingsBuilder setEnabled(Boolean enabled) {
            this.enabled = enabled;
            return this;
        }

        public TurboDesktopSettingsBuilder setColumns(Set<TurboDesktopColumn> columns) {
            this.columns = columns;
            return this;
        }

        public TurboDesktopSettingsBuilder setHeader(TurboHostHeader header) {
            this.header = header;
            return this;
        }

        public TurboDesktopSettingsBuilder setAdvertisingSettings(List<AdvertisingSettings> advertisingSettings) {
            Map<AdvertisingPlacement, List<AdvertisingSettings>> newSettings = AdvertisingSettings.adsMapFromList(advertisingSettings);
            changedAdvertisingPlacements.addAll(AdvertisingSettings.getChangedPlacements(newSettings, this.advertisingSettings));
            this.advertisingSettings = newSettings;
            return this;
        }

        public TurboDesktopSettingsBuilder setCss(String css) {
            this.css = css;
            return this;
        }

        public TurboDesktopSettingsBuilder setMinifiedCss(String minifiedCss) {
            this.minifiedCss = minifiedCss;
            return this;
        }

        public TurboDesktopSettingsBuilder setAabEnabled(Boolean aabEnabled) {
            this.aabEnabled = aabEnabled;
            return this;
        }

        public TurboDesktopSettingsBuilder setAntiItpEnabled(Boolean antiItpEnabled) {
            this.antiItpEnabled = antiItpEnabled;
            return this;
        }

        public TurboDesktopSettingsBuilder setDisplaySettings(TurboDisplaySettings displaySettings) {
            this.displaySettings = displaySettings;
            return this;
        }

        public TurboDesktopSettings build() {
            return new TurboDesktopSettings(enabled, columns, header, advertisingSettings, css, minifiedCss, aabEnabled, antiItpEnabled, displaySettings);
        }
    }
}
