import { useEffect, useRef, useState } from "react";
import '@/utils/styles/App.scss'
import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom';
import Home from '@/page/Home/index'
import Index from '@/page/Home/Index/index'
import User from '@/page/Home/User/index'
import Login from '@/page/Login/index'
import Meeting from '@/page/Meeting/index'
import NotFound from '@/page/NotFound/index'
import { storage } from '@/utils'
import { message, Spin } from "antd";
import JoinMeetingModal from "@/components/JoinMeetingModal";
import UpdateModal from "@/components/UpdateModal";
import * as CryptoJS from 'crypto-js';
import { PostLogin } from "@/api/Login";
import { agora } from "@/utils/package/agora";
import QuitTips from "@/components/QuitTips";
import { GetLeave } from "@/api/Meeting";
import ShareScreenWindow from "@/page/Meeting/ShareScreenWindow";
import UserListWindow from "@/page/Meeting/UserListWindow";
import ChatSmallWindow from "@/page/Meeting/ChatSmallWindow";
import ChatBigWindow from "@/page/Meeting/ChatBigWindow";
import NoticeWindow from "@/page/Meeting/NoticeWindow";
import { getKeyOpenChildWindow, getTitle, setKeyOpenChildWindow, storageSeeting } from "./utils/package/public";
const fs = require('fs').promises;
const { exec } = require('child_process');
const App: React.FC = () => {
    const navigate = useNavigate();
    const { state } = useLocation();
    const joinMeetingModalRef = useRef<any>();
    const updateModalRef = useRef<any>();
    const quitTipsRef = useRef<any>();
    const [_windowSize, setWindowSize] = useState({
        width: window.innerWidth,
        height: window.innerHeight,
    });
    const [spinning, setSpinning] = useState(false);
    const [isState, setIsState] = useState(true);
    const urlHashArr = ['#/userListWindow', '#/shareScreenWindow', '#/chatSmallWindow', '#/chatBigWindow', '#/noticeWindow']
    if (urlHashArr.indexOf(location.hash) == -1) {
        useEffect(() => {
            let userInfo = JSON.parse(storage.getItem('user') as string)
            let loginInfo = JSON.parse(storage.getItem('login') as string)
            window.electron.setEnv(import.meta.env.VITE_ENV);
            if (userInfo && !userInfo.isAnonymous) {
                if (loginInfo && loginInfo.isAutoLogin) {
                    PostLogin({
                        account: loginInfo.account,
                        pwd: CryptoJS.MD5(loginInfo.password).toString(CryptoJS.enc.Hex)
                    }).then(async (res) => {
                        if (res.code === 200) {
                            storage.setItem('user', JSON.stringify(res.data))
                            storage.setItem('userLogin', true)
                            toSrc('/home')
                            await window.electron.startSignalr(res.data)
                        } else {
                            toSrc('/login')
                        }
                    })
                } else {
                    toSrc('/login')
                }
            } else {
                toSrc('/login')
            }
            window.addEventListener('resize', handleResize);
            const originalSetItem = window.localStorage.setItem;
            window.localStorage.setItem = function (key, value) {
                originalSetItem.call(this, key, value);
                const event = new Event('customStorageChange') as any;
                event.key = key
                event.value = value
                window.dispatchEvent(event);
            };
            window.addEventListener('customStorageChange', handleCustomStorageChange);
            return () => {
                window.removeEventListener('resize', handleResize);
                window.removeEventListener('customStorageChange', handleCustomStorageChange);
            };
        }, []);
        useEffect(() => {
            window.electron.downFile(async (_e: any, data: any) => {
                const response = await fetch(data.filePath);
                const arrayBuffer = await response.arrayBuffer();
                const buffer = Buffer.from(arrayBuffer);
                fs.writeFile(`${data.downFilePaths}${data.fileName}`, buffer, {});
                message.success(`下载成功！文件已保存至:${data.downFilePaths}`)
                await fs.access(data.downFilePaths, fs.constants.F_OK);
                if (process.platform === 'win32') {
                    exec(`explorer "${data.downFilePaths}"`);
                } else if (process.platform === 'darwin') {
                    exec(`open "${data.downFilePaths}"`);
                }
            })
            window.electron.onFilePath(async (_e: any, filePath: string, key: string) => {
                const setting = await JSON.parse(storage.getItem('setting') as string)
                if (key === 'recordingFilesPath') {
                    setting.recordingFilesPath = filePath
                } else {
                    setting.shareFilesPath = filePath
                }
                storage.setItem('setting', JSON.stringify(setting))
            })
            window.electron.quitAndInstall(async (_e: any) => {
                let bool = await window.electron.isVisible()
                if (bool) {
                    storage.setItem('quitMeeting', true)
                    window.electron.setViewStatus('show')
                }
            })
            window.electron.isOpenWindows(async (_e: any) => {
                let bool = await window.electron.isVisible()
                if (location.hash.indexOf('/meeting') === -1) {
                    window.electron.setViewStatus(bool ? 'hide' : 'show')
                } else {
                    let shareScreenWindow = await getKeyOpenChildWindow('shareScreenWindow')
                    if (!shareScreenWindow) {
                        window.electron.setViewStatus(bool ? 'hide' : 'show')
                    }
                }
            })
            window.electron.changeLocalStorage(async (_e: any, data: any) => {
                for (const key in data) {
                    storage.setItem(key, data[key])
                }
            })
        }, [])
        useEffect(() => {
            window.electron.onUpdate((_e: any, data: any) => {
                if (location.hash.indexOf('/meeting') === -1) {
                    updateModalRef.current.changeModal(data)
                }
            })
            if (!storage.getItem('setting')) {
                storage.setItem('setting', JSON.stringify(storageSeeting))
            }
            if (!storage.getItem('openChildWindow')) {
                storage.setItem('openChildWindow', JSON.stringify({}))
            }
        }, [])
        useEffect(() => {
            if (isState) {
                setIsState(false)
                window.electron.onQuit(async () => {
                    if (location.hash.indexOf('/login') === 1) {
                        window.electron.quit(location.hash.indexOf('/meeting') === -1)
                    } else {
                        if (storage.getItem('isTips') === 'true') {
                            const setting = JSON.parse(storage.getItem('setting') as string)
                            if (setting.closeSetting === 'hide') {
                                window.electron.setViewStatus(setting.closeSetting)
                            } else {
                                window.electron.quit(location.hash.indexOf('/meeting') === -1)
                            }
                        } else {
                            quitTipsRef.current.changeModal()
                        }
                    }
                })
            }
            storage.setItem('stateInfo', JSON.stringify(state))
        }, [state])
        useEffect(() => {
            if (location.href.indexOf('/login') !== -1) {
                window.electron.onStop()
            }
            message.destroy('cameraTemporarily')
        }, [navigate])
    }
    useEffect(() => {
        document.addEventListener('keydown', (event) => {
            if (event.key === 'F11') {
                event.preventDefault();
            }
        });
        document.getElementsByTagName('title')[0].innerText = getTitle(import.meta.env.VITE_ENV)
    }, [])
    const handleResize = (): void => {
        setWindowSize({
            width: window.innerWidth,
            height: window.innerHeight,
        });
        window.electron.getIsMaximized().then((res: boolean) => {
            const dom = document.getElementById('root') as HTMLElement;
            dom.style.borderRadius = res ? '0px' : '10px'
        })
    };

    const onEventSignalr = (): void => {
        window.electron.onOtherSignalr(async (_e: any, item: any) => {
            switch (item.key) {
                case 'Invitation':
                    window.electron.joinNotification({
                        body: item.roomName,
                        name: item.InviterName,
                    })
                    joinMeetingModalRef.current.changeModal(item)
                    break;
                case 'ForceLogout':
                    if (item.msg) {
                        message.error(item.msg)
                    }
                    await leaveChannel(true)
                    toSrc('/login')
                    break;
            }
        })
    }
    const toSrc = (path: string): void => {
        window.electron.getWindowSize().then((res: any) => {
            switch (path) {
                case '/login':
                    storage.setItem('userLogin', false)
                    navigate('/login')
                    break;
                case '/home':
                    window.electron.setMainWindowSize({
                        width: Math.ceil(res.width / 1.5),
                        height: Math.ceil(res.height / 1.3),
                    })
                    navigate('/home')
                    break;
            }
        })
    };
    const leaveChannel = async (bool?: boolean): Promise<void> => {
        if (location.hash.indexOf('/meeting') === 1) {
            window.electron.closeChildWindow('shareScreenWindow')
            setKeyOpenChildWindow('shareScreenWindow', false)
            window.electron.setViewStatus('show')
            window.electron.getWindowSize().then((res: any) => {
                window.electron.setMainWindowSize({
                    width: Math.ceil(res.width / 1.5),
                    height: Math.ceil(res.height / 1.3),
                })
                window.electron.getIsMaximized().then((b: boolean) => {
                    if (!b) {
                        window.electron.setViewStatus('maximize')
                    }
                })
            })
            const data = JSON.parse(localStorage.stateInfo);
            if (!bool) {
                await GetLeave({
                    roomNum: data.channelId,
                })
            }
            await agora.leaveChannel()
        }
    };
    const handleCustomStorageChange = (e: any): void => {
        if (e.key === 'loading') {
            setSpinning(Boolean(e.value))
        } else if (e.key === 'isSignalr') {
            if (Boolean(e.value)) {
                onEventSignalr()
            }
        } else if (e.key === 'userLogin') {
            if (!Boolean(e.value)) {
                storage.removeItem('user')
                navigate('/login')
            }
        }
    };
    return (
        <>
            <Routes>
                <Route path='/' element={<Home />} />
                <Route path='/home' element={<Home />}>
                    <Route path='/home' element={<Navigate to='/home/index' />} />
                    <Route path='/home/index' element={<Index />} />
                    <Route path='/home/user' element={<User />} />
                </Route>
                <Route path='/login' element={<Login />} />
                <Route path='/meeting' element={<Meeting />} />
                <Route path='/shareScreenWindow' element={<ShareScreenWindow />} />
                <Route path='/userListWindow' element={<UserListWindow />} />
                <Route path='/chatSmallWindow' element={<ChatSmallWindow />} />
                <Route path='/chatBigWindow' element={<ChatBigWindow />} />
                <Route path='/noticeWindow' element={<NoticeWindow />} />
                <Route path='*' element={<NotFound />} />
            </Routes>
            <Spin spinning={spinning} fullscreen />
            <JoinMeetingModal ref={joinMeetingModalRef} />
            <UpdateModal ref={updateModalRef} />
            <QuitTips ref={quitTipsRef} />
        </>
    )
}

export default App
