import type { RiveParameters } from "@rive-app/react-webgl2";
import { useRive, useStateMachineInput } from "@rive-app/react-webgl2";
import { memo, useEffect, useState } from "react";
import { cn } from "@/shared/ui/cn";

const RIVE_SOURCE = "https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/obsidian-2.0.riv";
const STATE_MACHINE = "default";

function useDeferredRiveInit() {
  const [ready, setReady] = useState(false);

  useEffect(() => {
    const id = requestAnimationFrame(() => setReady(true));
    return () => cancelAnimationFrame(id);
  }, []);

  return ready;
}

export type PersonaState = "idle" | "listening" | "thinking" | "speaking" | "asleep";

export type PersonaProps = {
  className?: string;
  onLoadError?: RiveParameters["onLoadError"];
  state?: PersonaState;
};

export const Persona = memo(function Persona({
  className,
  onLoadError,
  state = "idle"
}: PersonaProps) {
  const ready = useDeferredRiveInit();

  const { rive, RiveComponent } = useRive(
    ready
      ? {
          autoplay: true,
          onLoadError,
          src: RIVE_SOURCE,
          stateMachines: STATE_MACHINE
        }
      : null
  );

  const listeningInput = useStateMachineInput(rive, STATE_MACHINE, "listening");
  const thinkingInput = useStateMachineInput(rive, STATE_MACHINE, "thinking");
  const speakingInput = useStateMachineInput(rive, STATE_MACHINE, "speaking");
  const asleepInput = useStateMachineInput(rive, STATE_MACHINE, "asleep");

  useEffect(() => {
    if (listeningInput) {
      listeningInput.value = state === "listening";
    }
    if (thinkingInput) {
      thinkingInput.value = state === "thinking";
    }
    if (speakingInput) {
      speakingInput.value = state === "speaking";
    }
    if (asleepInput) {
      asleepInput.value = state === "asleep";
    }
  }, [state, listeningInput, thinkingInput, speakingInput, asleepInput]);

  return (
    <RiveComponent
      className={cn("size-16 shrink-0", className)}
      style={{ filter: "brightness(0.45) contrast(1.35)" }}
    />
  );
});
