<template>
  <DefaultSelect
    v-model="selectedPartner"
    v-bind="$attrs"
    use-input
    hide-selected
    fill-input
    clearable
    input-debounce="400"
    :options="partnerOptions"
    :label
    :loading
    :placeholder
    @filter="onFilter"
    @virtual-scroll="onVirtualScroll"
  >
    <template #no-option>
      <q-item>
        <q-item-section class="text-grey">
          {{ loading ? $t("common.status.loading") : $t("http.errors.no_records_found") }}
        </q-item-section>
      </q-item>
    </template>
  </DefaultSelect>
</template>

<script setup>
import { ref, computed } from "vue";
import { getPartnerAgreementsForSelect, getConveniosForSelect } from "src/api/partnerAgreement";
import { useI18n } from "vue-i18n";
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";

const { label, placeholder, forAssociado, type } = defineProps({
  label: {
    type: String,
    default: () => useI18n().t("ui.navigation.convenios"),
  },
  placeholder: {
    type: String,
    default: () => useI18n().t("common.actions.search"),
  },
  forAssociado: {
    type: Boolean,
    default: false,
  },
  type: {
    type: String,
    default: "agreement",
  },
});

const selectedPartner = defineModel({ type: Object });

const PER_PAGE = 20;

const loading = ref(false);
const partnerOptions = ref([]);
const total = ref(0);
const search = ref("");

const hasMore = computed(() => partnerOptions.value.length < total.value);

const fetchPartners = async ({ reset = false } = {}) => {
  if (loading.value || (!reset && !hasMore.value)) return;

  loading.value = true;
  try {
    const page = reset ? 1 : Math.floor(partnerOptions.value.length / PER_PAGE) + 1;
    const payload = await (forAssociado ? getConveniosForSelect : getPartnerAgreementsForSelect)({
      page,
      perPage: PER_PAGE,
      search: search.value,
      type,
    });

    const mapped = (payload?.data ?? []).map((p) => ({
      label: p.trade_name || p.company_name,
      value: p.id,
      data: p,
    }));

    partnerOptions.value = reset ? mapped : partnerOptions.value.concat(mapped);
    total.value = payload?.total ?? partnerOptions.value.length;
  } catch (e) {
    console.error(e);
  } finally {
    loading.value = false;
  }
};

const onFilter = (val, update) => {
  search.value = val ?? "";
  fetchPartners({ reset: true }).then(() => update());
};

const onVirtualScroll = ({ to }) => {
  if (to === partnerOptions.value.length - 1) fetchPartners();
};
</script>
