<template>
  <div class="columns mx-0 px-0 py-2">
    <!-- Tab Navigation -->
    <div
      :class="`column is-narrow p-0 pr-4 ${viewport < 2 ? 'px-0' : ''}`"
      :style="`${viewport < 2 ? '' : 'border-right: 1px solid #B0B0B0;'}`"
    >
      <div
        :class="['is-clickable p-3', i !== 0 && 'mt-2', getStyle(v)]"
        style="width: 120px; border-radius: 4px"
        v-for="(v, i) in tabsArray"
        :key="i"
        @click="changeTab(v)"
      >
        {{ isVietnamese ? v.name : v.en }}
      </div>
    </div>

    <!-- Tab Content -->
    <div
      :class="`column pl-4 ${viewport < 2 ? 'px-0' : 'pr-0 py-0'}`"
      style="min-width: 0"
    >
      <div
        v-if="isLoading"
        class="has-text-centered"
      >
        <span class="icon is-large">
          <SvgIcon v-bind="{ name: 'loading.svg', type: 'primary', size: 18 }" />
        </span>
      </div>
      <component
        :is="getComponent(activeComponent.component)"
        v-else-if="activeComponent && activeComponent.component"
        v-bind="componentProps"
        @update="handleUpdate"
        @close="emit('close')"
      />
    </div>
  </div>
</template>

<script setup>
import { ref, computed, defineAsyncComponent, watch } from "vue";
import { useStore } from "@/stores/index";
import { useNuxtApp } from "#app";

const props = defineProps({
  tabs: [Array, Object],
  row: Object,
  pagename: String,
  application: Object,
});

const emit = defineEmits(["modalevent", "close"]);
const store = useStore();
const nuxtApp = useNuxtApp();
const { $dialog, $calculate, $findapi, $getapi, $copy } = nuxtApp;

const tabsArray = computed(() => {
  if (Array.isArray(props.tabs)) {
    return props.tabs;
  }
  if (typeof props.tabs === "object" && props.tabs !== null) {
    return Object.keys(props.tabs)
      .sort()
      .map((key) => props.tabs[key]);
  }
  return [];
});

const modules = import.meta.glob("@/components/**/*.vue");
function getComponent(path) {
  if (!path || typeof path !== "string" || !path.includes("/")) return null;
  const moduleKey = Object.keys(modules).find((key) => key.endsWith(`${path}.vue`));
  if (moduleKey) return defineAsyncComponent(modules[moduleKey]);
  console.warn(`Component not found: ${path}`);
  return null;
}

const lang = computed(() => store.lang);
const isVietnamese = computed(() => lang.value === "vi");
const viewport = computed(() => store.viewport);

const record = ref(props.row || {});
const activeTab = ref(
  tabsArray.value.find((t) => t.active === true || t.active === "true")?.code || tabsArray.value[0]?.code || "",
);
const tabData = ref(null);
const isLoading = ref(false);

const activeComponent = computed(() => tabsArray.value.find((t) => t.code === activeTab.value));

const componentProps = computed(() => {
  const baseProps = {
    row: record.value,
    data: tabData.value,
    pagename: props.pagename,
    application: props.application,
  };

  const tabSpecificProps = activeComponent.value?.vbind || {};
  const processedProps = {};

  if (record.value) {
    for (const key in tabSpecificProps) {
      const value = tabSpecificProps[key];
      if (typeof value === "string" && value.startsWith("row.")) {
        const recordKey = value.substring(4);
        processedProps[key] = record.value[recordKey];
      } else {
        processedProps[key] = value;
      }
    }
  }

  return { ...baseProps, ...processedProps };
});

watch(
  activeTab,
  async (newTabCode) => {
    const tabConfig = tabsArray.value.find((t) => t.code === newTabCode);
    if (tabConfig && tabConfig.api) {
      await fetchTabData(tabConfig);
    } else {
      tabData.value = null;
    }
  },
  { immediate: true },
);

async function fetchTabData(tabConfig) {
  isLoading.value = true;
  tabData.value = null;
  try {
    let conn = $findapi(tabConfig.api.name);
    if (!conn) {
      console.error(`API connection '${tabConfig.api.name}' not found.`);
      return;
    }
    conn = $copy(conn);

    if (tabConfig.api.params) {
      let params = $copy(tabConfig.api.params);
      for (const key in params.filter) {
        const value = params.filter[key];
        if (typeof value === "string" && value.startsWith("record.")) {
          const recordKey = value.substring(7);
          params.filter[key] = record.value[recordKey];
        }
      }
      conn.params = params;
    }

    const result = await $getapi([conn]);
    const apiResult = result.find((r) => r.name === tabConfig.api.name);
    if (apiResult && apiResult.data) {
      tabData.value = apiResult.data.rows;
    }
  } catch (error) {
    console.error("Error fetching tab data:", error);
  } finally {
    isLoading.value = false;
  }
}

function getStyle(tab) {
  const canEnter = checkCondition(tab, false);
  return tab.code === activeTab.value
    ? "has-background-primary has-text-white"
    : `has-background-light ${canEnter ? "" : "has-text-grey-light"}`;
}

function checkCondition(tab, showAlert = true) {
  if (!tab.condition) return true;
  const context = { record: record.value };
  const result = $calculate(context, [], tab.condition);
  if (!result.success || !result.value) {
    if (showAlert) {
      $dialog("Vui lòng <b>lưu dữ liệu</b> hoặc hoàn tất các bước trước khi chuyển sang mục này.", "Thông báo");
    }
    return false;
  }
  return true;
}

function changeTab(tab) {
  if (activeTab.value === tab.code) return;
  if (!checkCondition(tab)) return;
  activeTab.value = tab.code;
}

function handleUpdate(updatedRecord) {
  record.value = { ...record.value, ...updatedRecord };
  emit("modalevent", { name: "dataevent", data: record.value });
}
</script>
