import React, { useState, useEffect, useRef, createContext, useContext } from 'react';
import AliRtcEngine, { AliRtcSubscribeState, AliRtcVideoTrack, AliRtcSdkChannelProfile } from 'aliyun-rtc-sdk';
import { ToastContainer, toast } from 'react-toastify';

// 从 SDK 中提取需要的类型
type ImEngine = InstanceType<typeof AliVCInteraction.ImEngine>;
type ImGroupManager = AliVCInteraction.AliVCIMGroupManager;
type ImMessageManager = AliVCInteraction.AliVCIMMessageManager;
type ImLogLevel = AliVCInteraction.ImLogLevel;
type ImMessageLevel = AliVCInteraction.ImMessageLevel;

interface ImUser {
  userId: string;
  userExtension?: string;
}

interface ImGroupMessage {
  groupId: string;
  type: number;
  data: string;
  sender?: ImUser;
  timestamp?: number;
}

// 课堂上下文类型
type ClassroomContextType = {
  userId: string;
  role: 'teacher' | 'student';
  isLoggedIn: boolean;
  isJoinedClass: boolean;
  messageList: string[];
  errorMessage: string;
  setRole: (role: 'teacher' | 'student') => void;
};

const ClassroomContext = createContext<ClassroomContextType | null>(null);

// 辅助函数
function hex(buffer: ArrayBuffer): string {
  const hexCodes = [];
  const view = new DataView(buffer);
  for (let i = 0; i < view.byteLength; i += 4) {
    const value = view.getUint32(i);
    const stringValue = value.toString(16);
    const padding = '00000000';
    const paddedValue = (padding + stringValue).slice(-padding.length);
    hexCodes.push(paddedValue);
  }
  return hexCodes.join('');
}

async function generateToken(
  appId: string,
  appKey: string,
  channelId: string,
  userId: string,
  timestamp: number
): Promise<string> {
  const encoder = new TextEncoder();
  const data = encoder.encode(`${appId}${appKey}${channelId}${userId}${timestamp}`);
  const hash = await crypto.subtle.digest('SHA-256', data);
  return hex(hash);
}

function showToast(type: 'info' | 'success' | 'error', message: string): void {
  switch(type) {
    case 'info':
      toast.info(message);
      break;
    case 'success':
      toast.success(message);
      break;
    case 'error':
      toast.error(message);
      break;
  }
}

// 从SDK获取枚举值
const { ImLogLevel, ImMessageLevel } = window.AliVCInteraction;

// 配置信息
const IM_APP_ID = '4c2ab5e1b1b0';
const IM_APP_KEY = '314bb5eee5b623549e8a41574ba3ff32';
const IM_APP_SIGN = 'H4sIAAAAAAAE/wCQAG//zguHB+lYCilkv7diSkk4GmcvLuds+InRu9vFOFebMwm/jEgsK5bBT85Z0owObMxG58uXHyPFlPEBEDQm9FswNJ+KmX0VDYkcfdPPWkafA6Hc0B6F+p5De9yJfPEfHzwo/DHMaygbHfLmBgUtmKveq421sJr/gNBz9D04Ewsg39us+ao0NegzLt7xtXvFXXXJAAAA//8BAAD//yoav6aQAAAA';
const RTC_APP_ID = 'a5842c2a-d94a-43be-81de-1fdb712476e1';
const RTC_APP_KEY = 'b71d65f4f84c450f6f058f4ad507bd42';

export const ClassroomPage = () => {
  // 状态管理
  const [userId, setUserId] = useState<string>('');
  const [role, setRole] = useState<'teacher' | 'student'>('student');
  const [classId, setClassId] = useState<string>('');
  const [isLoggedIn, setIsLoggedIn] = useState<boolean>(false);
  const [isJoinedClass, setIsJoinedClass] = useState<boolean>(false);
  const [msgText, setMsgText] = useState<string>('');
  const [messageList, setMessageList] = useState<string[]>([]);
  const [errorMessage, setErrorMessage] = useState<string>('');

  // SDK实例
  const imEngine = useRef<ImEngine | null>(null);
  const imGroupManager = useRef<ImGroupManager | null>(null);
  const imMessageManager = useRef<ImMessageManager | null>(null);
  const aliRtcEngine = useRef<AliRtcEngine | null>(null);
  const remoteVideoElMap = useRef<Record<string, HTMLVideoElement>>({});
  const remoteVideoContainer = useRef<HTMLDivElement>(null);

  // 消息管理模块
  const showMessage = (text: string): void => {
    setMessageList([...messageList, text]);
  };

  const listenImEvents = (): void => {
    if (!imEngine.current) return;

    imEngine.current.on('connectsuccess', () => {
      showMessage('IM连接成功');
    });

    imEngine.current.on('disconnect', (code: number) => {
      showMessage(`IM断开连接: ${code}`);
    });
  };

  const listenGroupEvents = (): void => {
    if (!imGroupManager.current) return;

    imGroupManager.current.on('memberchange', (groupId: string, memberCount: number, joinUsers: ImUser[], leaveUsers: ImUser[]) => {
      showMessage(`成员变更: 加入${joinUsers.length}人, 离开${leaveUsers.length}人`);
    });
  };

  const listenMessageEvents = (): void => {
    if (!imMessageManager.current) return;

    imMessageManager.current.on('recvgroupmessage', (msg: AliVCInteraction.ImMessage, groupId: string) => {
      showMessage(`收到消息: ${msg.data}`);
    });
  };

  // 音视频模块
  const removeRemoteVideo = (userId: string, type: 'camera' | 'screen' = 'camera') => {
    const vid = `${type}_${userId}`;
    const el = remoteVideoElMap.current[vid];
    if (el) {
      aliRtcEngine.current!.setRemoteViewConfig(null, userId, type === 'camera' ? AliRtcVideoTrack.AliRtcVideoTrackCamera : AliRtcVideoTrack.AliRtcVideoTrackScreen);
      el.pause();
      remoteVideoContainer.current?.removeChild(el);
      delete remoteVideoElMap.current[vid];
    }
  };

  const listenRtcEvents = () => {
    if (!aliRtcEngine.current) return;

    aliRtcEngine.current.on('remoteUserOnLineNotify', (userId: string) => {
      showMessage(`用户 ${userId} 加入课堂`);
    });

    aliRtcEngine.current.on('remoteUserOffLineNotify', (userId: string) => {
      showMessage(`用户 ${userId} 离开课堂`);
      removeRemoteVideo(userId, 'camera');
      removeRemoteVideo(userId, 'screen');
    });
  };

  // 统一登录逻辑
  const login = async (userId: string): Promise<void> => {
    try {
      // 初始化IM
      const { ImEngine: ImEngineClass } = window.AliVCInteraction;
      imEngine.current = ImEngineClass.createEngine();
      await imEngine.current.init({
        deviceId: 'xxxx',
        appId: IM_APP_ID,
        appSign: IM_APP_SIGN,
        logLevel: ImLogLevel.ERROR,
      });
      
      // 初始化RTC
      aliRtcEngine.current = AliRtcEngine.getInstance();
      AliRtcEngine.setLogLevel(0);
      
      // 设置事件监听
      listenImEvents();
      listenRtcEvents();
      
      setIsLoggedIn(true);
      setErrorMessage('');
      showToast('success', '登录成功');
    } catch (err: any) {
      setErrorMessage(`登录失败: ${err.message}`);
      showToast('error', '登录失败');
    }
  };

  // 加入课堂
  const joinClass = async (classId: string): Promise<void> => {
    if (!imEngine.current || !aliRtcEngine.current) return;

    try {
      // 加入IM群组
      const gm = imEngine.current.getGroupManager();
      const mm = imEngine.current.getMessageManager();
      imGroupManager.current = gm || null;
      imMessageManager.current = mm || null;
      await gm!.joinGroup(classId);
      listenGroupEvents();
      listenMessageEvents();

      // 加入RTC频道
      const timestamp = Math.floor(Date.now() / 1000) + 3600 * 3;
      const token = await generateToken(RTC_APP_ID, RTC_APP_KEY, classId, userId, timestamp);
      aliRtcEngine.current.setChannelProfile(AliRtcSdkChannelProfile.AliRtcSdkCommunication);
      await aliRtcEngine.current.joinChannel(
        {
          channelId: classId,
          userId,
          appId: RTC_APP_ID,
          token,
          timestamp,
        },
        userId
      );

      // 设置本地预览
      aliRtcEngine.current.setLocalViewConfig('localPreviewer', AliRtcVideoTrack.AliRtcVideoTrackCamera);
      
      setIsJoinedClass(true);
      setErrorMessage('');
      showToast('success', '加入课堂成功');
    } catch (err: any) {
      setErrorMessage(`加入课堂失败: ${err.message}`);
      showToast('error', '加入课堂失败');
    }
  };

  // 离开课堂
  const leaveClass = async (): Promise<void> => {
    if (imGroupManager.current && classId) {
      await imGroupManager.current.leaveGroup(classId);
    }
    if (aliRtcEngine.current) {
      await aliRtcEngine.current.leaveChannel();
    }
    
    setIsJoinedClass(false);
    showToast('info', '已离开课堂');
  };

  // 发送消息
  const sendMessage = async (): Promise<void> => {
    if (!imMessageManager.current || !classId) return;

    try {
      await imMessageManager.current.sendGroupMessage({
        groupId: classId,
        data: msgText,
        type: 88888,
        level: ImMessageLevel.NORMAL,
      });
      setMsgText('');
      setErrorMessage('');
    } catch (err: any) {
      setErrorMessage(`消息发送失败: ${err.message}`);
    }
  };

  // 清理资源
  useEffect(() => {
    return () => {
      if (imGroupManager.current) {
        imGroupManager.current.removeAllListeners();
      }
      if (imMessageManager.current) {
        imMessageManager.current.removeAllListeners();
      }
      if (imEngine.current) {
        imEngine.current.removeAllListeners();
      }
      if (aliRtcEngine.current) {
        aliRtcEngine.current.destroy();
      }
    };
  }, []);

  return (
    <ClassroomContext.Provider value={{
      userId,
      role,
      isLoggedIn,
      isJoinedClass,
      messageList,
      errorMessage,
      setRole,
    }}>
      <div className="container mx-auto p-4">
        <h1 className="text-2xl font-bold mb-4">互动课堂</h1>
        
        <ToastContainer
          position="top-right"
          autoClose={5000}
          hideProgressBar={false}
          newestOnTop={false}
          closeOnClick
          rtl={false}
          pauseOnFocusLoss
          draggable
          pauseOnHover
        />

        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <div className="md:col-span-1">
            <form>
              <div className="mb-2">
                <label className="block text-sm font-medium text-gray-700">用户ID</label>
                <input
                  className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm"
                  value={userId}
                  onChange={(e) => setUserId(e.target.value)}
                />
              </div>
              
              <div className="mb-2">
                <label className="block text-sm font-medium text-gray-700">课堂ID</label>
                <input
                  className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm"
                  value={classId}
                  onChange={(e) => setClassId(e.target.value)}
                />
              </div>
              
              <div className="mb-2">
                <label className="block text-sm font-medium text-gray-700">角色</label>
                <select
                  className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm"
                  value={role}
                  onChange={(e) => setRole(e.target.value as 'teacher' | 'student')}
                >
                  <option value="student">学生</option>
                  <option value="teacher">老师</option>
                </select>
              </div>
              
              <div className="flex space-x-2 mb-2">
                <button
                  type="button"
                  className="px-3 py-2 bg-blue-600 text-white rounded-md"
                  disabled={isLoggedIn}
                  onClick={() => login(userId)}
                >
                  登录
                </button>
                
                <button
                  type="button"
                  className="px-3 py-2 bg-blue-600 text-white rounded-md"
                  disabled={!isLoggedIn || isJoinedClass}
                  onClick={() => joinClass(classId)}
                >
                  加入课堂
                </button>
                
                <button
                  type="button"
                  className="px-3 py-2 bg-gray-600 text-white rounded-md"
                  disabled={!isJoinedClass}
                  onClick={leaveClass}
                >
                  离开课堂
                </button>
              </div>
            </form>
            
            <div className="mt-4">
              <label className="block text-sm font-medium text-gray-700">消息</label>
              <input
                className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm"
                value={msgText}
                onChange={(e) => setMsgText(e.target.value)}
              />
              <button
                type="button"
                className="mt-2 px-3 py-2 bg-blue-600 text-white rounded-md"
                disabled={!isJoinedClass}
                onClick={sendMessage}
              >
                发送
              </button>
            </div>
          </div>
          
          <div className="md:col-span-1">
            <h4 className="text-lg font-medium mb-2">消息记录</h4>
            <div className="bg-gray-100 p-2 rounded-md h-64 overflow-y-auto">
              {messageList.map((msg, i) => (
                <div key={i} className="mb-1">{msg}</div>
              ))}
            </div>
          </div>
          
          <div className="md:col-span-1">
            <h4 className="text-lg font-medium mb-2">视频区域</h4>
            <video
              id="localPreviewer"
              muted
              className="w-full h-48 bg-black mb-2"
            ></video>
            <div
              id="remoteVideoContainer"
              ref={remoteVideoContainer}
              className="grid grid-cols-2 gap-2"
            ></div>
          </div>
        </div>
        
        {errorMessage && (
          <div className="mt-2 text-red-500">{errorMessage}</div>
        )}
      </div>
    </ClassroomContext.Provider>
  );
};