<template>
  <q-table
    v-model:fullscreen="fullscreen"
    row-key="id"
    class="softpar-table q-pa-sm"
    flat
    :columns="columns"
    :filter="filter"
    :grid="$q.screen.lt.sm"
    :loading="loading"
    :pagination="{ rowsPerPage }"
    :pagination-label="getPaginationLabel"
    :rows="rows"
    :rows-per-page-label="$t('common.ui.table.rows_per_page')"
    :visible-columns="visibleColumns"
    @row-click="onRowClick"
  >
    <template #top>
      <div
        class="flex full-width justify-between align-center q-mb-md"
        style="gap: 1rem; height: 40px"
      >
        <q-input
          v-if="showSearchField"
          v-model="filter"
          autofocus
          bg-color="surface"
          clearable
          color="primary"
          debounce="250"
          dense
          style="width: 390px"
          :placeholder="$t('common.actions.search')"
        >
          <template #append>
            <q-icon name="mdi-magnify" />
          </template>
        </q-input>

        <q-select
          v-if="showColumnsSelect"
          v-model="visibleColumns"
          emit-value
          map-options
          multiple
          options-outlined
          options-selected-class="text-bold"
          style="width: 150px"
          :display-value="$q.lang.table.columns"
          :options="mapColumns"
        />

        <q-btn
          v-if="filterBtn"
          color="secondary"
          icon="mdi-filter-outline"
          text-color="primary"
          @click="() => emit('toggleFilters')"
        >
        </q-btn>

        <q-space />

        <q-btn
          v-if="addItem"
          class="add-item-color btn-custom-default"
          color="secondary"
          padding="10px 16px"
          :outline="outlineAdd"
          @click="onAddItem"
        >
          <div class="text-primary">Adicionar</div>
        </q-btn>
      </div>

      <div class="q-mt-sm">
        <slot name="filters"></slot>
      </div>
    </template>

    <template #loading>
      <q-inner-loading showing color="primary" />
    </template>

    <template v-if="!hideNoDataLabel" #no-data>
      <div v-if="!loading" class="q-my-md row justify-center full-width">
        <div class="q-pa-md body2">
          {{ $t("http.errors.no_records_found") }}
        </div>
      </div>
    </template>

    <template v-for="(index, name) in $slots" #[name]="data">
      <slot :name="name" v-bind="data"></slot>
    </template>
  </q-table>
</template>

<script setup>
import { onMounted, ref, toRaw, watch } from "vue";
import { useRouter } from "vue-router";

const emit = defineEmits([
  "onRowClick",
  "onAddItem",
  "noRows",
  "toggleFilters",
]);

const {
  addItem,
  addItemRoute,
  apiCall,
  columns,
  hideNoDataLabel,
  noApiCall,
  outlineAdd,
  openItem,
  openItemRoute,
  rowsPerPage,
  showSearchField,
} = defineProps({
  addItem: { type: Boolean, default: true },
  addItemRoute: { type: String, default: "" },
  apiCall: { type: Function, required: true },
  columns: { type: Array, required: true },
  deleteFunction: { type: Function, default: null },
  filterBtn: { type: Boolean, default: true },
  hideNoDataLabel: { type: Boolean, default: false },
  noApiCall: { type: Boolean, default: false },
  outlineAdd: { type: Boolean, default: false },
  openItem: { type: Boolean, default: false },
  openItemRoute: { type: String, default: "" },
  rowsPerPage: { type: Number, default: 10 },
  showColumnsSelect: { type: Boolean, default: false },
  showSearchField: { type: Boolean, default: true },
});

const router = useRouter();

const rows = ref([]);
const filter = ref("");
const loading = ref(true);
const fullscreen = ref(false);
const showInativos = ref(false);
const inativos = ref([]);

//

const mapColumns = columns.reduce((accm, column) => {
  if (!column.required) {
    accm.push({
      label: column.label,
      value: column.name,
    });
  }
  return accm;
}, []);

const visibleColumns = ref(mapColumns.map((column) => column.value));

//

const getPaginationLabel = (from, to, last) => {
  return `${from}-${to} de ${last}`;
};

const onAddItem = () => {
  if (addItem) {
    if (addItemRoute) {
      router.push({ name: addItemRoute });
    } else {
      emit("onAddItem");
    }
  }
};

const onRowClick = (evt, row, index) => {
  const item = toRaw(row);

  if (openItem) {
    if (openItemRoute) {
      router.push({ name: openItemRoute, params: { id: item.id } });
    } else {
      emit("onRowClick", { evt, row, index });
    }
  }
};

const onRequest = async () => {
  if (noApiCall) {
    loading.value = false;

    return;
  }

  loading.value = true;

  const response = await apiCall();

  rows.value.splice(0, rows.value.length, ...response);

  if (rows.value.length == 0) {
    emit("noRows");
  }

  loading.value = false;
};

watch(showInativos, () => {
  if (showInativos.value) {
    rows.value = rows.value.concat(inativos.value);
  } else {
    inativos.value = rows.value.filter(
      (row) => row.status === false || row.ativo === false,
    );

    rows.value = rows.value.filter((row) => row.ativo);
  }
});

watch(
  () => apiCall,
  async () => {
    await onRequest();
  },
);

onMounted(async () => {
  await onRequest({
    filter: undefined,
  });
});

defineExpose({
  refresh: onRequest,
});
</script>

<style lang="scss">
@import "src/css/table.scss";

:deep(.q-field__control) {
  border-radius: 10px;
}
</style>
