<template>
  <Teleport to="#__nuxt > div">
    <div class="modal is-active" @click="doClick">
      <div
        class="modal-background"
        :style="`opacity:${count === 0 ? 0.7 : 0.3} !important;`"
      ></div>
      <div class="modal-card" :id="docid" :style="`width:${vWidth};`">
        <header
          class="modal-card-head my-0 p-2 pl-4 is-justify-content-space-between is-shadowless border-bottom"
          v-if="title"
        >
          <p class="fsb-17 has-text-primary" v-html="title"></p>
          <button
            class="button rounded-full p-2 is-white"
            @click="closeModal()"
          >
            <SvgIcon v-bind="{ name: 'close.svg', size: 16 }" />
          </button>
        </header>
        <section
          class="modal-card-body px-4 py-4"
          :style="`min-height:${
            height ? height : '750px'
          };border-bottom-left-radius:16px; border-bottom-right-radius:16px;`"
        >
          <component
            :is="resolvedComponent"
            v-bind="props.vbind"
            @modalevent="modalEvent"
            @close="closeModal"
          />
        </section>
      </div>
    </div>
  </Teleport>
</template>

<script setup>
import { onMounted, defineAsyncComponent, shallowRef, watchEffect } from 'vue';
import { useStore } from '@/stores/index';

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

const props = defineProps({
  component: String,
  width: String,
  height: String,
  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 viewport = store.viewport;
const docid = $id();
const title = props.title;
let count = 0;
const lock = false;
const vWidth = viewport <= 2 ? '100%' : props.width || '60%';

const closeModal = function () {
  if (!lock) 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);
  }
};

const doClick = function (e) {
  if (!e.srcElement.offsetParent) return;
  const el = document.getElementById(docid);
  if (el && !el.contains(e.target)) {
    closeModal();
  }
};

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>
