import React, { createContext, useState, useContext, useEffect } from 'react';
import Taro from '@tarojs/taro';
import { roomService } from '../services/api';

// 玩家信息接口
export interface Player {
  userId: string;
  nickName: string;
  avatarUrl: string;
  isHost: boolean;
  joinedAt: Date;
  status: 'active' | 'left';
}

// 房间信息接口
export interface Room {
  roomId: string;
  roomCode: string;
  gameType: string;
  status: 'waiting' | 'playing' | 'ended';
  hostId: string;
  hostInfo: {
    userId: string;
    nickName: string;
    avatarUrl: string;
  };
  players: Player[];
  createdAt: Date;
  maxPlayers: number;
  gameData: any;
  gameResult?: any;
}

// 房间上下文接口
interface RoomContextData {
  currentRoom: Room | null;
  isLoading: boolean;
  error: string | null;
  createRoom: (gameType: string, maxPlayers?: number) => Promise<string | null>;
  joinRoom: (roomCode: string) => Promise<boolean>;
  getRoomInfo: (roomId?: string, roomCode?: string) => Promise<boolean>;
  leaveRoom: () => Promise<boolean>;
  startGame: () => Promise<boolean>;
  endGame: (gameResult?: any) => Promise<boolean>;
  updateGameData: (gameData: any) => Promise<boolean>;
}

// 创建上下文
const RoomContext = createContext<RoomContextData>({
  currentRoom: null,
  isLoading: false,
  error: null,
  createRoom: async () => null,
  joinRoom: async () => false,
  getRoomInfo: async () => false,
  leaveRoom: async () => false,
  startGame: async () => false,
  endGame: async () => false,
  updateGameData: async () => false,
});

// 轮询间隔时间（毫秒）
const POLLING_INTERVAL = 3000;

// 房间上下文提供者组件
export const RoomProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [currentRoom, setCurrentRoom] = useState<Room | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [pollingTimer, setPollingTimer] = useState<NodeJS.Timeout | null>(null);

  // 清理轮询定时器
  useEffect(() => {
    return () => {
      if (pollingTimer) {
        clearInterval(pollingTimer);
      }
    };
  }, [pollingTimer]);

  // 从本地存储初始化房间信息
  useEffect(() => {
    const storedRoom = Taro.getStorageSync('currentRoom');
    if (storedRoom) {
      try {
        const roomData = JSON.parse(storedRoom);
        setCurrentRoom(roomData);
        
        // 如果有房间信息，启动轮询
        if (roomData && roomData.roomId) {
          startPolling(roomData.roomId);
        }
      } catch (error) {
        console.error('从存储中获取房间信息失败:', error);
      }
    }
  }, []);

  // 启动房间信息轮询
  const startPolling = (roomId: string) => {
    // 清除现有定时器
    if (pollingTimer) {
      clearInterval(pollingTimer);
    }

    // 创建新定时器
    const timer = setInterval(async () => {
      try {
        const res = await roomService.getRoomInfo(roomId);
        if (res.code === 200 && res.data) {
          const newRoomData = res.data;
          setCurrentRoom(newRoomData);
          Taro.setStorageSync('currentRoom', JSON.stringify(newRoomData));
          
          // 如果房间已结束，停止轮询
          if (newRoomData.status === 'ended') {
            clearInterval(timer);
            setPollingTimer(null);
          }
        } else if (res.code === 404) {
          // 房间不存在或已结束
          clearInterval(timer);
          setPollingTimer(null);
          setCurrentRoom(null);
          Taro.removeStorageSync('currentRoom');
        }
      } catch (error) {
        console.error('轮询房间信息失败:', error);
      }
    }, POLLING_INTERVAL);

    setPollingTimer(timer);
  };

  // 创建房间
  const createRoom = async (gameType: string, maxPlayers = 8): Promise<string | null> => {
    setIsLoading(true);
    setError(null);
    try {
      const res = await roomService.createRoom(gameType, maxPlayers);
      if (res.code === 200 && res.data) {
        const roomData = res.data;
        setCurrentRoom(roomData);
        Taro.setStorageSync('currentRoom', JSON.stringify(roomData));
        startPolling(roomData.roomId);
        return roomData.roomId;
      } else {
        setError(res.message || '创建房间失败');
        return null;
      }
    } catch (error) {
      console.error('创建房间异常:', error);
      setError('创建房间异常: ' + (error.message || error));
      return null;
    } finally {
      setIsLoading(false);
    }
  };

  // 加入房间
  const joinRoom = async (roomCode: string): Promise<boolean> => {
    setIsLoading(true);
    setError(null);
    try {
      const res = await roomService.joinRoom(roomCode);
      if (res.code === 200 && res.data) {
        const roomData = res.data;
        setCurrentRoom(roomData);
        Taro.setStorageSync('currentRoom', JSON.stringify(roomData));
        startPolling(roomData.roomId);
        return true;
      } else {
        setError(res.message || '加入房间失败');
        return false;
      }
    } catch (error) {
      console.error('加入房间异常:', error);
      setError('加入房间异常: ' + (error.message || error));
      return false;
    } finally {
      setIsLoading(false);
    }
  };

  // 获取房间信息
  const getRoomInfo = async (roomId?: string, roomCode?: string): Promise<boolean> => {
    if (!roomId && !roomCode && currentRoom) {
      roomId = currentRoom.roomId;
    }

    if (!roomId && !roomCode) {
      setError('缺少必要参数: roomId或roomCode');
      return false;
    }

    setIsLoading(true);
    setError(null);
    try {
      const res = await roomService.getRoomInfo(roomId, roomCode);
      if (res.code === 200 && res.data) {
        const roomData = res.data;
        setCurrentRoom(roomData);
        Taro.setStorageSync('currentRoom', JSON.stringify(roomData));
        if (roomData.roomId && !pollingTimer) {
          startPolling(roomData.roomId);
        }
        return true;
      } else {
        setError(res.message || '获取房间信息失败');
        if (res.code === 404) {
          setCurrentRoom(null);
          Taro.removeStorageSync('currentRoom');
        }
        return false;
      }
    } catch (error) {
      console.error('获取房间信息异常:', error);
      setError('获取房间信息异常: ' + (error.message || error));
      return false;
    } finally {
      setIsLoading(false);
    }
  };

  // 离开房间
  const leaveRoom = async (): Promise<boolean> => {
    if (!currentRoom || !currentRoom.roomId) {
      setError('当前未加入任何房间');
      return false;
    }

    setIsLoading(true);
    setError(null);
    try {
      const res = await roomService.leaveRoom(currentRoom.roomId);
      if (res.code === 200) {
        // 停止轮询
        if (pollingTimer) {
          clearInterval(pollingTimer);
          setPollingTimer(null);
        }
        
        setCurrentRoom(null);
        Taro.removeStorageSync('currentRoom');
        return true;
      } else {
        setError(res.message || '离开房间失败');
        return false;
      }
    } catch (error) {
      console.error('离开房间异常:', error);
      setError('离开房间异常: ' + (error.message || error));
      return false;
    } finally {
      setIsLoading(false);
    }
  };

  // 开始游戏
  const startGame = async (): Promise<boolean> => {
    if (!currentRoom || !currentRoom.roomId) {
      setError('当前未加入任何房间');
      return false;
    }

    setIsLoading(true);
    setError(null);
    try {
      const res = await roomService.startGame(currentRoom.roomId);
      if (res.code === 200) {
        // 更新房间状态
        await getRoomInfo(currentRoom.roomId);
        return true;
      } else {
        setError(res.message || '开始游戏失败');
        return false;
      }
    } catch (error) {
      console.error('开始游戏异常:', error);
      setError('开始游戏异常: ' + (error.message || error));
      return false;
    } finally {
      setIsLoading(false);
    }
  };

  // 结束游戏
  const endGame = async (gameResult?: any): Promise<boolean> => {
    if (!currentRoom || !currentRoom.roomId) {
      setError('当前未加入任何房间');
      return false;
    }

    setIsLoading(true);
    setError(null);
    try {
      const res = await roomService.endGame(currentRoom.roomId, gameResult);
      if (res.code === 200) {
        // 停止轮询
        if (pollingTimer) {
          clearInterval(pollingTimer);
          setPollingTimer(null);
        }
        
        // 更新房间状态
        await getRoomInfo(currentRoom.roomId);
        return true;
      } else {
        setError(res.message || '结束游戏失败');
        return false;
      }
    } catch (error) {
      console.error('结束游戏异常:', error);
      setError('结束游戏异常: ' + (error.message || error));
      return false;
    } finally {
      setIsLoading(false);
    }
  };

  // 更新游戏数据
  const updateGameData = async (gameData: any): Promise<boolean> => {
    if (!currentRoom || !currentRoom.roomId) {
      setError('当前未加入任何房间');
      return false;
    }

    setIsLoading(true);
    setError(null);
    try {
      const res = await roomService.updateGameData(currentRoom.roomId, gameData);
      if (res.code === 200) {
        // 更新房间状态
        await getRoomInfo(currentRoom.roomId);
        return true;
      } else {
        setError(res.message || '更新游戏数据失败');
        return false;
      }
    } catch (error) {
      console.error('更新游戏数据异常:', error);
      setError('更新游戏数据异常: ' + (error.message || error));
      return false;
    } finally {
      setIsLoading(false);
    }
  };

  const value = {
    currentRoom,
    isLoading,
    error,
    createRoom,
    joinRoom,
    getRoomInfo,
    leaveRoom,
    startGame,
    endGame,
    updateGameData,
  };

  return <RoomContext.Provider value={value}>{children}</RoomContext.Provider>;
};

// 自定义钩子，用于获取房间上下文
export const useRoom = () => useContext(RoomContext);

export default RoomContext; 