<script setup>

import { ref, useTemplateRef, computed } from 'vue';
import Dialog from './Dialog.vue';
import TextInput from './TextInput.vue';
import PasswordInput from './PasswordInput.vue';
import NumberInput from './NumberInput.vue';
import { uuidv4 } from '../utils.js';

const title = ref('');
const message = ref('');
const type = ref(''); // password, text, number?, email? default text
const confirmStyle = ref('');
const confirmLabel = ref('Yes');
const rejectLabel = ref('No');
const rejectStyle = ref('');
const isPrompt = ref(false);
const isMultiValue = ref(false);
const autoCloseOnConfirm = ref(true);
const value = ref([]);
const required = ref([]);
const placeholder = ref('');
const internalId = ref(uuidv4());
const confirmBusy = ref(false);

const dialog = useTemplateRef('dialog');

let resolver;
let rejecter;

const isFormValid = computed(() => {
  for (const i in value.value) {
    if (required.value[i] && !value.value[i]) return false;
  }

  return true;
});

function reset() {
  message.value = '';
  value.value = [];
  required.value = [];
  type.value = '';
  placeholder.value = '';
  confirmStyle.value = '';
  confirmLabel.value = 'Yes';
  rejectLabel.value = 'No';
  rejectStyle.value = '';
  isPrompt.value = false;
  isMultiValue.value = false;
  autoCloseOnConfirm.value = true;
  confirmBusy.value = false;
}

function info(options) {
  reset();

  isPrompt.value = false;
  isMultiValue.value = false;

  if (options.title) title.value = options.title;
  if (options.message) message.value = options.message;
  if (options.confirmLabel) confirmLabel.value = options.confirmLabel;
  if (options.confirmStyle) confirmStyle.value = options.confirmStyle;
  rejectLabel.value = '';

  dialog.value.open();

  return new Promise((resolve, reject) => {
    resolver = resolve;
    rejecter = reject;
  });
}

function confirm(options) {
  reset();

  isPrompt.value = false;
  isMultiValue.value = false;

  if (options.title) title.value = options.title;
  if (options.message) message.value = options.message;
  if (options.confirmLabel) confirmLabel.value = options.confirmLabel;
  if (options.rejectLabel) rejectLabel.value = options.rejectLabel;
  if (options.confirmStyle) confirmStyle.value = options.confirmStyle;
  if (options.rejectStyle) rejectStyle.value = options.rejectStyle;

  if (typeof options.autoCloseOnConfirm !== 'undefined') autoCloseOnConfirm.value = !!options.autoCloseOnConfirm;

  dialog.value.open();

  return new Promise((resolve, reject) => {
    resolver = resolve;
    rejecter = reject;
  });
}

function prompt(options) {
  reset();

  isPrompt.value = true;
  isMultiValue.value = Array.isArray(options.message);

  value.value = Array.isArray(options.value) ? options.value : [ options.value ];
  required.value = Array.isArray(options.required) ? options.required : [ options.required ];

  if (options.title) title.value = options.title;
  if (options.message) message.value = Array.isArray(options.message) ? options.message : [ options.message ];
  if (options.type) type.value = Array.isArray(options.type) ? options.type : [ options.type ];
  if (options.placeholder) placeholder.value = Array.isArray(options.placeholder) ? options.placeholder : [ options.placeholder ];
  if (options.confirmLabel) confirmLabel.value = options.confirmLabel;
  if (options.rejectLabel) rejectLabel.value = options.rejectLabel;
  if (options.confirmStyle) confirmStyle.value = options.confirmStyle;
  if (options.rejectStyle) rejectStyle.value = options.rejectStyle;

  dialog.value.open();

  setTimeout(() => { document.getElementById(internalId.value+0).focus(); }, 100);

  return new Promise((resolve, reject) => {
    resolver = resolve;
    rejecter = reject;
  });
}

function close() {
  dialog.value.close();
  confirmBusy.value = false;
}

function onConfirmed() {
  if (!isFormValid.value) return;

  const result = isPrompt.value ? (isMultiValue.value ? value.value : value.value[0]) : true;

  resolver(result);

  if (!result || autoCloseOnConfirm.value) {
    dialog.value.close();
  } else {
    confirmBusy.value = true;
  }
}

function onRejected() {
  close();
  resolver(isPrompt.value ? null : false);
}

defineExpose({
  info,
  confirm,
  prompt,
  close,
});

</script>

<template>
  <Dialog ref="dialog" :title="title" :confirm-active="isFormValid" :confirm-busy="confirmBusy" :confirm-label="confirmLabel" :rejectLabel="rejectLabel" :rejectStyle="rejectStyle" :confirmStyle="confirmStyle" @confirm="onConfirmed()" @close="onRejected()" :z-index="2003">
    <div v-if="isPrompt" class="pankow-input-dialog-prompt" v-for="(msg, index) in message">
      <label :for="internalId+index" v-html="msg"></label>
      <PasswordInput :id="internalId+index" v-if="type[index] === 'password'" v-model="value[index]" :placeholder="placeholder[index]" @keydown.enter="onConfirmed()"/>
      <NumberInput :id="internalId+index" v-else-if="type[index] === 'number'" v-model="value[index]" :placeholder="placeholder[index]" @keydown.enter="onConfirmed()"/>
      <TextInput :id="internalId+index" v-else v-model="value[index]" :placeholder="placeholder[index]" @keydown.enter="onConfirmed()"/>
    </div>
    <div v-else v-html="message"></div>
  </Dialog>
</template>

<style>

.pankow-input-dialog-prompt {
  display: flex;
  flex-direction: column;
}

</style>