package ru.yandex.canvas.model.stillage;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import com.fasterxml.jackson.annotation.JsonInclude;
import org.jetbrains.annotations.NotNull;

import ru.yandex.canvas.model.scraper.ScraperData;

/**
 * @author skirsanov
 */
public class StillageFileInfo {
    public static final String COLOR_INFO = "colorInfo";

    protected String id;

    private String url;

    /**
     * Размер файла в байтах
     */
    private int fileSize;

    //private byte[] md5Hash;
    private String md5Hash;
    private String mimeType;

    private String contentGroup;

    @JsonInclude(JsonInclude.Include.ALWAYS)
    private Map<String, Object> metadataInfo = new HashMap<>();

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public int getFileSize() {
        return fileSize;
    }

    public void setFileSize(int fileSize) {
        this.fileSize = fileSize;
    }

    // TODO: смигрировать данные после перехода на java и включить поле
    public String getMd5Hash() {
        return md5Hash;
    }

    /*public void setMd5Hash(byte[] md5Hash) {
        this.md5Hash = md5Hash;
    }*/

    public void setMd5Hash(String md5HashString) {
        this.md5Hash = md5HashString;
    }

    public String getMimeType() {
        return mimeType;
    }

    public void setMimeType(String mimeType) {
        this.mimeType = mimeType;
    }

    public String getContentGroup() {
        return contentGroup;
    }

    public void setContentGroup(String contentGroup) {
        this.contentGroup = contentGroup;
    }

    public Map<String, Object> getMetadataInfo() {
        return metadataInfo;
    }

    public void setMetadataInfo(Map<String, Object> metadataInfo) {
        this.metadataInfo = metadataInfo;
    }

    //TODO: think about put this into model. The problem is mongo hasn't JsonAnyGetter annotation and and we will be used to migrate data.
    public Optional<ImageColors> getImageColors() {
        if (!metadataInfo.containsKey(COLOR_INFO)) {
            return Optional.empty();
        }
        //noinspection unchecked
        return Optional.ofNullable(metadataInfo.get(COLOR_INFO))
                .filter(obj -> obj instanceof Map)
                .flatMap(colorInfoRaw -> ImageColors.fromRawData((Map<String, Object>) colorInfoRaw));
    }

    public static class ImageColors {
        private String averageBorderColor;
        private String colorWizBack;
        private String colorWizButton;
        private String colorWizButtonText;
        private String colorWizText;

        public ImageColors() {
        }

        public ImageColors(String averageBorderColor, String colorWizBack, String colorWizButton,
                           String colorWizButtonText, String colorWizText) {
            this.averageBorderColor = averageBorderColor;
            this.colorWizBack = colorWizBack;
            this.colorWizButton = colorWizButton;
            this.colorWizButtonText = colorWizButtonText;
            this.colorWizText = colorWizText;
        }

        static Optional<ImageColors> fromRawData(@NotNull Map<String, Object> colorInfoRaw) {
            if (!colorInfoRaw.containsKey("averageBorderColor") ||
                    !colorInfoRaw.containsKey("colorWizBack") ||
                    !colorInfoRaw.containsKey("colorWizButton") ||
                    !colorInfoRaw.containsKey("colorWizButtonText") ||
                    !colorInfoRaw.containsKey("colorWizText")
            ) {
                return Optional.empty();
            }
            return Optional.of(new ImageColors(
                    (String) colorInfoRaw.get("averageBorderColor"),
                    (String) colorInfoRaw.get("colorWizBack"),
                    (String) colorInfoRaw.get("colorWizButton"),
                    (String) colorInfoRaw.get("colorWizButtonText"),
                    (String) colorInfoRaw.get("colorWizText")));
        }

        public String getAverageBorderColor() {
            return averageBorderColor;
        }

        public void setAverageBorderColor(String averageBorderColor) {
            this.averageBorderColor = averageBorderColor;
        }

        public String getColorWizBack() {
            return colorWizBack;
        }

        public void setColorWizBack(String colorWizBack) {
            this.colorWizBack = colorWizBack;
        }

        public String getColorWizButton() {
            return colorWizButton;
        }

        public void setColorWizButton(String colorWizButton) {
            this.colorWizButton = colorWizButton;
        }

        public String getColorWizButtonText() {
            return colorWizButtonText;
        }

        public void setColorWizButtonText(String colorWizButtonText) {
            this.colorWizButtonText = colorWizButtonText;
        }

        public String getColorWizText() {
            return colorWizText;
        }

        public void setColorWizText(String colorWizText) {
            this.colorWizText = colorWizText;
        }

        @NotNull
        public ScraperData.ScraperColors toScraperColors() {
            return new ScraperData.ScraperColors(colorWizBack, averageBorderColor, colorWizText, colorWizButton,
                    colorWizButtonText);
        }
    }

    @Override
    public String toString() {
        return "StillageFileInfo{" +
                "id='" + id + '\'' +
                ", url='" + url + '\'' +
                ", fileSize=" + fileSize +
                ", md5Hash='" + md5Hash + '\'' +
                ", mimeType='" + mimeType + '\'' +
                ", contentGroup='" + contentGroup + '\'' +
                ", metadataInfo=" + metadataInfo +
                '}';
    }
}
