<script setup>

import { useI18n } from 'vue-i18n';
const i18n = useI18n();
const t = i18n.t;

import { ref, useTemplateRef } from 'vue';
import { Dialog, FormGroup, InputDialog, MultiSelect, Radiobutton, TagInput, TextInput } from '@cloudron/pankow';
import { API_ORIGIN } from '../constants.js';
import { getDataURLFromFile } from '../utils.js';
import ImagePicker from './ImagePicker.vue';
import ApplinksModel from '../models/ApplinksModel.js';
import UsersModel from '../models/UsersModel.js';
import GroupsModel from '../models/GroupsModel.js';

const applinksModel = ApplinksModel.create();
const usersModel = UsersModel.create();
const groupsModel = GroupsModel.create();

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

const imagePicker = useTemplateRef('imagePicker');
const applinkDialog = useTemplateRef('applinkDialog');
const inputDialog = useTemplateRef('inputDialog');
const users = ref([]);
const groups = ref([]);
const busy = ref(false);
const error = ref({});
const mode = ref('');
const id = ref('');
const upstreamUri = ref('');
const label = ref('');
const tags = ref([]);
const iconUrl = ref('');
const accessRestrictionOption = ref('');
const accessRestriction = ref({
  users: [],
  groups: [],
});

let iconFile = 'src';
function onIconChanged(file) {
  iconFile = file;
}

const form = useTemplateRef('form');
const isFormValid = ref(false);
function checkValidity() {
  isFormValid.value = form.value ? form.value.checkValidity() : false;

  if (isFormValid.value) {
    try {
      new URL(upstreamUri.value);
      // eslint-disable-next-line no-unused-vars
    } catch (e) {
      isFormValid.value = false;
    }
  }
}

async function onSubmit() {
  if (!form.value.reportValidity()) return;

  busy.value = true;

  const data = {
    upstreamUri: upstreamUri.value,
    tags: tags.value,
  };

  if (label.value) data.label = label.value;

  data.accessRestriction = null;
  if (accessRestrictionOption.value === 'groups') {
    data.accessRestriction = { users: [], groups: [] };
    data.accessRestriction.users = accessRestriction.value.users;
    data.accessRestriction.groups = accessRestriction.value.groups;
  }

  if (iconFile === 'fallback') { // user reset the icon
    data.icon = '';
  } else if (iconFile !== 'src') { // user loaded custom icon
    data.icon = (await getDataURLFromFile(iconFile)).replace(/^data:image\/[a-z]+;base64,/, '');
  }

  let error;
  if (mode.value === 'edit') [error] = await applinksModel.update(id.value, data);
  else [error] = await applinksModel.add(data);

  if (error) {
    busy.value = false;
    return console.error(error);
  }

  emits('success');
  applinkDialog.value.close();

  busy.value = false;
}

async function onRemove() {
  const yes = await inputDialog.value.confirm({
    message: `Really remove applink?`,
    confirmStyle: 'danger',
    confirmLabel: t('main.action.remove'),
    rejectLabel: t('main.dialog.cancel'),
    rejectStyle: 'secondary'
  });

  if (!yes) return;

  const [error] = await applinksModel.remove(id.value);
  if (error) return console.error(error);

  emits('success');
  applinkDialog.value.close();
}

defineExpose({
  open: async function (applink) {
    mode.value = applink ? 'edit' : 'new';
    id.value = applink ? applink.id : '';
    upstreamUri.value = applink ? applink.upstreamUri : '';
    label.value = applink ? applink.label : '';
    iconUrl.value = applink ? applink.iconUrl : 'fallback';
    iconFile = applink?.iconUrl ? 'src' : 'fallback';
    tags.value = applink ? applink.tags : [];
    accessRestrictionOption.value = applink && applink.accessRestriction ? 'groups' : 'any';
    accessRestriction.value = applink && applink.accessRestriction ? applink.accessRestriction : { users: [], groups: [] };

    // fetch users and groups
    let [error, result] = await usersModel.list();
    if (error) return console.error(error);
    result.forEach(u => { u.label = u.username || u.email; });
    users.value = result;

    [error, result] = await groupsModel.list();
    if (error) return console.error(error);
    groups.value = result;

    applinkDialog.value.open();

    setTimeout(checkValidity, 100); // update state of the confirm button
  }
});

</script>

<template>
  <Dialog ref="applinkDialog"
    :title="mode === 'edit' ? $t('app.editApplinkDialog.title') : $t('app.addApplinkDialog.title')"
    :alternate-label="mode === 'edit' ? 'Delete' : ''"
     alternate-style="danger"
    :reject-label="$t('main.dialog.cancel')"
     reject-style="secondary"
    :confirm-label="mode === 'edit' ? $t('main.dialog.save') : $t('main.action.add')"
    :confirm-active="!busy && isFormValid"
    :confirm-busy="busy"
    @confirm="onSubmit()"
    @alternate="onRemove()"
  >
    <InputDialog ref="inputDialog" />

    <form @submit.prevent="onSubmit()" autocomplete="off" ref="form" @input="checkValidity()">
      <fieldset :disabled="busy">
        <input style="display: none;" type="submit" />

        <p class="has-error" v-show="error.generic">{{ error.generic }}</p>

        <FormGroup :class="{ 'has-error': error.upstreamUri }">
          <label for="applinkUpstreamUri">{{ $t('app.applinks.upstreamUri') }}</label>
          <TextInput id="applinkUpstreamUri" v-model="upstreamUri" required />
          <span class="text-danger" v-show="error.upstreamUri">{{ error.upstreamUri }}</span>
        </FormGroup>

        <FormGroup>
          <label for="applinkLabel">{{ $t('app.applinks.label') }}</label>
          <TextInput id="applinkLabel" v-model="label" />
        </FormGroup>

        <div>
          <label>{{ $t('app.display.icon') }}</label>
          <ImagePicker ref="imagePicker" mode="simple" :src="iconUrl" :fallback-src="`${API_ORIGIN}/img/appicon_fallback.png`" @changed="onIconChanged" :size="512" display-height="80px" style="width: 80px"/>
        </div>

        <FormGroup>
          <label for="applinkTags">{{ $t('app.display.tags') }}</label>
          <TagInput id="applinkTags" v-model="tags" v-tooltip="$t('app.display.tagsTooltip')" />
          <small class="helper-text">{{ $t('app.display.tagsPlaceholder') }}</small>
        </FormGroup>

        <FormGroup>
          <label>{{ $t('app.accessControl.userManagement.dashboardVisibility') }} <sup><a href="https://docs.cloudron.io/apps/#no-sso" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
          <Radiobutton v-model="accessRestrictionOption" value="any" :label="$t('app.accessControl.userManagement.visibleForAllUsers')"/>
          <Radiobutton v-model="accessRestrictionOption" value="groups" :label="$t('app.accessControl.userManagement.visibleForSelected')"/>
          <!-- <span class="label label-danger"v-show="accessRestrictionOption === 'groups' && !isAccessRestrictionValid(applinkDialogData)">{{ $t('appstore.installDialog.errorUserManagementSelectAtLeastOne') }}</span> -->
        </FormGroup>

        <div v-if="accessRestrictionOption === 'groups'">
          <div style="margin-left: 20px; display: flex;">
            <div>
              {{ $t('appstore.installDialog.users') }}: <MultiSelect v-model="accessRestriction.users" :options="users" option-key="id" option-label="label" :search-threshold="20" />
            </div>
            <div>
              {{ $t('appstore.installDialog.groups') }}: <MultiSelect v-model="accessRestriction.groups" :options="groups" option-key="id" option-label="name" :search-threshold="20" />
            </div>
          </div>
        </div>
      </fieldset>
    </form>
  </Dialog>
</template>
