import { useState, useEffect, useRef } from "react";
import { Box, Avatar as MantineAvatar } from "@mantine/core";

interface GlitchAvatarProps {
  name: string;
  src?: string;
  glitchSrc?: string;
  size?: number;
  radius?: string | number;
  withBorder?: boolean;
  children?: React.ReactNode;
}

const FRAME_PADDING = 8;

const toCssRadius = (radius: string | number) =>
  typeof radius === "number" ? `${radius}px` : `var(--mantine-radius-${radius})`;

const GlitchAvatar = ({
  name,
  src,
  glitchSrc,
  size = 35,
  radius = "md",
  withBorder = true,
  children,
}: GlitchAvatarProps) => {
  const [showGlitch, setShowGlitch] = useState(false);
  const [isPlaying, setIsPlaying] = useState(false);
  const videoRef = useRef<HTMLVideoElement>(null);

  useEffect(() => {
    if (!glitchSrc) return;

    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;

    let timeoutId: ReturnType<typeof setTimeout>;
    const scheduleNextGlitch = () => {
      const delay = Math.random() * 10000 + 5000;
      timeoutId = setTimeout(() => {
        setShowGlitch(true);
        setIsPlaying(true);

        timeoutId = setTimeout(() => {
          setShowGlitch(false);
          setIsPlaying(false);
          scheduleNextGlitch();
        }, 4000);
      }, delay);
    };

    scheduleNextGlitch();
    return () => clearTimeout(timeoutId);
  }, [glitchSrc]);

  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    const handleEnded = () => {
      setShowGlitch(false);
      setIsPlaying(false);
    };

    video.addEventListener("ended", handleEnded);
    return () => video.removeEventListener("ended", handleEnded);
  }, []);

  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    video.load();
  }, [glitchSrc]);

  useEffect(() => {
    const video = videoRef.current;
    if (!video || !showGlitch || !isPlaying) return;

    video.currentTime = 0;
    video.play().catch((err) => {
      console.error("Failed to play glitch", err);
    });
  }, [showGlitch, isPlaying]);

  const innerRadius = toCssRadius(radius);

  return (
    <Box
      style={{
        position: "relative",
        width: "fit-content",
        padding: FRAME_PADDING,
        border: withBorder
          ? "1px solid var(--mantine-color-default-border)"
          : "1px solid transparent",
        borderRadius: `calc(${innerRadius} + ${FRAME_PADDING}px)`,
      }}
    >
      {src ? (
        <Box style={{ position: "relative" }}>
          <img
            src={src}
            alt={name}
            style={{
              display: "block",
              maxWidth: size,
              maxHeight: size,
              width: "auto",
              height: "auto",
              borderRadius: innerRadius,
              opacity: showGlitch ? 0 : 1,
              transition: showGlitch
                ? "opacity 0.05s ease-in"
                : "opacity 0.25s ease-out",
            }}
          />
          {glitchSrc && (
            <video
              ref={videoRef}
              src={glitchSrc}
              style={{
                position: "absolute",
                inset: 0,
                width: "100%",
                height: "100%",
                objectFit: "contain",
                borderRadius: innerRadius,
                opacity: showGlitch ? 1 : 0,
                visibility: showGlitch ? "visible" : "hidden",
                transition: showGlitch ? "opacity 0.05s ease-in" : "none",
                pointerEvents: "none",
              }}
              muted
              playsInline
              preload="auto"
            />
          )}
        </Box>
      ) : (
        <MantineAvatar
          alt={name}
          key={name}
          name={name}
          color="initials"
          size={size}
          radius={radius}
          w={size}
        >
          {children}
        </MantineAvatar>
      )}
    </Box>
  );
};

export default GlitchAvatar;
