<script setup>

import { ref, useTemplateRef } from 'vue';
import { Dialog, TextInput, FormGroup, MultiSelect } from '@cloudron/pankow';
import UsersModel from '../models/UsersModel.js';
import GroupsModel from '../models/GroupsModel.js';
import AppsModel from '../models/AppsModel.js';

const usersModel = UsersModel.create();
const groupsModel = GroupsModel.create();
const appsModel = AppsModel.create();

const emit = defineEmits([ 'success' ]);

const dialog = useTemplateRef('dialog');

// also determines if new or edit mode
const group = ref(null);
const busy = ref(false);
const formError = ref({});
const name = ref('');
const userIds = ref([]);
const allUsers = ref([]);
const appIds = ref([]);
const allApps = ref([]);

async function onSubmit() {
  busy.value = true;
  formError.value = {};

  if (group.value) {
    const [error] = await groupsModel.update(group.value.id, name.value, userIds.value, appIds.value);
    if (error) {
      if (error.body && error.body.message.indexOf('name') === 0) formError.value.name = error.body.message;
      else formError.value.generic = error.body ? error.body.message : 'Internal error';
      busy.value = false;
      return console.error(error);
    }
  } else {
    const [error] = await groupsModel.add(name.value, userIds.value, appIds.value);
    if (error) {
      if (error.body && error.body.message.indexOf('name') === 0) formError.value.name = error.body.message;
      else formError.value.generic = error.body ? error.body.message : 'Internal error';
      busy.value = false;
      return console.error(error);
    }
  }

  emit('success');
  dialog.value.close();
  busy.value = false;
}

defineExpose({
  async open(g = null) {
    g = g ? JSON.parse(JSON.stringify(g)) : null; // make a copy
    group.value = g;
    name.value = g ? g.name : '';
    formError.value = {};
    busy.value = false;

    let [error, result] = await usersModel.list();
    if (error) return console.error(error);
    result.forEach(u => u.label = (u.username || u.email));
    allUsers.value = result;
    userIds.value = g ? g.userIds : [];

    [error, result] = await appsModel.list();
    if (error) return console.error(error);
    result.forEach(a => a.label = (a.label || a.fqdn));
    allApps.value = result;
    appIds.value = g ? g.appIds : [];

    dialog.value.open();
  }
});

</script>

<template>
  <Dialog ref="dialog"
    :title="group ? $t('users.editGroupDialog.title') : $t('users.addGroupDialog.title')"
    :confirm-label="group ? $t('main.dialog.save') : $t('users.group.addGroupAction')"
    :confirm-busy="busy"
    :confirm-active="!busy && name !== ''"
     reject-style="secondary"
    :reject-label="$t('main.dialog.cancel')"
    :reject-active="!busy"
    @confirm="onSubmit()"
  >
    <p class="text-warning" v-if="group?.source">{{ $t('users.editGroupDialog.externalLdapWarning') }}</p>
    <form @submit.prevent="onSubmit()" autocomplete="off">
      <fieldset :disabled="busy">
        <input type="submit" style="display: none;" />

        <div class="error-label" v-if="formError.generic">{{ formError.generic }}</div>

        <FormGroup>
          <label for="nameInput">{{ $t('users.group.name') }}</label>
          <TextInput id="nameInput" v-model="name" required/>
          <div class="error-label" v-if="formError.name">{{ formError.name }}</div>
        </FormGroup>

        <FormGroup>
          <label for="usersInput">{{ $t('users.group.users') }}</label>
          <!-- membership of external groups cannot be edited -->
          <div v-if="group?.source"><span v-for="userId of userIds" :key="userId" style="padding-right: 5px">{{ allUsers.find(u => u.id === userId)?.username || allUsers.find(u => u.id === userId)[userId]?.email }}</span></div>
          <MultiSelect v-else v-model="userIds" :options="allUsers" option-key="id" :search-threshold="20"/>
        </FormGroup>

        <FormGroup>
          <label for="appsInput">{{ $t('users.group.allowedApps') }}</label>
          <MultiSelect v-model="appIds" :options="allApps" option-key="id" :search-threshold="20"/>
        </FormGroup>
      </fieldset>
    </form>
  </Dialog>
</template>
