"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.load = void 0;
const component_1 = require("@loadable/component");
const exenv_1 = require("exenv");
const react_1 = __importStar(require("react"));
const react_dom_1 = require("react-dom");
const container_1 = require("./container");
const Runtime_1 = require("./context/Runtime");
const data_1 = require("./data");
const once_1 = require("./once");
const runtime_1 = require("./runtime");
const printPerformance = () => {
    var _a;
    const timing = (_a = window.performance) === null || _a === void 0 ? void 0 : _a.timing;
    if (!timing) {
        return;
    }
    const domContentLoaded = timing.domContentLoadedEventEnd - timing.navigationStart;
    const loaded = timing.loadEventEnd - timing.navigationStart;
    console.log(`[micro-react]: ⚡⚡ DomContentLoaded ${domContentLoaded / 1e3}ms`);
    console.log(`[micro-react]: ⚡⚡ Load ${loaded / 1e3}ms`);
};
const renderOrHydrate = (App) => async () => {
    const container = container_1.getAppContainer();
    const runtimeData = runtime_1.getRuntimeData();
    // This should be preloaded by now
    let error = null;
    const data = await data_1.getPageData().catch((err) => {
        error = err;
    });
    const AppWithContext = (<react_1.StrictMode>
      <Runtime_1.Runtime.Provider value={runtimeData}>
        <App name={runtimeData.page.name} data={data} error={error}/>
      </Runtime_1.Runtime.Provider>
    </react_1.StrictMode>);
    if (container.children.length > 0) {
        const msg = '[micro-react]: ⚡⚡ Hydration took';
        console.time(msg);
        console.log('hydrationStart', (Date.now() - window.performance.timing.navigationStart) / 1e3);
        react_dom_1.hydrate(AppWithContext, container);
        console.timeEnd(msg);
    }
    else {
        const msg = '[micro-react]: ⚡ Rendering took';
        console.time(msg);
        console.log('renderStart', (Date.now() - window.performance.timing.navigationStart) / 1e3);
        react_dom_1.render(AppWithContext, container);
        console.timeEnd(msg);
    }
    printPerformance();
};
exports.load = (App) => {
    if (exenv_1.canUseDOM) {
        const renderOnce = once_1.once(renderOrHydrate(App));
        setTimeout(renderOnce, 6e3);
        if (document.readyState !== 'complete') {
            window.onload = () => component_1.loadableReady(renderOnce);
        }
        else {
            component_1.loadableReady(renderOnce);
        }
    }
    return App;
};
