import { animate, cubicBezier } from "framer-motion/dom";
import {
  Color,
  GLSL1,
  GLSL3,
  MathUtils,
  Mesh,
  PlaneGeometry,
  RawShaderMaterial,
  type WebGLRenderer,
} from "three";

import fs_es2 from "@/assets/three/shaders/background.fs.es2.glsl";
import fs from "@/assets/three/shaders/background.fs.glsl";
import vs_es2 from "@/assets/three/shaders/background.vs.es2.glsl";
import vs from "@/assets/three/shaders/background.vs.glsl";
import { QUIZ_STEPS } from "@/config/data";

export class Background extends Mesh {
  material: RawShaderMaterial;

  constructor(private renderer: WebGLRenderer) {
    super();
    this.renderOrder = -2;

    this.geometry = new PlaneGeometry(2, 2);
    this.material = new RawShaderMaterial({
      glslVersion: this.renderer.capabilities.isWebGL2 ? GLSL3 : GLSL1,
      vertexShader: this.renderer.capabilities.isWebGL2 ? vs : vs_es2,
      fragmentShader: this.renderer.capabilities.isWebGL2 ? fs : fs_es2,
      uniforms: {
        colorTo: {
          value: new Color("#7583c9"),
        },
        colorFrom: {
          value: new Color("#b3b5e3"),
        },
        angle: { value: MathUtils.DEG2RAD * 245 },
      },
      depthTest: false,
      depthWrite: false,
    });
  }

  setStep(step: number) {
    const duration = 2;
    const currentColors = [
      `#${this.material.uniforms.colorTo.value.getHexString()}`,
      `#${this.material.uniforms.colorFrom.value.getHexString()}`,
    ];
    const newColors = QUIZ_STEPS[step]?.backgroundColors || [
      "#000000",
      "#000000",
    ];

    animate(currentColors[0], newColors[0], {
      duration,
      ease: cubicBezier(0.4, 0, 0.2, 1),
      onUpdate: (color) => {
        this.material.uniforms.colorTo.value.set(color);
      },
    });

    animate(currentColors[1], newColors[1], {
      duration,
      ease: cubicBezier(0.4, 0, 0.2, 1),
      onUpdate: (color) => {
        this.material.uniforms.colorFrom.value.set(color);
      },
    });
  }
}
