<template>
  <q-dialog :auto-close="false" :model-value="visible" persistent bordered>
    <q-card class="dialog-content" >
      <q-toolbar class="bg-grey-4">
        <q-toolbar-title>「{{domain.name}}」のドメイン利用権限設定</q-toolbar-title>
        <q-btn flat round dense icon="close" @click="close" />
      </q-toolbar>

      <q-card-section class="q-mx-md " >
        <q-select
          class="q-mt-md"
          :disable="loading||!domain.domainActive"
          filled
          dense
          v-model="canSharedUserFilter"
          use-input
          input-debounce="0"
          :options="canSharedUserFilteredOptions"
          clearable
          :placeholder="canSharedUserFilter ? '' : domain.domainActive ? '権限を付与するユーザーを選択' : 'ドメインが無効なため、権限を付与できません'"
          @filter="filterFn"
          :display-value="canSharedUserFilter?`${canSharedUserFilter.fullName} （${canSharedUserFilter.email}）`:''">

          <template v-slot:after>
            <q-btn :disable="!canSharedUserFilter" :loading="addLoading" label="付与" color="primary" @click="shareTo(canSharedUserFilter as IUserDisplay)" />
          </template>

          <template v-slot:option="scope">
            <q-item v-bind="scope.itemProps">
              <q-item-section avatar>{{scope.opt.id}}</q-item-section>
              <q-item-section>{{scope.opt.fullName}}</q-item-section>
              <q-item-section>{{scope.opt.email}}</q-item-section>
            </q-item>
          </template>
        </q-select>
        <sharing-user-list class="q-mt-md" style="height: 330px" :users="sharedUsers" :loading="loading" title="ドメイン利用権限を持つユーザー">
          <template v-slot:actions="{ row }">
            <q-btn title="解除" flat color="primary" padding="xs" size="1em" :loading="row.id == removingUser?.id" icon="person_off" @click="removeShareTo(row)" />
          </template>
        </sharing-user-list>
      </q-card-section>

      <q-card-actions align="right" class="text-primary">
        <q-btn flat label="確定" @click="checkClose" />
        <q-btn flat label="キャンセル" @click="close" />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

<script setup lang="ts">
import { ref, watch, onMounted } from 'vue';
import { IDomainOwnerDisplay } from '../../types/DomainTypes';
import { IUser, IUserDisplay } from '../../types/UserTypes';
import { api } from 'boot/axios';
import SharingUserList from 'components/ShareDomain/SharingUserList.vue';
import { Dialog } from 'quasar'

interface Props {
  modelValue: boolean;
  domain: IDomainOwnerDisplay;
}

interface IUserDisplayWithShareRole extends IUserDisplay {
  role: number;
}

const props = defineProps<Props>();

const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void;
  (e: 'close'): void;
}>();

const addLoading = ref(false);
const removingUser = ref<IUserDisplayWithShareRole>();
const loading = ref(true);
const visible = ref(props.modelValue);

const allUsers = ref<IUserDisplayWithShareRole[]>([]);
const sharedUsers = ref<IUserDisplayWithShareRole[]>([]);
const sharedUsersIdSet = new Set<number>();

const canSharedUsers = ref<IUserDisplayWithShareRole[]>([]);
const canSharedUserFilter = ref<IUserDisplayWithShareRole>();
const canSharedUserFilteredOptions = ref<IUserDisplayWithShareRole[]>([]);

const filterFn = (val:string, update: (cb: () => void) => void) => {
  update(() => {
    if (val === '') {
      canSharedUserFilteredOptions.value = canSharedUsers.value;
      return;
    }
    const needle = val.toLowerCase();
    canSharedUserFilteredOptions.value = canSharedUsers.value.filter(v =>
      v.email.toLowerCase().indexOf(needle) > -1 || v.fullNameSearch.toLowerCase().indexOf(needle) > -1);
  })
}

watch(
  () => props.modelValue,
  async (newValue) => {
    visible.value = newValue;
    sharedUsers.value = [];
    canSharedUserFilter.value = undefined
    loading.value = false;
    addLoading.value = false;
    if (newValue) {
      await loadShared();
    }
  }
);

watch(
  () => visible.value,
  (newValue) => {
    emit('update:modelValue', newValue);
  }
);

const checkClose = () => {
  if (!canSharedUserFilter.value) {
    close();
    return;
  }
  Dialog.create({
    title: '注意',
    message: '選択済だがまだ付与未完了のユーザーがあります。<br>必要な操作を選んでください。',
    html: true,
    persistent: true,
    ok: {
      color: 'primary',
      label: '付与'
    },
    cancel: '直接閉じる',
  }).onCancel(() => {
    close();
  }).onOk(() => {
    shareTo(canSharedUserFilter.value as IUserDisplayWithShareRole);
  });
};

const close = () => {
  emit('close');
};

const shareTo = async (user: IUserDisplayWithShareRole) => {
  addLoading.value = true;
  loading.value = true;
  await api.post(`api/userdomain`, {
    'userid': user.id,
    'domainid': props.domain.id
  })
  await loadShared();
  canSharedUserFilter.value = undefined;
  loading.value = false;
  addLoading.value = false;
}

const removeShareTo = async (user: IUserDisplayWithShareRole) => {
  removingUser.value = user;
  loading.value = true;
  await api.delete(`api/domain/${props.domain.id}/${user.id}`)
  await loadShared();
  loading.value = false;
  removingUser.value = undefined;
};

const loadShared = async () => {
  loading.value = true;
  sharedUsersIdSet.clear();

  const { data } = await api.get(`/api/domainshareduser/${props.domain.id}`);
  sharedUsers.value = data.data.map((item: IUser) => {
    const val = itemToDisplay(item);
    sharedUsersIdSet.add(val.id);
    return val;
  });

  canSharedUsers.value = allUsers.value.filter((item) => !sharedUsersIdSet.has(item.id));
  canSharedUserFilteredOptions.value = canSharedUsers.value;

  loading.value = false;
}

onMounted(async () => {
  await getUsers();
})

const getUsers = async () => {
  if (Object.keys(allUsers.value).length > 0) {
    return;
  }
  loading.value = true;
  const result = await api.get(`api/v1/users`);
  allUsers.value = result.data.data.map(itemToDisplay);
  loading.value = false;
}

const itemToDisplay = (item: IUser) => {
  return {
    id: item.id,
    firstName: item.first_name,
    lastName: item.last_name,
    fullNameSearch: (item.last_name + item.first_name).toLowerCase(),
    fullName: item.last_name + ' ' + item.first_name,
    email: item.email,
    isSuperuser: item.is_superuser,
    isActive: item.is_active,
    role: 0, // TODO
  } as IUserDisplayWithShareRole
}
</script>

<style lang="scss">
.dialog-content {
  width: 700px !important;
  max-width: 80vw !important;
  max-height: 80vh;
  .q-select {
    min-width: 0 !important;
  }
}

</style>
