import { createElement } from "../../lib/skeleton/index.js";
import rxjs, { effect } from "../../lib/rx.js";
import { animate, slideXIn, opacityOut } from "../../lib/animate.js";
import { qs } from "../../lib/dom.js";
import { join } from "../../lib/path.js";
import ajax from "../../lib/ajax.js";

import { save } from "../../pages/viewerpage/model_files.js";
import { $ICON } from "../../pages/viewerpage/common_fab.js";
import { createLoader } from "../../components/loader.js";
import "../../components/fab.js";
import "../../components/icon.js";

export default async function(render, { getDownloadUrl, getFilename, acl$ }) {
    const $page = createElement(`
        <div class="component_xlsx full-width">
            <iframe class="full-width" src="${join(import.meta.url, "./dist/index.html")}"></iframe>
            <button is="component-fab" class="hidden"></button>
            <style>${css}</style>
        </div>
    `);
    const $iframe = qs($page, "iframe");
    const $fab = qs($page, `[is="component-fab"]`);
    render($page);

    // feature: load the workbook
    const removeLoader = createLoader($page);
    effect(rxjs.combineLatest([
        ajax({ url: getDownloadUrl(), responseType: "arraybuffer" }),
        acl$,
        fromMessages$($iframe, "xlsx:ready").pipe(rxjs.take(1)),
    ]).pipe(
        removeLoader,
        rxjs.tap(([{ response }, acl, _]) => {
            const readOnly = acl.indexOf("PUT") === -1 && acl.indexOf("POST") === -1;
            $iframe.contentWindow.postMessage(
                { type: "xlsx:load", buffer: response, name: getFilename(), readOnly }, "*", [response],
            );
        }),
    ));

    // feature: workbook save
    effect(fromMessages$($iframe, "xlsx:change").pipe(
        rxjs.filter(() => $fab.classList.contains("hidden")),
        rxjs.tap(async () => {
            $fab.render($ICON.SAVING);
            $fab.classList.remove("hidden");
            await animate($fab, { time: 100, keyframes: slideXIn(40) });
        }),
        rxjs.switchMap(() => rxjs.fromEvent($fab, "click").pipe(rxjs.take(1))),
        rxjs.tap(() => {
            $fab.render($ICON.LOADING);
            $fab.disabled = true;
            $iframe.contentWindow.postMessage({ type: "xlsx:save:request" }, "*");
        }),
        rxjs.switchMap(() => fromMessages$($iframe, "xlsx:save:response").pipe(rxjs.take(1))),
        rxjs.switchMap((e) => save(e.data.buffer)),
        rxjs.tap(async () => {
            $fab.removeAttribute("disabled");
            await animate($fab, { time: 100, keyframes: opacityOut() });
            $fab.classList.add("hidden");
        }),
    ));
}

const fromMessages$ = ($iframe, type) => rxjs.fromEvent(window, "message").pipe(
    rxjs.filter((e) => e.source === $iframe.contentWindow && e.data?.type === type),
);

const css = `
.component_xlsx iframe {
    height: 100%;
    border: none;
}
`;
