package me.koba1.led.model.colors;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import me.koba1.led.utils.ColorUtils;

@Getter
@Setter
@AllArgsConstructor
@ToString
public class KobaColor implements Cloneable {

    private String hex;
    private int alpha;

    public KobaColor() {
        this.hex = "#FF0000";
        this.alpha = 255;
    }

    public KobaColor(String hex) {
        this.hex = ColorUtils.getHex(hex);
        this.alpha = ColorUtils.getAlphaFromHex(hex);
    }

    public String getHex() {
        return this.hex + String.format("%02X", this.alpha);
    }

    public int getHexInt() {
        String cleanHex = this.hex.replace("#", "");
        int rgb = Integer.parseInt(cleanHex, 16);
//        System.out.println("RGB: " + rgb);
//        System.out.println("Alpha: " + this.alpha);
//        System.out.println((rgb << 8) | this.alpha);
//        System.out.println("===========================");
        return (rgb << 8) | this.alpha;
    }

    public KobaColor withAlpha(int alpha) {
        return new KobaColor(this.hex, alpha);
    }

//    public KobaColor setAlpha(int alpha) {
//        this.alpha = alpha;
//        return this;
//    }

    @JsonValue
    public String toJson() {
        return getHex();
    }

    @JsonCreator
    public static KobaColor fromJson(String value) {
        String hex = ColorUtils.getHex(value);
        int alpha = ColorUtils.getAlphaFromHex(value);

        return new KobaColor(hex, alpha);
    }

    public boolean isEquals(KobaColor other) {
        return this.hex.equals(other.hex) && this.alpha == other.alpha;
    }

    @Override
    public KobaColor clone() {
        try {
            KobaColor clone = (KobaColor) super.clone();
            // TODO: copy mutable state here, so the clone can't change the internals of the original
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}
