<template>
  <div class="my-select">
    <USelect
      v-model="selectedValue"
      :items="formattedItems"
      :placeholder="selectSchema.placeholder || 'انتخاب کنید'"
      :multiple="selectSchema.multiple || false"
      :disabled="selectSchema.disabled || loading"
      :loading="loading"
      @update:modelValue="onModelUpdate"
      :class="[gridColumnClass, 'cursor-pointer']"
      :style="selectWidthStyle"
      :ui="{ wrapper: 'w-full', base: 'w-full' }"
      dir="rtl"
      color="primary"
      size="xl"
      highlight
    />
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch } from "vue";
import { useCachedRequest } from "@/composables/useCachedRequest";

const props = defineProps({
  selectSchema: { type: Object, default: () => ({}) },
  gridColumnClass: { type: String, default: "" },
});

const emit = defineEmits(["my-select-action"]);
const emitAction = (action, payload) => {
  emit("my-select-action", { action, payload });
};

const selectedValue = ref(null);
const rawItems = ref([]);
const loading = ref(false);
const lastEmittedValue = ref(null);

const { fetchRequest } = useCachedRequest();
const mode = computed(() => props.selectSchema.mode ?? "local");

const formattedItems = computed(() => {
  const labelKey = props.selectSchema.labelKey || "name";
  const valueKey = props.selectSchema.valueKey || "id";

  return rawItems.value.map((item) => {
    if (typeof item === "string") return { label: item, value: item };
    return {
      label:
        item[labelKey] ?? item.name ?? item.title ?? item.label ?? "بدون عنوان",
      value: item[valueKey] ?? item.id ?? item._id ?? item.value,
    };
  });
});
const selectWidthStyle = computed(() => {
  return props.selectSchema.width ? { width: props.selectSchema.width } : {};
});

// مقایسه امن برای جلوگیری از emit تکراری
const isSameValue = (a, b) => {
  if (Array.isArray(a) && Array.isArray(b)) {
    if (a.length !== b.length) return false;
    return a.every((v, i) => v === b[i]);
  }
  return a === b;
};

const emitSelected = (val) => {
  if (isSameValue(val, lastEmittedValue.value)) return;

  lastEmittedValue.value = Array.isArray(val) ? [...val] : val;

  const selectedItem = formattedItems.value.find((i) =>
    props.selectSchema.multiple ? val?.includes(i.value) : i.value === val,
  );

  emitAction("selected", selectedItem);
};

const syncDefaultSelection = () => {
  if (props.selectSchema.value != null) return;
  if (!formattedItems.value.length) return;

  const isEmpty =
    selectedValue.value == null ||
    (Array.isArray(selectedValue.value) && !selectedValue.value.length);

  if (isEmpty) {
    const firstItem = formattedItems.value[0];
    const newVal = props.selectSchema.multiple
      ? [firstItem.value]
      : firstItem.value;

    selectedValue.value = newVal;
    emitSelected(newVal);
  }
};

const onModelUpdate = (val) => {
  emitSelected(val);
};

const fetchItems = async () => {
  if (mode.value !== "api") {
    rawItems.value =
      props.selectSchema.options ?? props.selectSchema.items ?? [];
    syncDefaultSelection();
    return;
  }

  const apiConfig = props.selectSchema.apiConfig || {};
  if (!apiConfig.url) return;

  loading.value = true;
  try {
    const data = await fetchRequest(apiConfig);
    rawItems.value = Array.isArray(data) ? data : (data?.data ?? []);
    syncDefaultSelection();
    emitAction("fetch:success", { items: rawItems.value });
  } catch (error) {
    emitAction("fetch:error", { error: error?.message ?? error });
  } finally {
    loading.value = false;
  }
};

watch(
  () => [props.selectSchema.items, props.selectSchema.options],
  () => {
    if (mode.value !== "api") {
      rawItems.value =
        props.selectSchema.options ?? props.selectSchema.items ?? [];
      syncDefaultSelection();
    }
  },
  { immediate: true, deep: true },
);

watch(
  () => props.selectSchema.value,
  (val) => {
    selectedValue.value = val ?? null;
    emitSelected(val);
  },
  { immediate: true },
);

onMounted(fetchItems);
</script>

<style lang="scss">
.my-select {
  button[role="combobox"] {
    direction: rtl; /* راست‌چین کردن متن و placeholder */
    text-align: right; /* ترازبندی متن داخل button */
  }

  /* 2. placeholder */
  button[role="combobox"] [data-slot="placeholder"] {
    text-align: right;
    direction: rtl;
  }

  /* 3. آیکون پایین (chevron) */
  button[role="combobox"] [data-slot="trailing"] {
    right: auto; /* اگر نیاز باشد موقعیت icon را اصلاح کنید */
    left: 0; /* icon به سمت چپ می‌رود */
  }

  /* 4. منوی بازشونده (اگر teleport شده باشد) */
  /* کلاس واقعی منو را از inspector پیدا کنید و به جای .u-select__menu بنویسید */
  .u-select__menu {
    direction: rtl !important;
    text-align: right !important;
  }

  /* 5. آیتم‌های منو */
  .u-select__menu [data-slot="item"] {
    text-align: right;
    direction: rtl;
    display: flex;
    flex-direction: row-reverse; /* اگر icon ها در آیتم هستند آنها را برعکس می‌کند */
  }
}
.i-lucide\:check {
  color: #22c55e;
  stroke: #22c55e;
}
</style>
