import { AnimatePresence, motion } from "motion/react";
import { useState } from "react";

import HandRaisedOffFilledIcon from "../icons/HandRaisedOffFilledIcon";
import HandRaisedFilledIcon from "../icons/HandRaisedFilledIcon";
import MicrophoneFilledIcon from "../icons/MicrophoneFilledIcon";
import VideoOffFilledIcon from "../icons/VideoOffFilledIcon";
import MicrophoneOffIcon from "../icons/MicrophoneOffIcon";
import VideoFilledIcon from "../icons/VideoFilledIcon";
import ControlButton from "./ControlButton";
import Admin from "../indicators/Admin";
import clsx from "clsx";

interface UserCameraControlsProps {
  isMuted: boolean;
  isVideoOff: boolean;
  isControlDisabled: boolean;
  onMute: () => void;
  onVideoOff: () => void;
  onCanControl: () => void;
}

interface UserCameraProps extends UserCameraControlsProps {
  isAdmin?: boolean;
  name?: string;
  mediaStream?: string;
  isSpeaking?: boolean;
}

export default function UserCamera({
  isMuted,
  isVideoOff,
  isControlDisabled,
  onMute,
  onVideoOff,
  onCanControl,
  isSpeaking = false,
  isAdmin = false,
  name = "Гость",
  mediaStream = "",
}: UserCameraProps) {
  const [isHover, setIsHover] = useState(false);

  return (
    <motion.div
      onMouseEnter={() => setIsHover(true)}
      onMouseLeave={() => setIsHover(false)}
      animate={{
        width: isHover ? "10.833vw" : "6.944vw",
        border: isSpeaking
          ? "0.139vw solid #7B60F3"
          : "0.139vw solid #FFFFFF4D",
      }}
      className={clsx(
        "aspect-square group rounded-[1.667vw] bg-yellow-500 relative flex-shrink-0 transition-all duration-300 pointer-events-auto hover:w-[10.833vw]w-[6.944vw] shadow-[0_4px_40px_0_rgba(15,16,17,0.1),0_2px_2px_0_rgba(0,0,0,0.06)]",
        isAdmin && "order-3"
      )}
    >
      {isAdmin && <Admin className="absolute top-0 right-0" />}

      <div
        key="name"
        className="absolute whitespace-nowrap transition-opacity duration-300 group-hover:opacity-100 opacity-0 text-white button-s top-[0.556vw] left-1/2 translate-x-[-50%] px-[0.556vw] py-[0.278vw] rounded-full bg-[#14141440] backdrop-blur-[4px]"
      >
        {name}
      </div>

      <video
        src={mediaStream}
        className="size-full object-cover"
        autoPlay
        muted={isMuted}
        playsInline
      />

      <UserCameraControls
        isMuted={isMuted}
        isVideoOff={isVideoOff}
        isControlDisabled={isControlDisabled}
        isHover={isHover}
        onMute={onMute}
        onVideoOff={onVideoOff}
        onCanControl={onCanControl}
      />
    </motion.div>
  );
}

function UserCameraControls({
  isMuted,
  isVideoOff,
  isControlDisabled,
  isHover,
  onMute,
  onVideoOff,
  onCanControl,
}: UserCameraControlsProps & { isHover: boolean }) {
  return (
    <div className="absolute bottom-[0.278vw] left-1/2 translate-x-[-50%]">
      <AnimatePresence mode="wait">
        {isHover ? (
          <motion.div
            key="controls"
            className="flex gap-[0.278vw] mb-[0.278vw]"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.2 }}
          >
            <ControlButton
              icon={isMuted ? <MicrophoneOffIcon /> : <MicrophoneFilledIcon />}
              size={"small"}
              enabled={!isMuted}
              onClick={onMute}
            />
            <ControlButton
              icon={isVideoOff ? <VideoOffFilledIcon /> : <VideoFilledIcon />}
              size={"small"}
              enabled={!isVideoOff}
              onClick={onVideoOff}
            />
            <ControlButton
              icon={
                isControlDisabled ? (
                  <HandRaisedOffFilledIcon />
                ) : (
                  <HandRaisedFilledIcon />
                )
              }
              size={"small"}
              enabled={!isControlDisabled}
              onClick={onCanControl}
            />
          </motion.div>
        ) : (
          <motion.div
            key="controls-muted"
            className="size-[1.667vw] bg-[#14141426] backdrop-blur-[4px] rounded-full flex items-center justify-center z-10"
            initial={{ opacity: 0 }}
            animate={{ opacity: isMuted ? 1 : 0 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.2 }}
          >
            <div className="size-[0.972vw] text-white">
              <MicrophoneOffIcon />
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}
