// React Hook for Play Page Synchronization
'use client';

import { useRouter } from 'next/navigation';
import { useCallback,useEffect, useRef } from 'react';

import { useWatchRoomContextSafe } from '@/components/WatchRoomProvider';

import type { PlayState } from '@/types/watch-room';

interface UsePlaySyncOptions {
  artPlayerRef: React.MutableRefObject<any>;
  videoId: string;
  videoName: string;
  videoYear?: string;
  searchTitle?: string;
  currentEpisode?: number;
  currentSource: string;
  videoUrl: string;
  playerReady: boolean;  // 播放器是否就绪
}

export function usePlaySync({
  artPlayerRef,
  videoId,
  videoName,
  videoYear,
  searchTitle,
  currentEpisode,
  currentSource,
  videoUrl,
  playerReady,
}: UsePlaySyncOptions) {
  const router = useRouter();
  const watchRoom = useWatchRoomContextSafe();
  const lastSyncTimeRef = useRef(0); // 上次同步时间
  const isHandlingRemoteCommandRef = useRef(false); // 标记是否正在处理远程命令

  // 检查是否在房间内
  const isInRoom = !!(watchRoom && watchRoom.currentRoom);
  const isOwner = watchRoom?.isOwner || false;
  const currentRoom = watchRoom?.currentRoom;
  const socket = watchRoom?.socket;

  // 广播播放状态给房间内所有人（任何成员都可以触发同步）
  const broadcastPlayState = useCallback(() => {
    if (!socket || !watchRoom || !isInRoom) return;

    const player = artPlayerRef.current;
    if (!player) return;

    const state: PlayState = {
      type: 'play',
      url: videoUrl,
      currentTime: player.currentTime || 0,
      isPlaying: player.playing || false,
      videoId,
      videoName,
      videoYear,
      searchTitle,
      episode: currentEpisode,
      source: currentSource,
    };

    // 使用防抖，避免频繁发送
    const now = Date.now();
    if (now - lastSyncTimeRef.current < 1000) return;
    lastSyncTimeRef.current = now;

    watchRoom.updatePlayState(state);
  }, [socket, videoUrl, videoId, videoName, videoYear, searchTitle, currentEpisode, currentSource, watchRoom, artPlayerRef, isInRoom]);

  // 接收并同步其他成员的播放状态
  useEffect(() => {
    if (!socket || !currentRoom || !isInRoom) {
      console.log('[PlaySync] Skip setup:', { hasSocket: !!socket, hasRoom: !!currentRoom, isInRoom });
      return;
    }

    console.log('[PlaySync] Setting up event listeners');

    const handlePlayUpdate = (state: PlayState) => {
      console.log('[PlaySync] Received play:update event:', state);
      const player = artPlayerRef.current;

      if (!player) {
        console.warn('[PlaySync] Player not ready for play:update');
        return;
      }

      console.log('[PlaySync] Processing play update - current state:', {
        playerPlaying: player.playing,
        statePlaying: state.isPlaying,
        playerTime: player.currentTime,
        stateTime: state.currentTime
      });

      // 标记正在处理远程命令
      isHandlingRemoteCommandRef.current = true;

      // play:update 只同步进度，不改变播放/暂停状态
      // 播放/暂停状态由 play:play 和 play:pause 命令控制
      const timeDiff = Math.abs(player.currentTime - state.currentTime);
      if (timeDiff > 2) {
        console.log('[PlaySync] Seeking to:', state.currentTime, '(diff:', timeDiff, 's)');
        player.currentTime = state.currentTime;
        // 延迟重置标记，确保 seeked 事件已处理完毕
        setTimeout(() => {
          isHandlingRemoteCommandRef.current = false;
          console.log('[PlaySync] Reset flag after seek');
        }, 500);
      } else {
        console.log('[PlaySync] Time diff is small, no seek needed');
        // 没有操作，立即重置标记
        isHandlingRemoteCommandRef.current = false;
      }
    };

    const handlePlayCommand = () => {
      console.log('[PlaySync] ========== Received play:play event ==========');
      console.log('[PlaySync] isHandlingRemoteCommandRef:', isHandlingRemoteCommandRef.current);
      const player = artPlayerRef.current;

      if (!player) {
        console.warn('[PlaySync] Player not ready for play:play');
        return;
      }

      console.log('[PlaySync] Player state before play:', {
        playing: player.playing,
        currentTime: player.currentTime,
        readyState: player.video?.readyState,
      });

      // 标记正在处理远程命令
      isHandlingRemoteCommandRef.current = true;
      console.log('[PlaySync] Set flag to true');

      // 只有在暂停状态时才执行播放
      if (!player.playing) {
        console.log('[PlaySync] Executing play command - calling player.play()');
        player.play()
          .then(() => {
            console.log('[PlaySync] Play command completed successfully');
            console.log('[PlaySync] Player state after play:', {
              playing: player.playing,
              currentTime: player.currentTime,
            });
            // 等待播放器事件触发后再重置标记
            setTimeout(() => {
              isHandlingRemoteCommandRef.current = false;
              console.log('[PlaySync] Reset flag after play');
            }, 500);
          })
          .catch((err: any) => {
            console.error('[PlaySync] Play error:', err);
            isHandlingRemoteCommandRef.current = false;
          });
      } else {
        console.log('[PlaySync] Player already playing, skipping');
        isHandlingRemoteCommandRef.current = false;
      }
      console.log('[PlaySync] ========== End play:play handling ==========');
    };

    const handlePauseCommand = () => {
      console.log('[PlaySync] ========== Received play:pause event ==========');
      console.log('[PlaySync] isHandlingRemoteCommandRef:', isHandlingRemoteCommandRef.current);
      const player = artPlayerRef.current;

      if (!player) {
        console.warn('[PlaySync] Player not ready for play:pause');
        return;
      }

      console.log('[PlaySync] Player state before pause:', {
        playing: player.playing,
        currentTime: player.currentTime,
      });

      // 标记正在处理远程命令
      isHandlingRemoteCommandRef.current = true;
      console.log('[PlaySync] Set flag to true');

      // 只有在播放状态时才执行暂停
      if (player.playing) {
        console.log('[PlaySync] Executing pause command - calling player.pause()');
        player.pause();
        console.log('[PlaySync] Player state after pause:', {
          playing: player.playing,
          currentTime: player.currentTime,
        });
        // pause 是同步的，但还是延迟重置以确保事件处理完毕
        setTimeout(() => {
          isHandlingRemoteCommandRef.current = false;
          console.log('[PlaySync] Reset flag after pause');
        }, 500);
      } else {
        console.log('[PlaySync] Player already paused, skipping');
        isHandlingRemoteCommandRef.current = false;
      }
      console.log('[PlaySync] ========== End play:pause handling ==========');
    };

    const handleSeekCommand = (currentTime: number) => {
      console.log('[PlaySync] Received play:seek event:', currentTime);
      const player = artPlayerRef.current;

      if (!player) {
        console.warn('[PlaySync] Player not ready for play:seek');
        return;
      }

      // 标记正在处理远程命令
      isHandlingRemoteCommandRef.current = true;

      console.log('[PlaySync] Executing seek command');
      player.currentTime = currentTime;

      // 延迟重置标记，确保 seeked 事件已处理完毕
      setTimeout(() => {
        isHandlingRemoteCommandRef.current = false;
        console.log('[PlaySync] Reset flag after seek command');
      }, 500);
    };

    const handleChangeCommand = (state: PlayState) => {
      console.log('[PlaySync] Received play:change event:', state);
      console.log('[PlaySync] Current isOwner:', isOwner);

      // 只有房员才处理视频切换命令
      if (isOwner) {
        console.log('[PlaySync] Skipping play:change - user is owner');
        return;
      }

      // 跟随切换视频
      // 构建完整的 URL 参数
      const params = new URLSearchParams({
        id: state.videoId,
        source: state.source,
        episode: String(state.episode || 1),
      });

      // 添加可选参数
      if (state.videoName) params.set('title', state.videoName);
      if (state.videoYear) params.set('year', state.videoYear);
      if (state.searchTitle) params.set('stitle', state.searchTitle);

      const url = `/play?${params.toString()}`;
      console.log('[PlaySync] Member redirecting to:', url);

      // 使用 router.push 进行导航,支持在同一页面更新参数
      router.push(url);
    };

    socket.on('play:update', handlePlayUpdate);
    socket.on('play:play', handlePlayCommand);
    socket.on('play:pause', handlePauseCommand);
    socket.on('play:seek', handleSeekCommand);
    socket.on('play:change', handleChangeCommand);

    console.log('[PlaySync] Event listeners registered');

    return () => {
      console.log('[PlaySync] Cleaning up event listeners');
      socket.off('play:update', handlePlayUpdate);
      socket.off('play:play', handlePlayCommand);
      socket.off('play:pause', handlePauseCommand);
      socket.off('play:seek', handleSeekCommand);
      socket.off('play:change', handleChangeCommand);
    };
  }, [socket, currentRoom, isInRoom, isOwner]);

  // 监听播放器事件并广播（所有成员都可以触发同步）
  useEffect(() => {
    if (!socket || !currentRoom || !isInRoom || !watchRoom) {
      console.log('[PlaySync] Skip player setup:', { hasSocket: !!socket, hasRoom: !!currentRoom, isInRoom, hasWatchRoom: !!watchRoom });
      return;
    }

    if (!playerReady) {
      console.log('[PlaySync] Player not ready yet, waiting...');
      return;
    }

    const player = artPlayerRef.current;
    if (!player) {
      console.warn('[PlaySync] Player ref is null despite playerReady=true');
      return;
    }

    console.log('[PlaySync] Setting up player event listeners');

    const handlePlay = () => {
      // 如果正在处理远程命令，不要广播（避免循环）
      if (isHandlingRemoteCommandRef.current) {
        console.log('[PlaySync] Play event triggered by remote command, not broadcasting');
        return;
      }

      const player = artPlayerRef.current;
      if (!player) return;

      // 确认播放器确实在播放状态才广播
      if (player.playing) {
        console.log('[PlaySync] Play event detected, player is playing, broadcasting...');
        // 只发送 play 命令，不发送完整状态（避免重复）
        watchRoom.play();
      } else {
        console.log('[PlaySync] Play event detected but player is paused, not broadcasting');
      }
    };

    const handlePause = () => {
      // 如果正在处理远程命令，不要广播（避免循环）
      if (isHandlingRemoteCommandRef.current) {
        console.log('[PlaySync] Pause event triggered by remote command, not broadcasting');
        return;
      }

      const player = artPlayerRef.current;
      if (!player) return;

      // 确认播放器确实在暂停状态才广播
      if (!player.playing) {
        console.log('[PlaySync] Pause event detected, player is paused, broadcasting...');
        // 只发送 pause 命令，不发送完整状态（避免重复）
        watchRoom.pause();
      } else {
        console.log('[PlaySync] Pause event detected but player is playing, not broadcasting');
      }
    };

    const handleSeeked = () => {
      // 如果正在处理远程命令，不要广播（避免循环）
      if (isHandlingRemoteCommandRef.current) {
        console.log('[PlaySync] Seeked event triggered by remote command, not broadcasting');
        return;
      }

      const player = artPlayerRef.current;
      if (!player) return;

      console.log('[PlaySync] Seeked event detected, broadcasting time:', player.currentTime);
      watchRoom.seekPlayback(player.currentTime);
    };

    player.on('play', handlePlay);
    player.on('pause', handlePause);
    player.on('seeked', handleSeeked);

    // 定期同步播放进度（每5秒）
    const syncInterval = setInterval(() => {
      if (!player.playing) return; // 暂停时不同步

      console.log('[PlaySync] Periodic sync - broadcasting state');
      broadcastPlayState();
    }, 5000);

    console.log('[PlaySync] Player event listeners registered with periodic sync');

    return () => {
      console.log('[PlaySync] Cleaning up player event listeners');
      player.off('play', handlePlay);
      player.off('pause', handlePause);
      player.off('seeked', handleSeeked);
      clearInterval(syncInterval);
    };
  }, [socket, currentRoom, artPlayerRef, watchRoom, broadcastPlayState, isInRoom, playerReady]);

  // 使用ref跟踪上一次的值，用于检测真正的变化
  const lastBroadcastRef = useRef<{
    videoId: string;
    source: string;
    episode: number;
  } | null>(null);

  // 房主：监听视频/集数/源变化并广播
  useEffect(() => {
    if (!isOwner || !socket || !currentRoom || !isInRoom || !watchRoom) {
      // 如果不是房主或不在房间，重置跟踪
      lastBroadcastRef.current = null;
      return;
    }
    if (!videoId || !videoUrl) return;

    const currentState = {
      videoId,
      source: currentSource,
      episode: currentEpisode || 1,
    };

    // 检查是否需要广播
    const shouldBroadcast = !lastBroadcastRef.current ||
      lastBroadcastRef.current.videoId !== currentState.videoId ||
      lastBroadcastRef.current.source !== currentState.source ||
      lastBroadcastRef.current.episode !== currentState.episode;

    if (!shouldBroadcast) {
      console.log('[PlaySync] No change detected, skipping broadcast');
      return;
    }

    console.log('[PlaySync] Detected change, will broadcast:', {
      from: lastBroadcastRef.current,
      to: currentState
    });

    // 延迟广播，确保页面已经稳定
    const timer = setTimeout(() => {
      const state: PlayState = {
        type: 'play',
        url: videoUrl,
        currentTime: artPlayerRef.current?.currentTime || 0,
        isPlaying: artPlayerRef.current?.playing || false,
        videoId,
        videoName,
        videoYear,
        searchTitle,
        episode: currentEpisode,
        source: currentSource,
      };

      console.log('[PlaySync] Broadcasting play:change:', state);
      watchRoom.changeVideo(state);

      // 更新跟踪值
      lastBroadcastRef.current = currentState;
    }, 500); // 减少延迟到500ms

    return () => clearTimeout(timer);
  }, [isOwner, socket, currentRoom, isInRoom, watchRoom, videoId, currentEpisode, currentSource, videoUrl, videoName, videoYear, searchTitle, artPlayerRef]);

  // 房主：加入房间时立即广播当前播放状态
  const lastRoomStateRef = useRef<{ isOwner: boolean; roomId: string | null }>({ isOwner: false, roomId: null });

  useEffect(() => {
    const currentRoomId = currentRoom?.id || null;
    const prevRoomState = lastRoomStateRef.current;

    // 检测是否刚成为房主或刚加入房间
    const justBecameOwner = !prevRoomState.isOwner && isOwner;
    const justJoinedRoom = !prevRoomState.roomId && currentRoomId;

    // 更新ref
    lastRoomStateRef.current = { isOwner, roomId: currentRoomId };

    if (!isOwner || !socket || !currentRoom || !isInRoom || !watchRoom) return;
    if (!videoId || !videoUrl) return;
    if (!justBecameOwner && !justJoinedRoom) return;

    console.log('[PlaySync] Owner joined room, broadcasting current state immediately:', {
      justBecameOwner,
      justJoinedRoom
    });

    // 立即广播当前状态
    const state: PlayState = {
      type: 'play',
      url: videoUrl,
      currentTime: artPlayerRef.current?.currentTime || 0,
      isPlaying: artPlayerRef.current?.playing || false,
      videoId,
      videoName,
      videoYear,
      searchTitle,
      episode: currentEpisode,
      source: currentSource,
    };

    // 短暂延迟确保房间连接已稳定
    const timer = setTimeout(() => {
      console.log('[PlaySync] Broadcasting play:change on room join:', state);
      watchRoom.changeVideo(state);

      // 同时更新跟踪值，避免立即重复广播
      lastBroadcastRef.current = {
        videoId,
        source: currentSource,
        episode: currentEpisode || 1,
      };
    }, 300);

    return () => clearTimeout(timer);
  }, [isOwner, currentRoom, socket, isInRoom, watchRoom, videoId, videoUrl, videoName, videoYear, searchTitle, currentEpisode, currentSource, artPlayerRef]);

  return {
    isInRoom,
    isOwner,
    shouldDisableControls: isInRoom && !isOwner, // 房员禁用某些控制
    broadcastPlayState, // 导出供手动调用
  };
}
