import { useEffect, useRef, useState } from "react";
import HandRaisedFilledIcon from "../icons/HandRaisedFilledIcon";
import MicrophoneFilledIcon from "../icons/MicrophoneFilledIcon";
import VideoOffFilledIcon from "../icons/VideoOffFilledIcon";
import VideoFilledIcon from "../icons/VideoFilledIcon";
import Admin from "../indicators/Admin";
import clsx from "clsx";
import VolumeIcon from "../icons/VolumeIcon";
import VolumeOffIcon from "../icons/VolumeOffIcon";
import { useVoiceActivity } from "../../hooks/useVoiceActivity";
import MicrophoneOffFilledIcon from "../icons/MicrophoneOffFilledIcon";

interface UserCameraControlsProps {
  isMuted: boolean;
  isVideoOff: boolean;
  hasControl: boolean;
}

interface UserCameraProps {
  isMuted: boolean;
  isVideoOff: boolean;
  hasControl?: boolean;
  onMute: () => void;
  onVideoOff: () => void;
  onCanControl: () => void;
  isAdmin?: boolean;
  name?: string;
  mediaStream?: MediaStream | null;
  isLocal?: boolean;
  isSpeaking?: boolean; // Для удаленных участников - получаем по Socket.IO
  onSpeakingChange?: (isSpeaking: boolean) => void; // Для локального - отправляем изменения
  hasLocalMediaPermission?: boolean; // Есть ли у локального пользователя разрешение на медиа
  mode: "full" | "mini";
  className?: string;
}

export default function UserCamera({
  isMuted,
  isVideoOff,
  hasControl = false,
  // onMute,
  // onVideoOff,
  // onCanControl,
  isAdmin = false,
  name = "Гость",
  mediaStream = null,
  isLocal = false,
  isSpeaking: remoteSpeaking,
  onSpeakingChange,
  hasLocalMediaPermission = false,
  mode = "full",
  className,
}: UserCameraProps) {
  const ref = useRef<HTMLVideoElement>(null);
  // Для удаленных участников: если у локального пользователя есть разрешение на медиа - unmute, иначе mute (для autoplay)
  const [isAudioMuted, setIsAudioMuted] = useState(!hasLocalMediaPermission);

  // Обновляем состояние muted при изменении hasLocalMediaPermission
  useEffect(() => {
    if (!isLocal) {
      // Для удаленных участников: если у локального нет разрешения - mute для autoplay
      setIsAudioMuted(!hasLocalMediaPermission);
      console.log(
        `[UserCamera] ${name} audio muted state updated to ${!hasLocalMediaPermission} (hasLocalMediaPermission: ${hasLocalMediaPermission})`
      );
    }
  }, [hasLocalMediaPermission, isLocal, name]);

  // Явно обновляем атрибут muted у video элемента при изменении isAudioMuted
  useEffect(() => {
    if (ref.current && !isLocal) {
      ref.current.muted = isAudioMuted;
      console.log(
        `[UserCamera] ${name} video element muted attribute set to ${isAudioMuted}`
      );
    }
  }, [isAudioMuted, isLocal, name]);

  // Детекция голосовой активности (только для локального пользователя)
  const { isSpeaking: isVoiceActive } = useVoiceActivity(
    isLocal ? mediaStream : null
  );

  // Для локального - используем локальную детекцию
  // Для удаленных - используем полученное состояние через Socket.IO
  const localSpeaking = !isMuted && isVoiceActive;
  const isSpeaking = isLocal ? localSpeaking : remoteSpeaking || false;

  // Отправляем изменения состояния для локального пользователя
  // Используем ref для отслеживания предыдущего состояния, чтобы избежать лишних вызовов
  const prevLocalSpeakingRef = useRef<boolean>(localSpeaking);

  useEffect(() => {
    if (
      isLocal &&
      onSpeakingChange &&
      prevLocalSpeakingRef.current !== localSpeaking
    ) {
      prevLocalSpeakingRef.current = localSpeaking;
      onSpeakingChange(localSpeaking);
    }
  }, [isLocal, localSpeaking, onSpeakingChange]);

  // Рамка либо горит на 100%, либо выключена
  // isSpeaking уже учитывает threshold и debounce (1 сек)
  const ringOpacity = isSpeaking ? 1 : 0;

  // Логируем для отладки (отключено для снижения шума)
  // useEffect(() => {
  //   console.log(
  //     `[${name}${
  //       isLocal ? " (local)" : ""
  //     }] isSpeaking: ${isSpeaking}, ringOpacity: ${ringOpacity.toFixed(
  //       2
  //     )}, isMuted: ${isMuted}`
  //   );
  // }, [isSpeaking, ringOpacity, name, isMuted, isLocal]);

  useEffect(() => {
    if (ref.current && mediaStream) {
      console.log(
        `[UserCamera] Setting srcObject for ${name}, isLocal: ${isLocal}, stream:`,
        mediaStream
      );
      ref.current.srcObject = mediaStream;

      // Принудительно запускаем воспроизведение
      ref.current.play().catch((error) => {
        console.error(`[UserCamera] Failed to play video for ${name}:`, error);
      });

      // Дополнительная попытка воспроизведения с задержкой для Firefox
      if (!isLocal) {
        // Попытка через 500ms
        setTimeout(() => {
          if (ref.current) {
            console.log(
              `[UserCamera] First retry for ${name}, paused: ${ref.current.paused}, readyState: ${ref.current.readyState}`
            );
            if (ref.current.paused) {
              ref.current.play().catch((error) => {
                console.error(
                  `[UserCamera] First retry play failed for ${name}:`,
                  error
                );
              });
            }
          }
        }, 500);

        // Попытка через 1 секунду
        setTimeout(() => {
          if (ref.current && ref.current.paused) {
            console.log(`[UserCamera] Second retry for ${name} after timeout`);
            ref.current.play().catch((error) => {
              console.error(
                `[UserCamera] Second retry play failed for ${name}:`,
                error
              );
            });
          }
        }, 1000);

        // Еще одна попытка через 3 секунды
        setTimeout(() => {
          if (ref.current) {
            console.log(
              `[UserCamera] Final retry for ${name}, paused: ${ref.current.paused}, readyState: ${ref.current.readyState}`
            );
            if (ref.current.paused) {
              ref.current.play().catch((error) => {
                console.error(
                  `[UserCamera] Final retry play failed for ${name}:`,
                  error
                );
              });
            }
          }
        }, 3000);
      }
    } else if (ref.current && !mediaStream) {
      console.log(`[UserCamera] Clearing srcObject for ${name}`);
      ref.current.srcObject = null;
    }
  }, [mediaStream, name, isLocal]);

  // Добавляем обработчики событий для отладки
  useEffect(() => {
    const videoElement = ref.current;
    if (!videoElement) return;

    const handleLoadStart = () => {
      console.log(`[UserCamera] ${name} video loadstart`);
    };

    const handleLoadedData = () => {
      console.log(`[UserCamera] ${name} video loadeddata`);
    };

    const handleCanPlay = () => {
      console.log(`[UserCamera] ${name} video canplay`);
    };

    const handleLoadedMetadata = () => {
      console.log(`[UserCamera] ${name} video loadedmetadata`);
    };

    const handleCanPlayThrough = () => {
      console.log(`[UserCamera] ${name} video canplaythrough`);
    };

    const handlePlay = () => {
      console.log(`[UserCamera] ${name} video play event`);
    };

    const handlePlaying = () => {
      console.log(`[UserCamera] ${name} video playing event`);
    };

    const handleWaiting = () => {
      console.log(
        `[UserCamera] ${name} video waiting event, paused: ${videoElement.paused}, readyState: ${videoElement.readyState}`
      );
    };

    const handleStalled = () => {
      console.log(
        `[UserCamera] ${name} video stalled event, paused: ${videoElement.paused}, readyState: ${videoElement.readyState}`
      );
    };

    const handlePause = () => {
      console.log(`[UserCamera] ${name} video pause event`);
    };

    const handleError = (e: Event) => {
      console.error(`[UserCamera] ${name} video error:`, e);
    };

    videoElement.addEventListener("loadstart", handleLoadStart);
    videoElement.addEventListener("loadeddata", handleLoadedData);
    videoElement.addEventListener("loadedmetadata", handleLoadedMetadata);
    videoElement.addEventListener("canplay", handleCanPlay);
    videoElement.addEventListener("canplaythrough", handleCanPlayThrough);
    videoElement.addEventListener("play", handlePlay);
    videoElement.addEventListener("playing", handlePlaying);
    videoElement.addEventListener("waiting", handleWaiting);
    videoElement.addEventListener("stalled", handleStalled);
    videoElement.addEventListener("pause", handlePause);
    videoElement.addEventListener("error", handleError);

    return () => {
      videoElement.removeEventListener("loadstart", handleLoadStart);
      videoElement.removeEventListener("loadeddata", handleLoadedData);
      videoElement.removeEventListener("loadedmetadata", handleLoadedMetadata);
      videoElement.removeEventListener("canplay", handleCanPlay);
      videoElement.removeEventListener("canplaythrough", handleCanPlayThrough);
      videoElement.removeEventListener("play", handlePlay);
      videoElement.removeEventListener("playing", handlePlaying);
      videoElement.removeEventListener("waiting", handleWaiting);
      videoElement.removeEventListener("stalled", handleStalled);
      videoElement.removeEventListener("pause", handlePause);
      videoElement.removeEventListener("error", handleError);
    };
  }, [name]);

  const toggleRemoteAudio = () => {
    if (!isLocal) {
      const newMutedState = !isAudioMuted;
      setIsAudioMuted(newMutedState);
      console.log(
        `[UserCamera] ${name} audio ${newMutedState ? "muted" : "unmuted"}`
      );
    }
  };

  const handleVideoClick = () => {
    if (!isLocal && ref.current) {
      console.log(
        `[UserCamera] User clicked on ${name} video, paused: ${ref.current.paused}, readyState: ${ref.current.readyState}, muted: ${ref.current.muted}`
      );
      if (ref.current.paused) {
        ref.current.play().catch((error) => {
          console.error(`[UserCamera] Click play failed for ${name}:`, error);
        });
      } else {
        console.log(`[UserCamera] Video ${name} is already playing`);
      }
    }
  };

  return (
    <div
      className={clsx(
        "select-none group relative pointer-events-auto",
        mode === "mini"
          ? "aspect-square h-fit flex-shrink-0 2xl:hover:w-[10.833vw] 2xl:w-[6.944vw] sm:w-[15.625vw] w-[27.778vw]"
          : "aspect-video max-w-full h-full",
        isLocal && "order-last",
        className
      )}
      style={{
        // boxShadow: isSpeaking
        //   ? `0 4px 40px 0 rgba(15,16,17,0.1), 0 2px 2px 0 rgba(0,0,0,0.06), 0 0 0 ${
        //       window.innerWidth >= 1536 ? "0.139vw" : "2px"
        //     } rgba(34, 197, 94, ${ringOpacity})`
        //   : `0 4px 40px 0 rgba(15,16,17,0.1), 0 2px 2px 0 rgba(0,0,0,0.06), 0 0 0 ${
        //       window.innerWidth >= 1536 ? "0.069vw" : "1px"
        //     } rgba(255, 255, 255, 0.3)`,
        transition:
          mode === "mini"
            ? "box-shadow 0.1s ease-out, width 0.3s, background-color 0.3s"
            : undefined,
      }}
      onClick={handleVideoClick}
    >
      <video
        ref={ref}
        className={clsx(
          "object-cover size-full 2xl:rounded-[1.667vw] rounded-2xl",
          isLocal && "scale-x-[-1]"
          // (!mediaStream || isVideoOff) && ""
        )}
        autoPlay
        muted={isLocal ? true : isAudioMuted}
        playsInline
        style={{
          boxShadow: isSpeaking
            ? `0 4px 40px 0 rgba(15,16,17,0.1), 0 2px 2px 0 rgba(0,0,0,0.06), 0 0 0 ${
                window.innerWidth >= 1440 ? "0.139vw" : "2px"
              } rgba(123, 96, 243, ${ringOpacity})`
            : `0 4px 40px 0 rgba(15,16,17,0.1), 0 2px 2px 0 rgba(0,0,0,0.06), 0 0 0 ${
                window.innerWidth >= 1440 ? "0.069vw" : "1px"
              } rgba(255, 255, 255, 0.3)`,
          transition:
            mode === "mini"
              ? "box-shadow 0.1s ease-out, width 0.3s, background-color 0.3s"
              : "box-shadow 0.1s ease-out",
        }}
        onLoadedData={() => {
          if (!isLocal && ref.current) {
            console.log(
              `[UserCamera] onLoadedData for ${name}, attempting play, readyState: ${ref.current.readyState}`
            );
            ref.current.play().catch((error) => {
              console.error(
                `[UserCamera] onLoadedData play failed for ${name}:`,
                error
              );
            });
          }
        }}
        onLoadedMetadata={() => {
          if (!isLocal && ref.current) {
            console.log(
              `[UserCamera] onLoadedMetadata for ${name}, attempting play, readyState: ${ref.current.readyState}`
            );
            ref.current.play().catch((error) => {
              console.error(
                `[UserCamera] onLoadedMetadata play failed for ${name}:`,
                error
              );
            });
          }
        }}
        onCanPlay={() => {
          if (!isLocal && ref.current) {
            console.log(`[UserCamera] onCanPlay for ${name}, attempting play`);
            ref.current.play().catch((error) => {
              console.error(
                `[UserCamera] onCanPlay play failed for ${name}:`,
                error
              );
            });
          }
        }}
        onPlaying={() => {
          console.log(
            `[UserCamera] onPlaying for ${name} - video is actually playing!`
          );
        }}
        onClick={(e) => {
          e.stopPropagation();
          handleVideoClick();
        }}
      />
      {isAdmin && mode === "mini" && (
        <Admin className="absolute top-0 right-0 z-10" />
      )}

      {/* Заглушка когда нет видео */}
      {(!mediaStream || isVideoOff) && (
        <div className="select-none pointer-events-none absolute inset-0 bg-[url(/img/UserCameraAvatar.png)] bg-cover bg-center 2xl:rounded-[1.667vw] rounded-2xl" />
      )}

      {mode === "mini" && (
        <div 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>
      )}

      {/* Кнопка управления звуком для удаленных участников */}
      {!isLocal && mediaStream && !isVideoOff && (
        <div
          className="absolute top-[0.556vw] right-[0.556vw] opacity-0 group-hover:opacity-100 transition-opacity duration-300"
          onMouseDown={(e) => e.stopPropagation()}
        >
          <button
            onClick={toggleRemoteAudio}
            className="2xl:size-[1.667vw] size-6 bg-[#14141426] backdrop-blur-[4px] hover:bg-[#14141440] rounded-full flex items-center justify-center transition-colors"
            title={isAudioMuted ? "Включить звук" : "Выключить звук"}
          >
            <div className="2xl:size-[0.972vw] size-3.5 text-white">
              {isAudioMuted ? <VolumeOffIcon /> : <VolumeIcon />}
            </div>
          </button>
        </div>
      )}

      {mode === "full" && (
        <div className="2xl:px-[1.111vw] 2xl:py-[0.556vw] px-4 py-2 bg-[#141414]/25 backdrop-blur-[10px] 2xl:rounded-[1.111vw] rounded-2xl absolute 2xl:bottom-[1.111vw] bottom-4 left-1/2 -translate-x-1/2 z-10 flex 2xl:gap-[0.556vw] gap-2 items-center">
          <p className="font-medium text-white button-m">{name}</p>
          {isAdmin && (
            <Admin className="2xl:size-[1.111vw] size-4 absolute 2xl:-top-[0.278vw] 2xl:-right-[0.278vw] -right-1 -top-1" />
          )}
        </div>
      )}

      {/* Индикаторы состояния только для удаленных участников */}
      {!isLocal && mode === "mini" && (
        <UserCameraControls
          isMuted={isMuted}
          isVideoOff={isVideoOff}
          hasControl={hasControl}
        />
      )}
    </div>
  );
}

function UserCameraControls({
  isMuted,
  isVideoOff,
  hasControl,
}: UserCameraControlsProps) {
  return (
    <div
      className="select-none absolute transition-opacity 2xl:bottom-[0.278vw] bottom-1 left-1/2 -translate-x-1/2 flex 2xl:gap-[0.278vw] gap-1 2xl:mb-[0.278vw] mb-1 group-hover:opacity-100 opacity-0"
      // onMouseDown={(e) => e.stopPropagation()}
    >
      {/* Индикатор микрофона */}
      <div className="2xl:size-[1.667vw] size-6 bg-[#14141426] backdrop-blur-[4px] rounded-full flex items-center justify-center">
        <div className="2xl:size-[0.972vw] size-3.5 text-white">
          {isMuted ? <MicrophoneOffFilledIcon /> : <MicrophoneFilledIcon />}
        </div>
      </div>

      {/* Индикатор видео */}
      <div className="2xl:size-[1.667vw] size-6 bg-[#14141426] backdrop-blur-[4px] rounded-full flex items-center justify-center">
        <div className="2xl:size-[0.972vw] size-3.5 text-white">
          {isVideoOff ? <VideoOffFilledIcon /> : <VideoFilledIcon />}
        </div>
      </div>

      {/* Индикатор управления - показывается только если hasControl = true */}
      {hasControl && (
        <div className="2xl:size-[1.667vw] size-6 bg-[#14141426] backdrop-blur-[4px] rounded-full flex items-center justify-center">
          <div className="2xl:size-[0.972vw] size-3.5 text-white">
            <HandRaisedFilledIcon />
          </div>
        </div>
      )}
    </div>
  );
}
