package ru.yandex.webmaster3.storage.turbo.service.preview;

import java.util.Optional;

import javax.annotation.Nullable;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Strings;
import lombok.Builder;
import lombok.NonNull;
import lombok.Value;
import org.apache.commons.lang3.ObjectUtils;

import ru.yandex.webmaster3.core.turbo.model.TurboDisplaySettings;
import ru.yandex.webmaster3.core.turbo.model.TurboHostSettings;
import ru.yandex.webmaster3.core.turbo.model.TurboLogo;
import ru.yandex.webmaster3.core.turbo.model.desktop.TurboDesktopSettings;

/**
 * Created by Oleg Bazdyrev on 04/12/2020.
 */
@Value
@Builder
public class TurboDisplaySettingsData {

    @JsonProperty("touch")
    PlatformSettingsData touch;
    @JsonProperty("desktop")
    PlatformSettingsData desktop;

    @Value
    @Builder
    public static final class PlatformSettingsData {
        @JsonProperty("light-mode")
        ColorSchemeData lightMode;
        @JsonProperty("dark-mode")
        ColorSchemeData darkMode;

        public static PlatformSettingsData fromSettings(TurboDisplaySettings settings) {
            if (!settings.isEnabled()) {
                return null;
            }
            var builder = PlatformSettingsData.builder();
            TurboLogo logo = settings.getHeader() == null ? null : settings.getHeader().getLogoInfo();
            TurboDisplaySettings.ColorScheme lightMode = settings.getLightMode();
            if (lightMode != null) { // lightMode always enabled
                builder.lightMode(ColorSchemeData.fromSettings(settings, lightMode, logo));
            }
            TurboDisplaySettings.ColorScheme darkMode = settings.getDarkMode();
            if (darkMode != null && darkMode.isEnabled()) {
                builder.darkMode(ColorSchemeData.fromSettings(settings, darkMode, logo));
            }
            return builder.build();
        }
    }

    @Value
    @Builder
    public static final class ColorSchemeData {
        @JsonProperty("enabled")
        boolean enabled;
        @JsonProperty("colors")
        ColorsData colors;
        @JsonProperty("fonts")
        FontsData fonts;
        @JsonProperty("logo")
        TurboHostSettingsData.Logo logo;

        public static ColorSchemeData fromSettings(TurboDisplaySettings settings, TurboDisplaySettings.ColorScheme scheme, TurboLogo logo) {
            var builder = ColorSchemeData.builder();
            builder.enabled(true);
            builder.colors(ColorsData.builder()
                    .author(getColor(scheme.getContentDateColor()))
                    .background(getColor(scheme.getContentBackgroundColor()))
                    .buttons(getColor(scheme.getContentButtonColor()))
                    .headerBackground(getColor(scheme.getHeaderBackgroundColor()))
                    .headerIcons(getColor(scheme.getHeaderForegroundColor()))
                    .headerText(getColor(scheme.getHeaderForegroundColor()))
                    .date(getColor(scheme.getContentDateColor()))
                    .title(getColor(scheme.getContentTextColor()))
                    .links(getColor(scheme.getContentLinkColor()))
                    .text(getColor(scheme.getContentTextColor()))
                    .textButtons(getColor(scheme.getContentTextButtonColor()))
                    .build());
            builder.fonts(FontsData.builder()
                    .headers(FontData.builder().size(settings.getHeaderFontSize().getValue()).type(settings.getHeaderFontFamily().getValue()).build())
                    .text(FontData.builder().size(settings.getContentFontSize().getValue()).type(settings.getContentFontFamily().getValue()).build())
                    .build());
            builder.logo(TurboHostSettingsData.Logo.fromTurboLogo(
                    Optional.ofNullable(scheme.getLogo())
                            .map(l -> Strings.isNullOrEmpty(l.getLogoId()) ? null : l) // no logo?
                            .orElse(logo))
            );
            return builder.build();
        }
    }

    @Value
    @Builder
    public static final class FontsData {
        @JsonProperty("headers")
        FontData headers;
        @JsonProperty("text")
        FontData text;
    }

    @Value
    @Builder
    public static final class FontData {
        @JsonProperty("type")
        String type;
        @JsonProperty("size")
        String size;
    }

    @Value
    @Builder
    public static final class ColorsData {
        @JsonProperty("header-background")
        String headerBackground;
        @JsonProperty("header-text")
        String headerText;
        @JsonProperty("header-icons")
        String headerIcons;
        @JsonProperty("title")
        String title;
        @JsonProperty("text")
        String text;
        @JsonProperty("author")
        String author;
        @JsonProperty("date")
        String date;
        @JsonProperty("links")
        String links;
        @JsonProperty("buttons")
        String buttons;
        @JsonProperty("text-buttons")
        String textButtons;
        @JsonProperty("background")
        String background;
    }

    public static TurboDisplaySettingsData fromSettings(@NonNull TurboHostSettings settings,
                                                        @Nullable TurboDesktopSettings desktopSettings) {

        var builder = builder();
        if (settings.getDisplaySettings() != null) {
            builder.touch(PlatformSettingsData.fromSettings(settings.getDisplaySettings()));
        }
        if (desktopSettings != null && desktopSettings.getDisplaySettings() != null) {
            builder.desktop(PlatformSettingsData.fromSettings(desktopSettings.getDisplaySettings()));
        }
        return builder.build();
    }

    public static String getColor(TurboDisplaySettings.ColorSettings cs) {
        if (cs == null) {
            return null;
        } else {
            return cs.isCustomSelected() ? cs.getCustomColor() : cs.getColor();
        }
    }
}
