import { makeAutoObservable, runInAction } from "mobx";

const TRANSITION_DURATION = 60000;
const TICK_INTERVAL = 100;
const TICK_STEP = TICK_INTERVAL / TRANSITION_DURATION;

function hexToRgb(hex: string): { r: number; g: number; b: number } | null {
  const clean = hex.trim().replace(/^#/, "");
  const full = clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean;
  if (full.length !== 6) return null;
  return {
    r: parseInt(full.slice(0, 2), 16),
    g: parseInt(full.slice(2, 4), 16),
    b: parseInt(full.slice(4, 6), 16),
  };
}

function interpolateRgb(
  from: { r: number; g: number; b: number },
  to: { r: number; g: number; b: number },
  t: number
): string {
  const r = Math.round(from.r + (to.r - from.r) * t);
  const g = Math.round(from.g + (to.g - from.g) * t);
  const b = Math.round(from.b + (to.b - from.b) * t);
  return `rgb(${r}, ${g}, ${b})`;
}

const WHITE = { r: 255, g: 255, b: 255 };
const DEFAULT_MAIN = { r: 0, g: 111, b: 58 };

interface ColorStore {
  currentColor: string;
  setCurrentColor: (color: string) => void;
  setMainColor: (hex: string) => void;
  startColorAnimation: () => void;
  stopColorAnimation: () => void;
}

class ColorStore implements ColorStore {
  currentColor: string = "#fff";
  private mainColor: { r: number; g: number; b: number } = DEFAULT_MAIN;
  private progress: number = 0;
  private direction: number = 1;
  private tickInterval: ReturnType<typeof setInterval> | null = null;

  constructor() {
    makeAutoObservable(this);
  }

  setCurrentColor = (color: string) => {
    this.currentColor = color;
  };

  setMainColor = (hex: string) => {
    const parsed = hexToRgb(hex);
    if (parsed) {
      this.mainColor = parsed;
    }
  };

  startColorAnimation = () => {
    if (this.tickInterval) return;

    this.tickInterval = globalThis.setInterval(() => {
      runInAction(() => {
        this.progress += TICK_STEP * this.direction;

        if (this.progress >= 1) {
          this.progress = 1;
          this.direction = -1;
        } else if (this.progress <= 0) {
          this.progress = 0;
          this.direction = 1;
        }

        this.currentColor = interpolateRgb(WHITE, this.mainColor, this.progress);
      });
    }, TICK_INTERVAL);
  };

  stopColorAnimation = () => {
    if (this.tickInterval) {
      clearInterval(this.tickInterval);
      this.tickInterval = null;
    }
  };

  dispose = () => {
    this.stopColorAnimation();
  };
}

export const colorStore = new ColorStore();
export { ColorStore };
