<template>
  <div class="q-pa-md">
    <div class="q-gutter-sm row items-start">
        <q-breadcrumbs>
          <q-breadcrumbs-el icon="work" label="ロールの割り当て" />
        </q-breadcrumbs>
    </div>

    <div class="row" style="min-height: 80vh;">
      <!-- left role panel -->
      <div class="col-auto">
        <div class="q-pa-md" style="width: 250px">
          <q-list bordered separator class="rounded-borders">
            <q-item active v-if="allLoading"  active-class="menu-active">
              <q-item-section class="text-weight-bold"> 読み込み中... </q-item-section>
            </q-item>
            <q-item v-else v-for="item in roles" :key="item.id" clickable v-ripple :active="selected?.id === item.id" @click="roleClicked(item)" active-class="menu-active">
              <q-item-section class="text-weight-bold"> {{ item.name }} </q-item-section>
            </q-item>
          </q-list>
        </div>
      </div>
      <!-- right table panel -->
      <div class="col">

        <q-table title="ユーザーリスト" :rows="rows" :columns="columns" row-key="id" :filter="filter" :loading="allLoading || loading"
          :pagination="pagination" >

          <template v-slot:top>
            <q-btn color="primary" :disable="allLoading || loading || selected?.id == EMPTY_ROLE.id" label="追加" @click="showAddRoleDialog" />
            <q-space />
            <q-input borderless dense filled debounce="300" v-model="filter" placeholder="検索">
              <template v-slot:append>
                <q-icon name="search" />
              </template>
            </q-input>
          </template>

          <template v-slot:body-cell-status="props">
            <q-td :props="props">
              <div class="row">
                <div v-if="props.row.isActive">
                  <q-chip square color="positive" text-color="white" icon="done" label="使用可能" size="sm" />
                </div>
                <div v-else>
                  <q-chip square color="negative" text-color="white" icon="block" label="使用不可" size="sm" />
                </div>

                <q-chip v-if="props.row.isSuperuser" square color="accent" text-color="white" icon="admin_panel_settings"
                  label="システム管理者" size="sm" />
              </div>
            </q-td>
          </template>

          <template v-slot:header-cell-status="p">
            <q-th :props="p">
              <div class="row items-center">
                <label class="q-mr-md">{{ p.col.label }}</label>
                <q-select v-model="statusFilter" :options="statusFilterOptions" borderless
                  dense options-dense style="font-size: 12px; padding-top: 1px;" />
              </div>
            </q-th>
          </template>

          <template v-if="selected && selected.id > 0" v-slot:body-cell-actions="p">
            <q-td auto-width :props="p">
              <table-action-menu :row="p.row" minWidth="180px" max-width="200px" :actions="actionList" />
            </q-td>
          </template>
        </q-table>
      </div>
    </div>


    <show-dialog v-model:visible="showSelectUser" name="ユーザー選択" @close="closeSelectUserDialog" min-width="50vw" min-height="50vh" :ok-btn-auto-close="false" :ok-btn-loading="isAdding">
      <template v-slot:toolbar>
        <q-input dense debounce="300" v-model="dgFilter" placeholder="検索" clearable>
          <template v-slot:before>
            <q-icon name="search" />
          </template>
        </q-input>
      </template>
      <user-select-box ref="userDialog" name="ユーザー" type="single" :filter="dgFilter" :filterInitRowsFunc="filterInitRows" />
    </show-dialog>

    <q-dialog v-model="deleteDialog" persistent>
      <q-card>
        <q-card-section class="row items-center">
          <q-icon name="warning" color="warning" size="2em" />
          <div class="q-ml-sm text-weight-bold">ロールメンバーを削除</div>
        </q-card-section>
        <q-card-section class="q-py-none">
          <!-- <span class="q-ml-sm">この役割を与えられたユーザーは、メンバー役に再配置されます。</span> -->
          <div class="q-mx-sm">ユーザー「{{targetRow?.email}}」を「{{selected?.name}}」の役割から</div>
          <div class="q-mx-sm">本当に外しますか？</div>
        </q-card-section>

        <q-card-actions align="right">
          <q-btn flat label="Cancel" color="primary" v-close-popup />
          <q-btn flat label="OK" color="primary" :loading="deleteUserRoleLoading" @click="deleteUserRole" />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, watch } from 'vue';
import { IRolesDisplay, IUserRolesDisplay } from 'src/types/UserTypes';
import { useUserStore } from 'stores/useUserStore';
import ShowDialog from 'src/components/ShowDialog.vue';
import UserSelectBox from 'src/components/dialog/UserSelectBox.vue';
import TableActionMenu from 'components/TableActionMenu.vue';

const userStore = useUserStore();

const columns = [
  { name: 'id', label: 'ID', field: 'id', align: 'left', sortable: true },
  { name: 'lastName', label: '氏名', field: 'lastName', align: 'left', sortable: true },
  { name: 'firstName', label: '苗字', field: 'firstName', align: 'left', sortable: true },
  { name: 'email', label: '電子メール', field: 'email', align: 'left', sortable: true },
  { name: 'status', label: '状況', field: 'status', align: 'left' },
  { name: 'actions', label: '', field: 'actions', align: 'right' }
];

const statusFilterOptions = [
  { label: '全データ',          filter: () => true },
  { label: 'システム管理者のみ', filter: (row: IUserRolesDisplay) => row.isSuperuser },
  { label: '使用可能',          filter: (row: IUserRolesDisplay) => row.isActive },
  { label: '使用不可',          filter: (row: IUserRolesDisplay) => !row.isActive },
]

const pagination = ref({ sortBy: 'id', descending: true, rowsPerPage: 20 });

const roles = computed(() => {
  if (userStore.roles.length > 0) {
    return userStore.roles.concat(EMPTY_ROLE);
  }
  return userStore.roles;
});

const selected = ref<IRolesDisplay>();

const allLoading = ref(true);
const loading = ref(false);
const filter = ref('');
const statusFilter = ref(statusFilterOptions[0]);
const dgFilter = ref('');

const allUsers = computed(() => userStore.users.filter(statusFilter.value.filter));
const targetRow = ref<IUserRolesDisplay>();

const userDialog = ref();
const showSelectUser=ref(false);
const isAdding = ref(false);
const deleteDialog = ref(false);
const deleteUserRoleLoading = ref(false);

const EMPTY_ROLE: IRolesDisplay = {
  id: -2,
  name: 'ロールなし',
  key: 'dummy',
  level: -1
}

const actionList =  [
  // { label: '移動', icon: 'account_tree', action: toEditFlowPage },
  // { separator: true },
  { label: '削除', icon: 'delete_outline', class: 'text-red', action: removeRow },
];

const rows = computed(() => allUsers.value.filter((item) => {
  if (!selected.value) {
    return false;
  }
  if (selected.value.id == -2) {
    return !item.roles || item.roles.length == 0;
  }
  return item.roleIds?.includes(selected.value.id);
}));
const rowIds = computed(() => new Set(rows.value?.map((item) => item.id)));

const getUsers = async () => {
  loading.value = true;
  await userStore.loadUsers();
  loading.value = false;
}

onMounted(async () => {
  allLoading.value = true;
  await Promise.all([
    userStore.loadRoles(),
    getUsers()
  ]);
  allLoading.value = false;
});

watch(roles, (newRoles) => {
  if (newRoles.length > 0) {
    selected.value = newRoles[0];
  }
});

const roleClicked = async (role: IRolesDisplay) => {
  selected.value = role;
}

const filterInitRows = (user: IUserRolesDisplay) => {
  return !rowIds.value.has(user.id);
}

const showAddRoleDialog = () => {
  showSelectUser.value = true;
  isAdding.value = false;
  dgFilter.value = ''
}

const closeSelectUserDialog = async (val: 'OK'|'Cancel') => {
  showSelectUser.value = true;
  if (val == 'OK' && userDialog.value.selected[0] && selected.value && selected.value.id >= 0) {
      isAdding.value = true;
      await userStore.addRole(userDialog.value.selected[0], selected.value);
      await getUsers();
  }
  showSelectUser.value = false;
  isAdding.value = false;
}

function removeRow(user: IUserRolesDisplay) {
  targetRow.value = user;
  deleteDialog.value = true;
}

const deleteUserRole = async () => {
  if (targetRow.value?.id && selected.value && selected.value.id >= 0) {
    deleteUserRoleLoading.value = true;
    await userStore.removeRole(targetRow.value, selected.value);
    await getUsers();
    deleteUserRoleLoading.value = false;
    deleteDialog.value = false;
  }
}

</script>
<style lang="scss" scoped>
  .menu-active {
    color: white;
    background: var(--q-primary)
  }
</style>