import { WidgetContent } from "../../plug-api/app_event.ts";
import { WidgetType } from "../deps.ts";
import type { Client } from "../client.ts";
import { createWidgetSandboxIFrame } from "../components/widget_sandbox_iframe.ts";
import type { CodeWidgetCallback } from "$sb/types.ts";

export class IFrameWidget extends WidgetType {
  iframe?: HTMLIFrameElement;

  constructor(
    readonly from: number,
    readonly to: number,
    readonly client: Client,
    readonly bodyText: string,
    readonly codeWidgetCallback: CodeWidgetCallback,
  ) {
    super();
  }

  toDOM(): HTMLElement {
    const from = this.from;
    const iframe = createWidgetSandboxIFrame(
      this.client,
      this.bodyText,
      this.codeWidgetCallback(this.bodyText, this.client.currentPage!),
      (message) => {
        switch (message.type) {
          case "blur":
            this.client.editorView.dispatch({
              selection: { anchor: from },
            });
            this.client.focus();

            break;
          case "reload":
            this.codeWidgetCallback(this.bodyText, this.client.currentPage!)
              .then(
                (widgetContent: WidgetContent) => {
                  iframe.contentWindow!.postMessage({
                    type: "html",
                    html: widgetContent.html,
                    script: widgetContent.script,
                    theme:
                      document.getElementsByTagName("html")[0].dataset.theme,
                  });
                },
              );
            break;
        }
      },
    );

    const estimatedHeight = this.estimatedHeight;
    iframe.height = `${estimatedHeight}px`;

    return iframe;
  }

  get estimatedHeight(): number {
    const cachedHeight = this.client.getCachedWidgetHeight(this.bodyText);
    // console.log("Calling estimated height", this.bodyText, cachedHeight);
    return cachedHeight > 0 ? cachedHeight : 150;
  }

  eq(other: WidgetType): boolean {
    return (
      other instanceof IFrameWidget &&
      other.bodyText === this.bodyText
    );
  }
}