import { useEffect, useState, useRef } from "react";
import {
  createWebRTCService,
  type Participant,
  type ChatMessage,
} from "../lib/webrtc";

let webrtcServiceInstance: ReturnType<typeof createWebRTCService> | null = null;
let isInitializing = false;

export const useWebRTC = (roomId?: string, autoJoin = false) => {
  const callbacksRegisteredRef = useRef(false);
  const hasJoinedRoomRef = useRef(false);
  const [localStream, setLocalStream] = useState<MediaStream | null>(null);
  const [participants, setParticipants] = useState<Participant[]>([]);
  const [isAudioMuted, setIsAudioMuted] = useState(false);
  const [isVideoMuted, setIsVideoMuted] = useState(false);
  const [chatMessages, setChatMessages] = useState<ChatMessage[]>([]);
  const [isConnected, setIsConnected] = useState(false);
  const [isInitialized, setIsInitialized] = useState(false);

  // Мониторинг изменений участников (отключено для снижения шума в консоли)
  // useEffect(() => {
  //   console.log("[useWebRTC] Participants state updated:", participants.map(p => ({
  //     id: p.id,
  //     hasStream: !!p.stream,
  //   })));
  // }, [participants]);

  useEffect(() => {
    // Создаем сервис только один раз (синглтон)
    if (!webrtcServiceInstance) {
      webrtcServiceInstance = createWebRTCService({});
    }

    // Инициализируем состояние из существующего сервиса
    const existingStream = webrtcServiceInstance.getLocalStream();
    if (existingStream) {
      console.log("[useWebRTC] Initializing with existing local stream");
      setLocalStream(existingStream);
      setIsInitialized(true);
    }

    const existingParticipants = webrtcServiceInstance.getParticipants();
    console.log("[useWebRTC] Component mounted, existing participants:", existingParticipants.length);
    if (existingParticipants.length > 0) {
      console.log("[useWebRTC] Initializing with participants:", existingParticipants.map(p => p.id));
      setParticipants(existingParticipants);
    }

    const existingMessages = webrtcServiceInstance.getChatMessages();
    if (existingMessages.length > 0) {
      console.log("[useWebRTC] Initializing with existing messages:", existingMessages.length);
      setChatMessages(existingMessages);
    }

    // Добавляем коллбэки только один раз для этого компонента
    if (callbacksRegisteredRef.current) {
      return;
    }

    callbacksRegisteredRef.current = true;
    const removeCallbacks = webrtcServiceInstance.addCallbacks({
      onLocalStreamReady: (stream) => {
        console.log("[useWebRTC] Local stream ready");
        setLocalStream(stream);
        setIsInitialized(true);
      },
      onRemoteStreamReady: (participantId, stream) => {
        console.log("[useWebRTC] onRemoteStreamReady called for:", participantId);
        setParticipants((prev) => {
          const existing = prev.find((p) => p.id === participantId);
          if (existing) {
            console.log("[useWebRTC] Updating stream for existing participant:", participantId);
            return prev.map((p) =>
              p.id === participantId ? { ...p, stream } : p
            );
          } else {
            console.log("[useWebRTC] Adding new participant with stream:", participantId);
            return [...prev, { id: participantId, stream }];
          }
        });
      },
      onRoomParticipants: () => {
        setIsConnected(true);
      },
      onParticipantJoined: (participant) => {
        console.log("[useWebRTC] onParticipantJoined called for:", participant.id);
        setParticipants((prev) => {
          if (prev.find((p) => p.id === participant.id)) {
            console.log("[useWebRTC] Participant already in list, skipping");
            return prev;
          }
          console.log("[useWebRTC] Adding participant to state");
          return [...prev, participant];
        });
      },
      onParticipantLeft: (participantId) => {
        setParticipants((prev) => prev.filter((p) => p.id !== participantId));
      },
      onParticipantAudioToggle: (participantId, isEnabled) => {
        console.log(`[useWebRTC] Audio toggle for ${participantId}: ${isEnabled}`);
        setParticipants((prev) =>
          prev.map((p) =>
            p.id === participantId ? { ...p, isMuted: !isEnabled } : p
          )
        );
      },
      onParticipantVideoToggle: (participantId, isEnabled) => {
        console.log(`[useWebRTC] Video toggle for ${participantId}: ${isEnabled}`);
        setParticipants((prev) =>
          prev.map((p) =>
            p.id === participantId ? { ...p, isVideoOff: !isEnabled } : p
          )
        );
      },
      onParticipantSpeakingChange: (participantId, isSpeaking) => {
        setParticipants((prev) =>
          prev.map((p) =>
            p.id === participantId ? { ...p, isSpeaking } : p
          )
        );
      },
      onChatMessage: (message) => {
        console.log("[useWebRTC] onChatMessage called:", message);
        setChatMessages((prev) => [...prev, message]);
      },
      onError: (error) => {
        console.error("[useWebRTC] Error:", error);
      },
    });

    const initWebRTC = async () => {
      if (!webrtcServiceInstance || isInitializing) {
        return;
      }

      // Проверяем, есть ли уже localStream
      if (webrtcServiceInstance.getLocalStream()) {
        setIsInitialized(true);
        return;
      }

      try {
        isInitializing = true;
        const stream = await webrtcServiceInstance.initializeLocalStream();
        
        // Даже если stream === null (пользователь отказался от разрешений),
        // считаем инициализацию завершенной
        if (stream === null) {
          console.log("[useWebRTC] Initialized without local stream (user denied permissions)");
          setIsInitialized(true);
        }
      } catch (error) {
        console.error("[useWebRTC] Initialization error:", error);
        // Даже при ошибке разрешаем продолжить
        setIsInitialized(true);
      } finally {
        isInitializing = false;
      }
    };

    initWebRTC();

    // Cleanup при размонтировании компонента
    return () => {
      callbacksRegisteredRef.current = false;
      removeCallbacks();
    };
  }, []); // Пустой массив зависимостей - эффект срабатывает только при монтировании

  // Отдельный эффект для присоединения к комнате
  // ВАЖНО: Присоединяемся только ПОСЛЕ инициализации localStream!
  useEffect(() => {
    if (
      !webrtcServiceInstance ||
      !autoJoin ||
      !roomId ||
      hasJoinedRoomRef.current ||
      !isInitialized
    ) {
      return;
    }

    const joinRoomAsync = async () => {
      await webrtcServiceInstance!.joinRoom(roomId);
      hasJoinedRoomRef.current = true;
    };

    joinRoomAsync();
  }, [roomId, autoJoin, isInitialized]);

  const toggleAudio = () => {
    if (!webrtcServiceInstance) return;
    const newState = webrtcServiceInstance.toggleAudio();
    setIsAudioMuted(!newState);
  };

  const toggleVideo = () => {
    if (!webrtcServiceInstance) return;
    const newState = webrtcServiceInstance.toggleVideo();
    setIsVideoMuted(!newState);
  };

  const sendMessage = (content: string, senderName?: string, isAuthenticated?: boolean) => {
    if (!webrtcServiceInstance) return;
    webrtcServiceInstance.sendChatMessage(content, senderName, isAuthenticated);
  };

  const joinRoom = async (roomId: string) => {
    if (!webrtcServiceInstance) return;
    await webrtcServiceInstance.joinRoom(roomId);
    setIsConnected(true);
  };

  const leaveRoom = () => {
    if (!webrtcServiceInstance) return;
    webrtcServiceInstance.leaveRoom();
    setIsConnected(false);
    setParticipants([]);
  };

  const updateSpeakingState = (isSpeaking: boolean) => {
    if (!webrtcServiceInstance) return;
    webrtcServiceInstance.updateSpeakingState(isSpeaking);
  };

  const updateUserId = (newUserId: string) => {
    if (!webrtcServiceInstance) return;
    webrtcServiceInstance.updateUserId(newUserId);
  };

  return {
    localStream,
    participants,
    isAudioMuted,
    isVideoMuted,
    chatMessages,
    isConnected,
    isInitialized,
    currentUserId: webrtcServiceInstance?.getCurrentUserId() || "",
    toggleAudio,
    toggleVideo,
    sendMessage,
    updateSpeakingState,
    updateUserId,
    joinRoom,
    leaveRoom,
  };
};
