<template>
  <q-table
    v-model:fullscreen="fullscreen"
    flat
    class="softpar-table"
    :pagination="{ rowsPerPage }"
    :pagination-label="getPaginationLabel"
    row-key="id"
    :rows="rows"
    rows-per-page-label="Itens por página"
    :columns="props.columns"
    :visible-columns="visibleColumns"
    :filter="filter"
    @row-click="onRowClick"
  >
    <template #top>
      <q-input
        v-if="mostrarCampoPesquisa"
        v-model="filter"
        outlined
        dense
        debounce="500"
        placeholder="Pesquisar"
        style="min-width: 400px"
        clearable
        autofocus
      >
        <template #append>
          <q-icon name="mdi-magnify" />
        </template>
      </q-input>

      <!-- <q-checkbox
        v-if="props.mostrarToggleInativos"
        v-model="showInativos"
        class="q-ml-sm"
        :label="props.labelInativo"
        dense
        color="secondary"
      /> -->

      <q-select
        v-if="mostrarSelecaoDeColunas"
        v-model="visibleColumns"
        class="q-ml-md"
        multiple
        dense
        outlined
        options-outlined
        :display-value="$q.lang.table.columns"
        emit-value
        map-options
        :options="mapColuns"
        option-value="name"
        style="min-width: 150px"
        options-selected-class="text-bold"
      />

      <q-btn
        v-if="mostrarBotaoFullscreen"
        flat
        class="q-ml-md"
        @click="fullscreen = !fullscreen"
      >
        <q-icon name="mdi-fullscreen" />
      </q-btn>

      <q-space />

      <q-btn-dropdown
        v-if="props.dropDown"
        class="q-mr-md"
        color="primary"
        label="Opções"
      />

      <q-btn
        v-if="props.addItem"
        class="button-secondary"
        color="primary"
        padding="12px 16px"
        :outline="props.outlineAdd"
        label="Adicionar"
        @click="onAddItem"
      >
      </q-btn>
    </template>

    <template #body-cell-status="{ value, row }">
      <q-td style="width: 8%">
        <q-item-section>
          <span class="text-center">
            <div v-if="row.status && value" class="ativo body2 text-positive">
              Ativo
            </div>
            <div v-if="!row.status" class="inativo body2 text-accent">
              Inativo
            </div>
          </span>
        </q-item-section>
      </q-td>
    </template>

    <template #body-cell-ativo="{ value, row }">
      <q-td style="width: 8%">
        <q-item-section>
          <span class="text-center">
            <div v-if="row.ativo && value" class="ativo body2 text-positive">
              Ativo
            </div>
            <div v-if="row.ativo && !value" class="ativo body2 text-positive">
              Ativo
            </div>
            <div v-if="!row.ativo" class="inativo body2 text-accent">
              Ativo
            </div>
          </span>
        </q-item-section>
      </q-td>
    </template>

    <template v-if="!props.hideNoDataLabel" #no-data>
      <div class="q-my-md row justify-center full-width">
        <q-spinner v-if="loading" color="primary" size="30px" />
        <div v-else class="q-pa-md body2">
          Nenhum registro encontrado
        </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 { ref, onMounted, toRaw, watch } from "vue";
import { useRouter } from "vue-router";

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

const props = defineProps({
  // colunas de configuração da tabela
  columns: {
    type: Array,
    required: true,
  },

  // rota da api, ex: /clientes
  apiRoute: {
    type: Function,
    required: true,
  },

  // botao de adicionar com aparencia de outline
  outlineAdd: {
    type: Boolean,
    default: false,
  },

  // ir para sub pagina on row click
  openItem: {
    type: Boolean,
    default: false,
  },
  // rota da sub page
  openItemRoute: {
    type: String,
    default: "",
  },

  // botao de adicionar
  addItem: {
    type: Boolean,
    default: true,
  },

  // botao de opcoes
  dropDown: {
    type: Boolean,
    default: false,
  },

  // botao de adicionar route
  addItemRoute: {
    type: String,
    default: "",
  },

  // quantidade de items por pagina
  rowsPerPage: {
    type: Number,
    default: 10,
  },

  comecarDesativado: {
    type: Boolean,
    default: false,
  },

  mostrarSelecaoDeColunas: {
    type: Boolean,
    default: false,
  },

  mostrarBotaoFullscreen: {
    type: Boolean,
    default: false,
  },

  // mostrarToggleInativos: {
  //   type: Boolean,
  //   default: false,
  // },

  mostrarCampoPesquisa: {
    type: Boolean,
    default: true,
  },

  noApiRoute: {
    type: Boolean,
    default: false,
  },

  hideNoDataLabel: {
    type: Boolean,
    default: false,
  },

  // labelInativo: {
  //   type: String,
  //   default: "Exibir inativos",
  // },
});

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 getPaginationLabel = (from, to, last) => {
  return `${from}-${to} de ${last}`;
};

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(
  () => props.apiRoute,
  async () => {
    await onRequest();
  },
);

// remove as colunas obrigatórias do filtro de colunas
const mapColuns = props.columns.reduce((accm, column) => {
  if (!column.required) {
    accm.push(column);
  }
  return accm;
}, []);

// as colunas que serão carregadas
const visibleColumns = ref(mapColuns.map((column) => column.name));

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

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

// busca os dados do banco com filtros e pagination
const onRequest = async () => {
  // const filter = params.filter;
  if (props.noApiRoute) {
    loading.value = false;
    return;
  }
  // inicia o loading
  loading.value = true;

  // pega os dados do servidor
  const response = await props.apiRoute();
  // limpa os dados atuais e adiciona os novos
  rows.value.splice(0, rows.value.length, ...response);

  // if (props.mostrarToggleInativos && !showInativos.value) {
  //   inativos.value = rows.value.filter(
  //     (row) => row.status === false || row.ativo === false,
  //   );
  //   rows.value = rows.value.filter((row) => row.ativo || row.status === true);
  // }

  if (rows.value.length == 0) {
    emit("noRows");
  }
  // finaliza o loading
  loading.value = false;
};

onMounted(async () => {
  // faz a primeira requisição
  await onRequest({
    filter: undefined,
  });
  if (props.comecarDesativado) {
    visibleColumns.value = mapColuns
      .map((column) => column.required)
      .map((column) => column.name);
  }
});
</script>

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

.ativo {
  justify-content: center;
  align-items: center;
  padding: 5px 12px;
  gap: 10px;
  background: #cfdab7;
  border-radius: 24px;
}

.chip {
  justify-content: center;
  align-items: center;
  padding: 5px 12px;
  gap: 10px;
  border-radius: 24px;
}

.inativo {
  justify-content: center;
  align-items: flex-start;
  padding: 5px 12px;
  gap: 10px;
  background: #f7cfbb;
  border-radius: 24px;
}
</style>
