import React, { useState, useEffect } from 'react';
// import 'https://g.alicdn.com/apsara-media-box/imp-interaction/1.6.1/alivc-im.iife.js'

// 从 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;
}

interface ImGroupMemberChangeEvent {
  groupId: string;
  memberCount: number;
  joinUsers: ImUser[];
  leaveUsers: ImUser[];
}

interface ImGroupMuteChangeEvent {
  groupId: string;
  status: AliVCInteraction.ImGroupMuteStatus;
}

interface ImGroupInfoChangeEvent {
  groupId: string;
  info: AliVCInteraction.ImGroupInfoStatus;
}

interface ImError {
  code: number;
  msg: string;
  message?: string;
}

const { ImEngine: ImEngineClass, ImLogLevel, ImMessageLevel } = window.AliVCInteraction;

// 请从控制台复制对应的值填入下面 AppId、 AppKey、AppSign 变量当中
// 注意：这里仅作为本地快速体验使用，实际开发请勿在前端泄露 AppKey
const AppId = '4c2ab5e1b1b0';
const AppKey = '314bb5eee5b623549e8a41574ba3ff32';
const AppSign = 'H4sIAAAAAAAE/wCQAG//zguHB+lYCilkv7diSkk4GmcvLuds+InRu9vFOFebMwm/jEgsK5bBT85Z0owObMxG58uXHyPFlPEBEDQm9FswNJ+KmX0VDYkcfdPPWkafA6Hc0B6F+p5De9yJfPEfHzwo/DHMaygbHfLmBgUtmKveq421sJr/gNBz9D04Ewsg39us+ao0NegzLt7xtXvFXXXJAAAA//8BAAD//yoav6aQAAAA';

export const LivePage = () => {
    const [userId, setUserId] = useState<string>('');
    const [groupId, setGroupId] = useState<string>('');
    const [isLoggedIn, setIsLoggedIn] = useState<boolean>(false);
    const [isJoinedGroup, setIsJoinedGroup] = useState<boolean>(false);
    const [msgText, setMsgText] = useState<string>('');
    const [messageList, setMessageList] = useState<string[]>([]);
    const [errorMessage, setErrorMessage] = useState<string>('');

    const engine: ImEngine = ImEngineClass.createEngine();
    const [groupManager, setGroupManager] = useState<ImGroupManager | null>(null);
    const [messageManager, setMessageManager] = useState<ImMessageManager | null>(null);
    const [joinedGroupId, setJoinedGroupId] = useState<string | null>(null);

    const sha256 = async (message: string): Promise<string> => {
        const encoder = new TextEncoder();
        const data = encoder.encode(message);
        const result = await crypto.subtle.digest('SHA-256', data).then((buffer) => {
            let hash = Array.prototype.map.call(new Uint8Array(buffer), (x) => ('00' + x.toString(16)).slice(-2)).join('');
            return hash;
        });
        return result;
    };

    const getLoginAuth = async (userId: string, role: string): Promise<AliVCInteraction.ImAuth> => {
        const nonce = 'AK_4';
        const timestamp = Math.floor(Date.now() / 1000) + 3600 * 3;
        const pendingShaStr = `${AppId}${AppKey}${userId}${nonce}${timestamp}${role}`;
        const appToken = await sha256(pendingShaStr);
        return {
            nonce,
            timestamp,
            token: appToken,
            role,
        };
    };

    const showMessage = (text: string): void => {
        setMessageList([...messageList, text]);
    };

    const listenEngineEvents = (): void => {
        engine.on('connecting', () => {
            console.log('connecting');
        });
        engine.on('connectfailed', (err) => {
            console.log(`connect failed: ${err.message}`);
        });
        engine.on('connectsuccess', () => {
            console.log('connect success');
        });
        engine.on('disconnect', (code: number) => {
            console.log(`disconnect: ${code}`);
        });
        engine.on('tokenexpired', async (cb: (error: null, auth: AliVCInteraction.ImAuth) => void) => {
            console.log('token expired');
            // 这里需要更新为获取新的登录信息的代码
            // const auth = await getLoginAuth(userId, role);
            // cb(null, auth);
        });
    };

    const listenGroupEvents = (): void => {
        if (!groupManager) {
            return;
        }
        groupManager.on('exit', (groupId: string, reason: number) => {
            showMessage(`group ${groupId} close, reason: ${reason}`);
        });
        groupManager.on('memberchange', (groupId: string, memberCount: number, joinUsers: ImUser[], leaveUsers: ImUser[]) => {
            showMessage(`group ${groupId} member change, memberCount: ${memberCount}, joinUsers: ${joinUsers.map(u => u.userId).join(',')}, leaveUsers: ${leaveUsers.map(u => u.userId).join('')}`);
        });
        groupManager.on('mutechange', (groupId: string, status: AliVCInteraction.ImGroupMuteStatus) => {
            showMessage(`group ${groupId} mute change`);
        });
        groupManager.on('infochange', (groupId: string, info: AliVCInteraction.ImGroupInfoStatus) => {
            showMessage(`group ${groupId} info change`);
        });
    };

    const listenMessageEvents = (): void => {
        if (!messageManager) {
            return;
        }
        messageManager.on('recvgroupmessage', (msg: AliVCInteraction.ImMessage, groupId: string) => {
            console.log('recvgroupmessage', msg, groupId);
            showMessage(`receive group: ${groupId}, type: ${msg.type}, data: ${msg.data}`);
        });
    };

    const login = async (userId: string): Promise<void> => {
        try {
            await engine.init({
                deviceId: 'xxxx',
                appId: AppId,
                appSign: AppSign,
                logLevel: ImLogLevel.ERROR,
            });
            listenEngineEvents();
            const role = 'admin';
            const authData = await getLoginAuth(userId, role);
            await engine.login({
                user: {
                    userId,
                    userExtension: '{}',
                },
                userAuth: {
                    timestamp: authData.timestamp,
                    nonce: authData.nonce,
                    role: authData.role,
                    token: authData.token,
                },
            });
            const gm = engine.getGroupManager();
            const mm = engine.getMessageManager();
            setGroupManager(gm || null);
            setMessageManager(mm || null);
            setIsLoggedIn(true);
            setErrorMessage('');
        } catch (err: any) {
            setErrorMessage(`初始化、登录失败: ${err.code} ${err.msg}`);
        }
    };

    const logout = async (): Promise<void> => {
        try {
            await engine.logout();
            engine.unInit();
            setGroupManager(null);
            setMessageManager(null);
            setJoinedGroupId(null);
            setIsLoggedIn(false);
            setIsJoinedGroup(false);
            setErrorMessage('');
        } catch (err: any) {
            setErrorMessage(`登出失败: ${err.code} ${err.msg}`);
        }
    };

    const joinGroup = async (groupId: string): Promise<void> => {
        try {
            if (!groupManager) {
                return;
            }
            await groupManager.joinGroup(groupId);
            setJoinedGroupId(groupId);
            listenGroupEvents();
            listenMessageEvents();
            setIsJoinedGroup(true);
            setErrorMessage('');
        } catch (err: any) {
            setErrorMessage(`加入群组失败: ${err.code} ${err.msg}`);
        }
    };

    const leaveGroup = async (): Promise<void> => {
        try {
            if (!groupManager || !joinedGroupId) {
                return;
            }
            await groupManager.leaveGroup(joinedGroupId);
            groupManager.removeAllListeners();
            messageManager?.removeAllListeners();
            setJoinedGroupId(null);
            setIsJoinedGroup(false);
            setErrorMessage('');
        } catch (err: any) {
            setErrorMessage(`离开群组失败: ${err.code} ${err.msg}`);
        }
    };

    const createGroup = async (): Promise<void> => {
        try {
            if (!groupManager) {
                return;
            }
            const res = await groupManager.createGroup({
                groupId,
                groupName: 'xxx',
                groupMeta: 'xxx',
            });
            console.log('创建群组成功', res);
            setErrorMessage('');
        } catch (err: any) {
            setErrorMessage(`创建群组失败: ${err.code} ${err.msg}`);
        }
    };

    const sendMessage = async (): Promise<void> => {
        try {
            if (!messageManager || !joinedGroupId) {
                return;
            }
            const res = await messageManager.sendGroupMessage({
                groupId: joinedGroupId,
                data: msgText,
                type: 88888,
                skipAudit: false,
                skipMuteCheck: false,
                level: ImMessageLevel.NORMAL,
                noStorage: true,
                repeatCount: 1,
            });
            console.log('群消息发送成功', res);
            setMsgText('');
            setErrorMessage('');
        } catch (err: any) {
            setErrorMessage(`群消息发送失败: ${err.code} ${err.msg}`);
        }
    };

    const clearMessages = (): void => {
        setMessageList([]);
    };

    useEffect(() => {
        return () => {
            if (groupManager) {
                groupManager.removeAllListeners();
            }
            if (messageManager) {
                messageManager.removeAllListeners();
            }
            if (engine) {
                engine.removeAllListeners();
            }
        };
    }, []);

    return (
        <div className="container mx-auto p-4">
            <h1 className="text-2xl font-bold mb-4">互动消息 quick start</h1>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div>
                    <form>
                        <div className="mb-2">
                            <label htmlFor="userId" 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 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
                                id="userId"
                                placeholder="请输入英文字母或数字"
                                value={userId}
                                onChange={(e) => setUserId(e.target.value)}
                            />
                        </div>
                        <div className="mb-2">
                            <label htmlFor="groupId" 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 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
                                id="groupId"
                                placeholder="加入群组前请确认是否已存在，不存在先创建"
                                value={groupId}
                                onChange={(e) => setGroupId(e.target.value)}
                            />
                        </div>
                        <div className="mb-2 flex space-x-2">
                            <button
                                id="loginBtn"
                                type="button"
                                className={`px-3 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 ${isLoggedIn? 'opacity-50 cursor-not-allowed' : ''}`}
                                disabled={isLoggedIn}
                                onClick={() => login(userId)}
                            >
                                登录
                            </button>
                            <button
                                id="joinBtn"
                                type="button"
                                className={`px-3 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 ${isLoggedIn && isJoinedGroup? 'opacity-50 cursor-not-allowed' : ''}`}
                                disabled={isLoggedIn && isJoinedGroup}
                                onClick={() => joinGroup(groupId)}
                            >
                                加入群组
                            </button>
                            <button
                                id="createBtn"
                                type="button"
                                className={`px-3 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 ${!isLoggedIn? 'opacity-50 cursor-not-allowed' : ''}`}
                                disabled={!isLoggedIn}
                                onClick={() => createGroup()}
                            >
                                创建群组
                            </button>
                            <button
                                id="leaveBtn"
                                type="button"
                                className={`px-3 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-600 hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 ${!isLoggedIn ||!isJoinedGroup? 'opacity-50 cursor-not-allowed' : ''}`}
                                disabled={!isLoggedIn ||!isJoinedGroup}
                                onClick={() => leaveGroup()}
                            >
                                离开群组
                            </button>
                            <button
                                id="logoutBtn"
                                type="button"
                                className={`px-3 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-600 hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 ${!isLoggedIn? 'opacity-50 cursor-not-allowed' : ''}`}
                                disabled={!isLoggedIn}
                                onClick={() => logout()}
                            >
                                登出
                            </button>
                        </div>
                        <p className="mb-2 text-sm text-gray-600">假如群组ID已存在，可以一键登录+加入群组</p>
                        <div className="mb-2 flex space-x-2">
                            <button
                                id="oneLoginBtn"
                                type="button"
                                className={`px-3 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 ${isLoggedIn && isJoinedGroup? 'opacity-50 cursor-not-allowed' : ''}`}
                                disabled={isLoggedIn && isJoinedGroup}
                                onClick={() => {
                                    if (userId && groupId) {
                                        login(userId).then(() => {
                                            joinGroup(groupId);
                                        });
                                    }
                                }}
                            >
                                一键登录+加入群组
                            </button>
                            <button
                                id="oneLogoutBtn"
                                type="button"
                                className={`px-3 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-600 hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 ${!isLoggedIn ||!isJoinedGroup? 'opacity-50 cursor-not-allowed' : ''}`}
                                disabled={!isLoggedIn ||!isJoinedGroup}
                                onClick={() => {
                                    leaveGroup().then(() => {
                                        logout();
                                    });
                                }}
                            >
                                一键离开群组+登出
                            </button>
                        </div>
                    </form>
                    <form className="mt-4">
                        <div className="mb-2">
                            <label htmlFor="msgText" 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 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
                                id="msgText"
                                value={msgText}
                                onChange={(e) => setMsgText(e.target.value)}
                            />
                        </div>
                        <div className="mb-2">
                            <button
                                id="sendBtn"
                                type="button"
                                className={`px-3 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 ${!isLoggedIn ||!isJoinedGroup? 'opacity-50 cursor-not-allowed' : ''}`}
                                disabled={!isLoggedIn ||!isJoinedGroup}
                                onClick={() => sendMessage()}
                            >
                                发送
                            </button>
                        </div>
                    </form>
                </div>
                <div>
                    <h5 className="flex justify-between items-center text-lg font-medium mb-2">
                        消息展示
                        <button
                            id="clearBtn"
                            type="button"
                            className="px-3 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-600 hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500"
                            onClick={clearMessages}
                        >
                            清空
                        </button>
                    </h5>
                    <div id="msgList" className="mt-4 space-y-2">
                        {messageList.map((msg, index) => (
                            <div key={index} className="bg-gray-100 p-2 rounded-md">{msg}</div>
                        ))}
                    </div>
                </div>
            </div>
            {errorMessage && <div className="mt-2 text-red-500">{errorMessage}</div>}
        </div>
    );
};