// if ((module as any).hot) {
//     (module as any).hot.accept();
// }

import * as dotenv from 'dotenv'; // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import
import { Node } from 'prosemirror-model';
import { EditorView } from 'prosemirror-view';
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import { AssignAllExtensions } from '../../extensions/Extensions';
import { FieldLoader } from '../../fields/FieldLoader';
import { BranchingTrailManager } from '../util/BranchingTrailManager';
import { CurrentUserUtils } from '../util/CurrentUserUtils';
import { LinkFollower } from '../util/LinkFollower';
import { PingManager } from '../util/PingManager';
import { ReplayMovements } from '../util/ReplayMovements';
import { TrackMovements } from '../util/TrackMovements';
import { KeyManager } from './GlobalKeyHandler';
import { InkingStroke } from './InkingStroke';
import { MainView } from './MainView';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { CollectionView } from './collections/CollectionView';
import { TabDocView } from './collections/TabDocView';
import { CollectionFreeFormView } from './collections/collectionFreeForm';
import { CollectionFreeFormInfoUI } from './collections/collectionFreeForm/CollectionFreeFormInfoUI';
import { FaceCollectionBox, UniqueFaceBox } from './collections/collectionFreeForm/FaceCollectionBox';
import { ImageLabelBox } from './collections/collectionFreeForm/ImageLabelBox';
import { CollectionSchemaView } from './collections/collectionSchema/CollectionSchemaView';
import { SchemaRowBox } from './collections/collectionSchema/SchemaRowBox';
import './global/globalScripts';
import { AudioBox } from './nodes/AudioBox';
import { ChatBox } from './nodes/chatbot/chatboxcomponents/ChatBox';
import { ComparisonBox } from './nodes/ComparisonBox';
import { DataVizBox } from './nodes/DataVizBox/DataVizBox';
import { DiagramBox } from './nodes/DiagramBox';
import { DocumentContentsView, HTMLtag } from './nodes/DocumentContentsView';
import { EquationBox } from './nodes/EquationBox';
import { FieldView } from './nodes/FieldView';
import { FontIconBox } from './nodes/FontIconBox/FontIconBox';
import { FunctionPlotBox } from './nodes/FunctionPlotBox';
import { ImageBox } from './nodes/ImageBox';
import { KeyValueBox } from './nodes/KeyValueBox';
import { LabelBox } from './nodes/LabelBox';
import { LinkBox } from './nodes/LinkBox';
import { LoadingBox } from './nodes/LoadingBox';
import { MapBox } from './nodes/MapBox/MapBox';
import { MapPushpinBox } from './nodes/MapBox/MapPushpinBox';
import { PDFBox } from './nodes/PDFBox';
import { PhysicsSimulationBox } from './nodes/PhysicsBox/PhysicsSimulationBox';
import { RecordingBox } from './nodes/RecordingBox';
import { ScreenshotBox } from './nodes/ScreenshotBox';
import { ScriptingBox } from './nodes/ScriptingBox';
import { VideoBox } from './nodes/VideoBox';
import { WebBox } from './nodes/WebBox';
import { CalendarBox } from './nodes/calendarBox/CalendarBox';
import { DashDocCommentView } from './nodes/formattedText/DashDocCommentView';
import { DashDocView } from './nodes/formattedText/DashDocView';
import { DashFieldView } from './nodes/formattedText/DashFieldView';
import { EquationView } from './nodes/formattedText/EquationView';
import { FootnoteView } from './nodes/formattedText/FootnoteView';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import { SummaryView } from './nodes/formattedText/SummaryView';
import { ImportElementBox } from './nodes/importBox/ImportElementBox';
import { PresBox, PresElementBox } from './nodes/trails';
import { FaceRecognitionHandler } from './search/FaceRecognitionHandler';
import { SearchBox } from './search/SearchBox';
import { StickerPalette } from './smartdraw/StickerPalette';

dotenv.config();

AssignAllExtensions();
FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' }; // bcz: not sure why this is needed to get the code loaded properly...

(async () => {
    MainView.Live = window.location.search.includes('live');
    const rootEle = document.getElementById('root');
    if (!rootEle) return;
    rootEle.style.zIndex = '0';
    const root = ReactDOM.createRoot(rootEle);
    root.render(<FieldLoader />);
    window.location.search.includes('safe') && CollectionView.SetSafeMode(true);
    const info = await CurrentUserUtils.loadCurrentUser();
    if (!info.userDocumentId) {
        alert('Fatal Error: user not found in database');
        return;
    }
    await CurrentUserUtils.loadUserDocument(info);
    setTimeout(() => {
        // prevent zooming browser
        document.getElementById('root')!.addEventListener('wheel', event => event.ctrlKey && event.preventDefault(), { capture: true, passive: true });
        const startload = (document as unknown as { startLoad: number }).startLoad; // see index.html in deploy/
        const loading = Date.now() - (startload ? Number(startload) : Date.now() - 3000);
        const d = new Date();
        d.setTime(d.getTime() + 100 * 24 * 60 * 60 * 1000);
        const expires = 'expires=' + d.toUTCString();
        document.cookie = `loadtime=${loading};${expires};path=/`;
        new TrackMovements();
        new ReplayMovements();
        new BranchingTrailManager({});
        new PingManager();
        new KeyManager();
        new FaceRecognitionHandler();

        // initialize plugins and classes that require plugins
        CollectionDockingView.Init(TabDocView);
        FormattedTextBox.Init((tbox: FormattedTextBox) => ({
            dashComment(node: Node, view: EditorView, getPos: () => number | undefined) { return new DashDocCommentView(node, view, getPos); }, // prettier-ignore
            dashDoc(node: Node, view: EditorView, getPos: () => number | undefined)     { return new DashDocView(node, view, getPos, tbox); }, // prettier-ignore
            dashField(node: Node, view: EditorView, getPos: () => number | undefined)   { return new DashFieldView(node, view, getPos, tbox); }, // prettier-ignore
            equation(node: Node, view: EditorView, getPos: () => number | undefined)    { return new EquationView(node, view, getPos, tbox); }, // prettier-ignore
            summary(node: Node, view: EditorView, getPos: () => number | undefined)     { return new SummaryView(node, view, getPos); }, // prettier-ignore
            footnote(node: Node, view: EditorView, getPos: () => number | undefined)    { return new FootnoteView(node, view, getPos); }, // prettier-ignore
        }));
        CollectionFreeFormInfoUI.Init();
        LinkFollower.Init();
        KeyValueBox.Init();
        PresBox.Init(TabDocView.AllTabDocs);
        DocumentContentsView.Init(KeyValueBox.LayoutString(), {
            StickerPalette: StickerPalette,
            FormattedTextBox,
            ImageBox,
            FontIconBox,
            LabelBox,
            EquationBox,
            FieldView,
            CollectionFreeFormView,
            CollectionDockingView,
            CollectionSchemaView,
            CollectionView,
            WebBox,
            KeyValueBox,
            PDFBox,
            VideoBox,
            AudioBox,
            RecordingBox,
            PresBox,
            PresElementBox,
            SearchBox,
            ImageLabelBox,
            FaceCollectionBox,
            UniqueFaceBox,
            FunctionPlotBox,
            InkingStroke,
            LinkBox,
            ScriptingBox,
            MapBox,
            ScreenshotBox,
            DataVizBox,
            ChatBox,
            DiagramBox,
            HTMLtag,
            CalendarBox,
            ComparisonBox,
            LoadingBox,
            PhysicsSimulationBox,
            SchemaRowBox,
            ImportElementBox,
            MapPushpinBox,
        });
        root.render(<MainView />);
    }, 0);
})();
