/* eslint-disable import/order */
/**
 * Startup file which initializes the AIOT Tree. You can access the exports
 * through <code>window.rml</code>.
 *
 * @module rml
 */
import $ from "jquery";

import applyMediaViews, { firstCreatedToolbar } from "./others/mediaViews.js";
import optionsScreen from "./others/optionsScreen.js";
import store, { StoredAppTree, TreeNode, Upload, injectAndObserve } from "./store/index.js";
import {
    IS_DARKMODE,
    addUrlParam,
    applyNodeDefaults,
    dataUriToBlob,
    fetchTree,
    findDeep,
    hooks,
    humanFileSize,
    i18n,
    isMaterialWp,
    ready,
    request,
    rmlOpts,
    secondsFormat,
    urlBuilder,
    urlParam,
} from "./util/index.js";

import "@devowl-wp/react-folder-tree/legacy/style/style.scss";
import "@devowl-wp/react-folder-tree/legacy/style/theme-wordpress.scss";
import "./style/style.scss";
import "./hooks/index.js";
import "./others/static.js";
import "./util/wpRfc.js";
import "./others/exportMediaLibrary.js";
import "./others/defaultFolder.js";
import { handleCorruptRestApi } from "@devowl-wp/utils";

import { Modal } from "./components/index.js";
import { ConfigLicensingConsumer } from "./components/licensing/index.js";

import { Provider as LicenseProvider } from "@devowl-wp/real-product-manager-wp-client";

import { createRoot } from "react-dom/client";

handleCorruptRestApi({
    [rmlOpts.restNamespace]: async () => {
        await request({
            location: {
                path: "/plugin",
                // `rmlOpts.restNamespace` uses the legacy namespace, for /plugin we need to force the new namespace
                namespace: "real-media-library/v1",
            },
        });
    },
});

// ReplaceWith should return the new object
!$.fn.replaceWithPush &&
    ($.fn.replaceWithPush = function (a) {
        const $a = $(a);
        this.replaceWith($a);
        return $a;
    });

/**
 * General event when script for RML is ready to load.
 *
 * @event module:util/hooks#general
 */
hooks.call("general");

applyMediaViews();

ready(() => {
    // Add rml-touch class if touch device
    if ("ontouchstart" in window || window.navigator.maxTouchPoints) {
        $("body").addClass("rml-touch");
    }

    "WebkitAppearance" in document.documentElement.style && $("body").addClass("rml-webkit");

    if (
        rmlOpts &&
        $("body").hasClass("wp-admin") &&
        ($("body").hasClass("upload-php") ||
            // MLA compatibility
            $("body").hasClass("media_page_mla-menu"))
    ) {
        let $container;
        let container;
        const containerId = `rml${rmlOpts.others.blogId}`;

        /**
         * General event when DOM is ready and a list table / grid mode
         * is available in media library page.
         *
         * @event module:util/hooks#ready
         */
        hooks.call("ready");

        // Avoid flickering
        $("#wpbody").fadeTo(100, 1);

        // Create the container sidebar
        $("body").addClass("activate-aiot");
        $container = $("<div/>").prependTo("body.wp-admin #wpbody").addClass("rml-container");
        container = $container.get(0);

        // Create the wrapper and React component, the modal react element is created in hooks/modal.js
        if (rmlOpts.others.listMode === "grid") {
            // When in grid mode, we have to wait for the first attachments browser
            firstCreatedToolbar.done((attachmentsBrowser) => {
                createRoot(container).render(
                    <StoredAppTree attachmentsBrowser={attachmentsBrowser} id={containerId} />,
                );
            });
        } else {
            createRoot(container).render(<StoredAppTree id={containerId} />);
        }

        // Show license dialog for the first time
        if (rmlOpts.others.showLicenseFormImmediate && !window.Playwright) {
            const modal = Modal.info({
                className: "rml-immediate-license-form",
                title: "Real Media Library",
                width: 800,
                maskClosable: false,
                content: (
                    <LicenseProvider>
                        <div>
                            <img src={`${rmlOpts.publicUrl}images/logos/real-media-library.svg`} />
                            <ConfigLicensingConsumer withinModal onClose={() => modal.destroy()} />
                        </div>
                    </LicenseProvider>
                ),
            });
        }
    }

    // Wait for modals
    if (process.env.PLUGIN_CTX === "pro") {
        /* onlypro:start */
        hooks.register("attachmentsBrowser/modal/dom/ready", function (container) {
            if (!rmlOpts) return;
            try {
                hooks.call("attachmentsBrowser/modal/exception", [container], this);
                const containerId = `rml${rmlOpts.others.blogId}`;
                const useStore = container.$el.parents(".media-frame").data("useStore");

                createRoot(container.el).render(
                    <StoredAppTree attachmentsBrowser={this} isModal id={containerId} useStore={useStore} />,
                );
            } catch (e) {
                // Silence is golden.
            }
        });
        /* onlypro:end */
    }

    // Options panel
    $("body").hasClass("options-media-php") && optionsScreen();
});

IS_DARKMODE && $("body").addClass("aiot-wp-dark-mode");
isMaterialWp() && $("body").addClass("aiot-wp-material");

export {
    /**
     * @type module:util/hooks
     */
    hooks,
    /**
     * @type object
     */
    rmlOpts,
    /**
     * @type module:util.i18n
     */
    i18n,
    /**
     * @type module:util.urlParam
     */
    urlParam,
    /**
     * @type module:util.applyNodeDefaults
     */
    applyNodeDefaults,
    /**
     * @type module:util.fetchTree
     */
    fetchTree,
    /**
     * @type module:util.findDeep
     */
    findDeep,
    /**
     * @type module:util.humanFileSize
     */
    humanFileSize,
    /**
     * @type module:util.secondsFormat
     */
    secondsFormat,
    /**
     * @type module:util.dataUriToBlob
     */
    dataUriToBlob,
    /**
     * @type module:util/addUrlParam
     */
    addUrlParam,
    /**
     * @type module:store.injectAndObserve
     */
    injectAndObserve,
    /**
     * @type module:store~store
     */
    store,
    /**
     * @type module:store/TreeNode~TreeNode
     */
    TreeNode,
    /**
     * @type module:store/Upload~Upload
     */
    Upload,
    /**
     * @type module:store.StoredAppTree
     */
    StoredAppTree,
    /**
     * @type function
     */
    urlBuilder,
    /**
     * @type function
     */
    request,
};
