import { Alert, Box, Button, Divider, Flex, Overlay } from "@mantine/core";
import { useEffect, useState } from "react";
import { Route, Routes, useLocation, useNavigate } from "react-router-dom";
import { Profile } from "@/app/views/Profile/Profile";
import { useRosettaColors } from "@/app/hooks/useRosettaColors";
import { DialogPreview } from "@/app/views/DialogPreview/DialogPreview";
import { Theme } from "../Theme/Theme";
import { Safety } from "../Safety/Safety";
import { Backup } from "../Backup/Backup";
import { Chat } from "../Chat/Chat";
import { PrivateView } from "@/app/components/PrivateView/PrivateView";
import { useDialogFiber } from "@/app/providers/DialogProvider/useDialogFiber";
import { Update } from "../Update/Update";
import { useRosettaBreakpoints } from "@/app/hooks/useRosettaBreakpoints";
import { Dialogs } from "../Dialogs/Dialogs";
import { DialogsPanel } from "@/app/components/DialogsPanel/DialogsPanel";
import { useViewPanelsState, ViewPanelsState } from "@/app/hooks/useViewPanelsState";
import { TransportProvider } from "@/app/providers/TransportProvider/TransportProvider";
import { useDebouncedCallback } from "@mantine/hooks";
import { SystemAccountProvider } from "@/app/providers/SystemAccountsProvider/SystemAccountsProvider";
import { CreateGroup } from "../CreateGroup/CreateGroup";
import { GroupInfo } from "../GroupInfo/GroupInfo";
import { GroupEncryption } from "../GroupEncryption/GroupEncryption";
import useWindow from "@/app/hooks/useWindow";
import { usePublicKey } from "@/app/providers/AccountProvider/usePublicKey";
import { useDatabase } from "@/app/providers/DatabaseProvider/useDatabase";
import { useMemoryClean } from "@/app/providers/MemoryProvider/useMemoryClean";
import { useAccountProvider } from "@/app/providers/AccountProvider/useAccountProvider";
import { useLogout } from "@/app/providers/AccountProvider/useLogout";
import { useUpdateMessage } from "@/app/hooks/useUpdateMessage";
import { useDeviceMessage } from "@/app/hooks/useDeviceMessage";
import { UpdateProvider } from "@/app/providers/UpdateProvider/UpdateProvider";
import { useSynchronize } from "@/app/providers/DialogProvider/useSynchronize";
import { CallProvider } from "@/app/providers/CallProvider/CallProvider";

export function Main() {
    const { mainColor, borderColor } = useRosettaColors();
    const { lg } = useRosettaBreakpoints();
    const location = useLocation();
    const [viewState, setViewState] = useViewPanelsState();

    /**
     * Слушаем диалоги в пассивном режиме
     */
    useDialogFiber();

    /**
     * Отправляем сообщение об обновлении,
     * если версия приложения изменилась
     */
    useUpdateMessage();

    /**
     * Слушаем все сообщения на присоединение новых устройств 
     * к нашему аккаунту
     */
    useDeviceMessage();

    /**
     * Синхронизируем сообщения при подключении
     */
    useSynchronize();

    const { setSize, setResizeble } = useWindow();

    /**
     * Operation: OLD PUBLIC KEY MIGRATION
     */
    const publicKey = usePublicKey();
    const [oldPublicKey, setOldPublicKey] = useState(false);
    const { runQuery } = useDatabase();
    const navigate = useNavigate();
    const memClean = useMemoryClean();
    const { setAccounts } = useAccountProvider();
    const logout = useLogout();

    useEffect(() => {
        if (publicKey.length > 80) {
            /**
             * Old public keys
             */
            setOldPublicKey(true);
        }
    }, [publicKey]);

    const dropAccountsAndMessages = async () => {
        localStorage.clear();
        await runQuery("DELETE FROM accounts");
        await runQuery("DELETE FROM messages");
        await runQuery("DELETE FROM dialogs");
        memClean();
        setAccounts([]);
        logout();
        setTimeout(() => {
            navigate("/");
        }, 500);
    }

    useEffect(() => {
        let { width, height } = getWindowSavedSize();
        setSize(width, height);
        setResizeble(true);

        const sizeListener = () => {
            saveSize(window.innerWidth, window.innerHeight);
        };
        window.addEventListener("resize", sizeListener);

        return () => {
            window.removeEventListener("resize", sizeListener);
        }
    }, []);


    useEffect(() => {
        if (lg && viewState == ViewPanelsState.DIALOGS_PANEL_ONLY) {
            setViewState(ViewPanelsState.DIALOGS_PANEL_SHOW);
            return;
        }
        if (!lg && location.pathname != '/main') {
            setViewState(ViewPanelsState.DIALOGS_PANEL_HIDE);
            return;
        }
        if (!lg && location.pathname == '/main' && window.innerWidth < 770) {
            setViewState(ViewPanelsState.DIALOGS_PANEL_ONLY);
            return;
        }
        if (!lg) {
            setViewState(ViewPanelsState.DIALOGS_PANEL_HIDE);
            return;
        }
        if (lg) {
            setViewState(ViewPanelsState.DIALOGS_PANEL_SHOW);
            return;
        }
    }, [lg, location]);

    const saveSize = useDebouncedCallback((w: number, h: number) => {
        localStorage.setItem("windowWidth", w.toString());
        localStorage.setItem("windowHeight", h.toString());
    }, 1000);

    const getWindowSavedSize = () => {
        const savedWidth = localStorage.getItem("windowWidth");
        const savedHeight = localStorage.getItem("windowHeight");
        return {
            width: savedWidth ? parseInt(savedWidth) : window.innerWidth,
            height: savedHeight ? parseInt(savedHeight) : window.innerHeight
        }
    }


    return (
        <PrivateView>
            <SystemAccountProvider>
                <TransportProvider>
                    <UpdateProvider>
                        <CallProvider>
                            <Flex direction={'row'} style={{
                                height: '100%',
                                width: '100vw',
                            }}>
                                <div style={{
                                    display: viewState != ViewPanelsState.DIALOGS_PANEL_HIDE ? 'block' : 'none',
                                    width: viewState == ViewPanelsState.DIALOGS_PANEL_ONLY ? '100%' : '300px',
                                }}>
                                    <DialogsPanel></DialogsPanel>
                                </div>
                                {lg && (
                                    <Divider color={borderColor} orientation={'vertical'}></Divider>
                                )}
                                {viewState != ViewPanelsState.DIALOGS_PANEL_ONLY && <Box
                                    bg={mainColor}
                                    style={{
                                        flexGrow: 1,
                                        height: 'calc(100vh - 27px)',
                                        width: `calc(100% - 300px)`,
                                        minWidth: 0
                                    }}
                                >
                                    <Routes>
                                        <Route path={'/chat/:id'} element={<Chat />}></Route>
                                        <Route path={'/profile/:id'} element={<Profile />}></Route>
                                        <Route path={'/'} element={<DialogPreview />}></Route>
                                        <Route path={'/theme'} element={<Theme />}></Route>
                                        <Route path={'/safety'} element={<Safety />}></Route>
                                        <Route path={'/update'} element={<Update />}></Route>
                                        <Route path={'/backup'} element={<Backup />}></Route>
                                        <Route path={'/dialogs'} element={<Dialogs />}></Route>
                                        <Route path={'/newgroup'} element={<CreateGroup />}></Route>
                                        <Route path={'/group/:id'} element={<GroupInfo />}></Route>
                                        <Route path={'/groupencrypt/:key'} element={<GroupEncryption />}></Route>
                                    </Routes>
                                </Box>}
                            </Flex>
                            {oldPublicKey && (
                                <Overlay blur={8} color="#333">
                                    <Flex direction={'column'} align={'center'} justify={'center'} h={'100%'}>
                                        <Alert w={400} variant="filled" color="red" title="Old account">
                                            Your account uses an old format public key which is no longer supported. Please create a new account to continue using the application.
                                            <br></br>After press "OK" button, the application will close and remove all data.
                                        </Alert>
                                        <Button w={400} mt={'md'} color="red" onClick={dropAccountsAndMessages}>OK</Button>
                                    </Flex>
                                </Overlay>
                            )}
                        </CallProvider>
                    </UpdateProvider>
                </TransportProvider>
            </SystemAccountProvider>
        </PrivateView>);
}