<template>
  <div class="q-pa-md">
    <q-table
      flat
      bordered
      ref="tableRef"
      title="groups"
      title-class="text-bold text-blue-9"
      :no-data-label="$t('noDataAvailable')"
      :loading-label="$t('loading')"
      :rows-per-page-label="$t('recordsPerPage')"
      :selected-rows-label="(val) => val + ' ' + $t('recordSelected')"
      :rows="groups"
      :columns="columns"
      row-key="id"
      v-model:pagination="pagination"
      :loading="loading"
      :filter="filter"
      :selection="selectOption ? 'multiple' : 'none'"
      v-model:selected="selected"
      binary-state-sort
      dense
      class="bigger-table-text"
    >
      <template v-slot:top-left>
        <TopButtonGroup
          :permit-add="user.isPermittedTo('group', 'write')"
          v-on:add="openGroupDialog"
          :tool-tip-add="$t('addNewgroup')"
          :permit-select="
            user.isPermittedTo('group', 'write') || user.isPermittedTo('group', 'delete')
          "
          v-model:select-option="selectOption"
          :tool-tip-select="$t('selectgroupOptions')"
        />
        <div v-if="selectOption && selected.length > 0">
          <q-btn flat dense icon="more_vert" @click="openSubmenu = true" />
          <q-menu v-if="openSubmenu" anchor="bottom middle" self="top middle">
            <q-item
              v-if="user.isPermittedTo('group', 'delete')"
              clickable
              v-close-popup
              @click="openRemoveDialog(...selected)"
              class="text-negative"
              >{{ $t('delete') }}</q-item
            >
          </q-menu>
        </div>
        <div v-if="selectOption && selected.length > 0" class="text-weight-bold">
          {{ $t('selected') }}: {{ selected.length }}
        </div>
      </template>

      <!-- top right of table-->

      <template v-slot:top-right>
        <SearchableInput v-model="filter" :placeholder="$t('search')" />
      </template>

      <!-- table body content-->
      <template v-slot:body-cell="props">
        <component
          :is="props.col.component"
          :td-props="props"
          :permitted="user.isPermittedTo('group', 'write')"
          v-on:onClick="openGroupDialog(props.col.label, props.row)"
          :value="props.value + ' (' + getAmount(props.row.name) + ')'"
        />
      </template>
      <template v-slot:body-cell-option="props">
        <component
          :td-props="props"
          :is="props.col.component"
          :permitDelete="user.isPermittedTo('group', 'delete')"
          :removeFunction="() => openRemoveDialog(props.row)"
        >
        </component>
      </template>
    </q-table>
  </div>
  <DialogFrame ref="groupDialog" :header-title="$t('addNewgroup')" :height="250" :width="350">
    <q-form ref="form">
      <div class="row justify-center q-gutter-md">
        <q-input
          class="q-ml-md col-5 required"
          :label="$t('groupName')"
          filled
          :rules="[(val) => !!val || $t('groupNameIsRequired')]"
          v-model="localGroup.name"
          autofocus
          @keyup.enter="save()"
        ></q-input>
      </div>
    </q-form>
    <div class="row justify-center">
      <q-btn class="q-ma-md" color="primary" no-caps @click="save()">{{ $t('save') }}</q-btn>
    </div>
  </DialogFrame>
  <OkDialog
    ref="okDialog"
    :dialog-label="$t('delete')"
    :text="$t('doYouWantToDelete') + ' ' + deleteText"
    label-color="red"
    :button-cancel-label="$t('cancel')"
    :button-ok-label="$t('confirm')"
    :button-ok-flat="false"
    button-ok-color="red"
    v-on:update-confirm="(val) => removegroup(...val)"
  ></OkDialog>
</template>

<script setup lang="ts">
import { appApi } from 'src/boot/axios';
import { ref, onMounted } from 'vue';
import DialogFrame from 'src/vueLib/dialog/DialogFrame.vue';
import OkDialog from 'src/components/dialog/OkDialog.vue';
import { useNotify } from 'src/vueLib/general/useNotify';
import { useGroupTable } from './GroupTable';
import { useUserStore } from 'src/vueLib/login/userStore';
import { i18n } from 'src/boot/lang';
import type { Group, Groups } from 'src/vueLib/models/group';
import SearchableInput from '../components/SearchableInput.vue';
import TopButtonGroup from '../components/TopButtonGroup.vue';
import { getAllMembers } from '../members/MembersTable';
import type { Members } from 'src/vueLib/models/member';
import { openDatabase } from 'src/vueLib/components/DatabaseCall';

const { NotifyResponse } = useNotify();
const groupDialog = ref();
const form = ref();
const localGroup = ref<Group>({} as Group);
const localLabel = ref('');
const okDialog = ref();
const deleteText = ref('');
const selectOption = ref(false);
const selected = ref<Groups>([]);
const openSubmenu = ref(false);
const filter = ref('');
const user = useUserStore();
const members = ref<Members>([]);

const { groups, pagination, loading, columns, updateGroups } = useGroupTable();

//load on mounting page
onMounted(async () => {
  loading.value = true;

  members.value = await getAllMembers();

  await openDatabase()
    .then(() => {
      updateGroups().catch((err) => {
        NotifyResponse(err, 'error');
      });
    })
    .catch((err) => NotifyResponse(err, 'error'))

    .finally(() => {
      loading.value = false;
    });
});

//opens dialog for one value
function openGroupDialog(label?: string, group?: Group) {
  localLabel.value = label!;
  localGroup.value = group ? group : <Group>{ name: '' };
  groupDialog.value?.open();
}

//opens remove dialog
function openRemoveDialog(...groups: Groups) {
  if (groups.length === 1) {
    deleteText.value = "'" + localGroup.value.name + "''";
  } else {
    deleteText.value = String(groups.length) + ' ' + i18n.global.t('groups');
  }
  okDialog.value?.open(groups);
}

//remove group from database
function removegroup(...removegroups: Groups) {
  const groupIds: number[] = [];

  removegroups.forEach((group: Group) => {
    groupIds.push(group.id);
  });

  appApi
    .post('groups/delete', { ids: groupIds })
    .then(() => {
      updateGroups().catch((err) => {
        NotifyResponse(err, 'error');
      });
      selected.value = [];
    })
    .catch((err) => NotifyResponse(err, 'error'))
    .finally(() => {
      loading.value = false;
    });
}

async function save() {
  const valid = await form.value.validate();

  if (!valid) return;

  let query = 'groups/edit';
  let payload = JSON.stringify([localGroup.value]);

  if (!localGroup.value.id) {
    query = 'groups/add';
    payload = JSON.stringify(localGroup.value);
  }

  appApi
    .post(query, payload)
    .then(() => {
      updateGroups().catch((err) => NotifyResponse(err, 'error'));
      groupDialog.value.close();
    })
    .catch((err) => NotifyResponse(err, 'error'));
}

function getAmount(name: string) {
  const amount = members.value.filter((e) => e.group?.name == name);
  return amount.length;
}
</script>

<style>
.bigger-table-text .q-table__middle td {
  font-size: 14px;
}

.bigger-table-text .q-table__top,
.bigger-table-text .q-table__bottom,
.bigger-table-text th {
  font-size: 14px;
}
</style>
