<template>
  <Teleport
    defer
    to="#modals"
  >
    <div
      :id="id"
      class="modal is-active has-text-text-20"
    >
      <div
        class="modal-background"
        @click="closeModal"
      ></div>
      <div
        class="modal-card"
        :style="{
          width: $store.viewport <= 1 ? 'calc(100% - 2rem)' : width,
        }"
      >
        <header
          v-if="title"
          class="modal-card-head px-4 py-3"
        >
          <p
            class="modal-card-title fs-17 font-semibold control is-expanded"
            v-html="title"
          ></p>
          <button
            class="delete is-medium"
            aria-label="close"
            @click="closeModal"
          ></button>
        </header>
        <section
          class="modal-card-body p-4"
          :style="{ minHeight: height }"
        >
          <Suspense>
            <component
              :is="resolvedComponent"
              v-bind="vbind"
              @modalevent="modalEvent"
              @close="closeModal"
            />
            <template #fallback>
              <div class="h-full is-flex is-justify-content-center is-align-items-center">
                <Icon
                  name="svg-spinners:180-ring-with-bg"
                  :size="28"
                  class="has-text-primary"
                />
              </div>
            </template>
          </Suspense>
        </section>
        <footer class="modal-card-foot px-4 pb-4 pt-0"></footer>
      </div>
    </div>
  </Teleport>
</template>

<script setup>
import { onMounted, defineAsyncComponent, shallowRef, watchEffect } from "vue";

const emit = defineEmits(["close", "remove", "select", "dataevent", "update"]);
const { $store } = useNuxtApp();

const props = defineProps({
  component: String,
  width: { type: String, default: "60%" },
  height: { type: String, default: "750px" },
  vbind: Object,
  title: String,
});

const componentFiles = import.meta.glob("~/components/**/*.vue");
const resolvedComponent = shallowRef(null);

function loadDynamicComponent() {
  if (!props.component) {
    resolvedComponent.value = null;
    return;
  }

  const fullPath = `/components/${props.component}.vue`;
  const componentPath = Object.keys(componentFiles).find((path) => path.endsWith(fullPath));

  if (componentPath) {
    resolvedComponent.value = defineAsyncComponent(componentFiles[componentPath]);
  } else {
    console.error(`Không tìm thấy component tại: ${fullPath}`);
    resolvedComponent.value = null;
  }
}

// Theo dõi sự thay đổi của props.component để load lại nếu cần
watchEffect(() => {
  loadDynamicComponent();
});

const id = useId();
let count = 0;

function closeModal() {
  const modals = document.getElementById("modals");
  const isTopMost = modals.lastElementChild?.id === id;
  if (isTopMost) {
    emit("close");
  }
}

const modalEvent = function (ev) {
  if (ev.name === "select") {
    emit("select", ev.data);
  } else if (ev.name === "dataevent") {
    emit("dataevent", ev.data);
  } else if (ev.name === "update") {
    emit("update", ev.data);
  } else {
    emit(ev.name, ev.data);
  }
};

onMounted(() => {
  document.documentElement.classList.add("is-clipped");
  window.addEventListener("keydown", (e) => {
    if (e.key === "Escape") closeModal();
  });
  const collection = document.getElementsByClassName("modal-background");
  count = collection.length;
});

onUnmounted(() => {
  count--;
  if (count === 0) document.documentElement.classList.remove("is-clipped");
});
</script>
<style scoped>
.modal {
  overflow: scroll;
}

.modal-background {
  position: fixed;
  --bulma-modal-background-background-color: hsla(
    var(--bulma-scheme-h),
    var(--bulma-scheme-s),
    var(--bulma-scheme-invert-l),
    0.5
  );
}

.modal-card {
  overflow: visible;
}

.modal-card:not(:has(.modal-card-head)) .modal-card-body {
  border-start-start-radius: var(--bulma-radius-large);
  border-start-end-radius: var(--bulma-radius-large);
}

.modal-card:has(.modal-card-foot:empty) .modal-card-body {
  border-end-start-radius: var(--bulma-radius-large);
  border-end-end-radius: var(--bulma-radius-large);
}

.modal-card-foot {
  background-color: var(--bulma-modal-card-body-background-color);

  &:empty {
    display: none;
  }
}
</style>
