import { defineComponent, inject, ref, watch, unref } from "vue";
import { FormConfig, PageSearch } from "../../PageSearch";
import type { Events, Hooks } from "./types";

import { type ModalConfig, PageModal } from "../../PageModal";

import {
  PageContent,
  type ContentConfig,
  type PageContentInstance
} from "/@/components/PageContent";

const PageContainer = defineComponent({
  name: "PageContainer",
  props: {
    pageName: { type: String, default: "" },
    contentConfig: { type: Object as PropType<ContentConfig> },
    searchConfig: { type: Object as PropType<FormConfig> },
    modalConfig: { type: Object as PropType<ModalConfig> },
    getContentRef: { type: Function as PropType<(ref: PageContentInstance) => any> },
    getModalRef: { type: Function as PropType<(ref: PageContentInstance) => any> },
    hooks: { type: Object as PropType<Hooks>, default: () => ({}) },
    events: { type: Object as PropType<Events>, default: () => ({}) },
    otherSearchParameter : { type: Object as PropType<Events>, default: () => ({}) },
    isPageStart: { type: Boolean, default: false }
  },
  emits: ["content-select-change"],
  setup(props, { slots, emit, expose }) {
    const { pageSearchHook, pageModalHook } = props.hooks as Hooks;
    const search = pageSearchHook ? pageSearchHook() : ({} as any);
    const innerContentRef = search.pageContentRef ? search.pageContentRef : ref(null);

    const modal = pageModalHook ? pageModalHook(innerContentRef) : ({} as any);
    const innerModalRef = modal.pageModalRef ? modal.pageModalRef : ref(null);
    const { permissions } = inject<AuthProvide>("Auth", {
      permissions: ref([])
    });

    function renderPageContent() {
      const { contentConfig, events, otherSearchParameter } = props;
      const { content: contentEvents = {} } = events as any;
      if (!contentConfig) return;
      return (
        <PageContent
          class="h-full"
          ref={innerContentRef}
          contentConfig={contentConfig}
          powers={permissions.value}
          onPreviewBtnClick={contentEvents.preview || modal.handlePreviewData}
          onUpdateBtnClick={contentEvents.update || modal.handleUpdateData}
          onCreateBtnClick={contentEvents.create || modal.handleCreateData}
          onSelectionChange={value => emit("content-select-change", value)}
          otherSearchParameter={otherSearchParameter}
          onGetReuslt={data => contentEvents.result && contentEvents.result(data)}
          onGetHandleResult={data =>contentEvents.handleResult && contentEvents.handleResult(data)}
          v-slots={{
            table_header: () => slots.content_table_header && slots.content_table_header(),
            header: () => slots.content_header && slots.content_header(),
            custom: row => slots.content_action && slots.content_action(row),
            expand: row => slots.expand && slots.expand(row)
          }}
        />
      );
    }

    function renderPageSearch() {
      const { searchConfig, events} = props;
      const { search: searchEvents = {} } = events as any;
      if (!searchConfig) return null;
      return (
        <PageSearch
          formConfig={searchConfig}
          onResetBtnClick={searchEvents.reset ? searchEvents.reset : search.handleResetClick}
          onSearchBtnClick={search.handleSearchClick}
          v-slots={{ 
            custom: () => slots.search_field && slots.search_field() ,
            action: () => slots.search_button && slots.search_button() ,
          }}
        />
      );
    }

    function renderPageModal() {
      const { modalConfig } = props;
      if (!modalConfig) return null;
      return (
        <PageModal
          ref={innerModalRef}
          modalConfig={modalConfig}
          defaultInfo={modal.defaultInfo.value}
          onConfirmBtnClick={modal.handleConfrim}
        />
      );
    }

    watch(
      () => innerContentRef,
      () => {
        const contentRef = unref(innerContentRef);
        const { getContentRef } = props;
        if (contentRef && getContentRef) getContentRef(contentRef);
      },
      { deep: true }
    );

    watch(
      () => innerModalRef,
      () => {
        const modalRef = unref(innerModalRef);
        const { getModalRef } = props;
        if (modalRef && getModalRef) getModalRef(modalRef);
      },
      { deep: true }
    );

    expose({
      getContent: () => innerContentRef
    });

    return () => {
      return (
        <div class={`w-full h-full ${props.isPageStart ? 'page-container-start' : ''}`}>
          {renderPageSearch()}
          {renderPageContent()}
          {renderPageModal()}
        </div>
      );
    };
  }
});

export default PageContainer;
