import {
  defineComponent,
  onBeforeUpdate,
  onUnmounted,
  watch,
  type PropType
} from "vue-demi";
import { ModContext } from "../types/ModContext";
import { InvokerItem } from "./InvokerItem";

let idCount = 0;
export type InvokerModName = string;

export default defineComponent({
  props: {
    height: {
      type: String,
      default: () => "auto",
    },
    scroll: {
      type: Boolean,
      default: () => false,
    },
    items: {
      type: Array,
      default: () => undefined as InvokerItem[] | undefined,
    },
    name: {
      type: String as PropType<InvokerModName> | undefined,
      default: () => undefined,
      required: false,
    }
  },
  emits: ["destroyed"],
  setup(props, { slots, expose, emit }) {
    /** Invoker实例ID */
    const id = ++idCount;
    /** vue实例上下文，此处获取的是Receiver的vue组件实例 */
    let receiver: ModContext | null = null;

    window["MES_MOD_INVOKERS"] ||= {};
    window["MES_MOD_INVOKERS"][id] = {
      getRenderContext,
      initFinish,
      receiver,
    };


    /** 主动更新 */
    function updateComponent() {
      // 判断子页面vue对象是否存在
      receiver?.Update(); // 强制渲染
    }

    // 子组件调用
    function eventCallback(type: string, ...args: any[]) {
      switch (type) {
        case "created":
          initFinish(args[0]);
          break;
      }
    }

    /** 当Receiver初始化完毕后触发 */
    function initFinish(context: ModContext) {
      receiver = context;
      console.log('[Mod-Invoker]initFinish')
    }

    function getRefs() {
      const refs = receiver?.refs;
      if (!refs) throw new Error("[Mod-Invoker] Receiver not found");
      return refs;
    }

    // vue3 渲染上下文
    function getRenderContext() {
      return props.items;
    }

    expose({
      getRefs,
      getRenderContext,
      eventCallback,
      initFinish,
    });

    watch(
      () => props.items,
      () => {
        updateComponent();
      }
    );

    onBeforeUpdate(() => {

    });
    onUnmounted(() => {
      console.log("[Mod-Invoker] invoker-destroyed");
      emit('destroyed');
    });

    return (h) => {
      if (slots.default) {
        return <div>{slots.default()}</div>;
      }

      return (
        <iframe
          src={props.url.replace('{id}',id.toString())}
          scrolling={props.scroll ? "yes" : "no"}
          style={`border: none; width: 100%; height: ${props.height}; `}
        ></iframe>
      );
    };
  },
});
