import { Bot } from "lucide-react";
import { lazy, Suspense, useCallback, useEffect, useRef, useState } from "react";
import type { PersonaState } from "@/shared/ai-elements/persona";
import { cn } from "@/shared/ui/cn";

const LazyPersona = lazy(async () => {
  const module = await import("@/shared/ai-elements/persona");
  return { default: module.Persona };
});

type AgentPersonaProps = {
  className?: string;
  state?: PersonaState;
};

function useElementVisibility() {
  const containerRef = useRef<HTMLSpanElement>(null);
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;

    let intersectsViewport = false;
    const updateVisibility = () => {
      setVisible(intersectsViewport && document.visibilityState === "visible");
    };
    const observer = new IntersectionObserver(([entry]) => {
      intersectsViewport = Boolean(entry?.isIntersecting);
      updateVisibility();
    });

    observer.observe(container);
    document.addEventListener("visibilitychange", updateVisibility);

    return () => {
      observer.disconnect();
      document.removeEventListener("visibilitychange", updateVisibility);
    };
  }, []);

  return { containerRef, visible };
}

function PersonaFallback() {
  return (
    <span className="grid h-full w-full place-items-center rounded-full border border-slate-300/70 bg-slate-100 text-slate-500">
      <Bot className="h-2/5 w-2/5" aria-hidden="true" />
    </span>
  );
}

export function AgentPersona({ className, state = "idle" }: AgentPersonaProps) {
  const { containerRef, visible } = useElementVisibility();
  const [failed, setFailed] = useState(false);
  const handleLoadError = useCallback(() => setFailed(true), []);

  const shouldRenderAnimation = !failed && visible;

  return (
    <span
      ref={containerRef}
      aria-label="Agent 状态"
      className={cn("relative block shrink-0", className)}
    >
      {shouldRenderAnimation ? (
        <Suspense fallback={<PersonaFallback />}>
          <LazyPersona
            className="h-full w-full scale-110"
            onLoadError={handleLoadError}
            state={state}
          />
        </Suspense>
      ) : (
        <PersonaFallback />
      )}
    </span>
  );
}
