<template>
  <div class="btn-submit" :class="{ 'btn-group': !!dropdownItems }">
    <button :class="buttonClass" :disabled="isDisabled" @click="performAction(action)" accesskey="S" title="Alt + S">
      <span v-if="!validatorGroup"><code>submit</code> needs to be used inside <code>validator-group</code>!</span>
      <slot>Versturen</slot>
    </button>

    <dropdown-menu
      v-if="dropdownItems && dropdownItems.length"
      :disabled="isDisabled"
      :buttonClass="buttonClass + ' dropdown-toggle-split'"
    >
      <button
        type="button"
        v-for="dropdownItem in dropdownItems"
        :key="dropdownItem.label"
        @click="performAction(dropdownItem.action)"
        class="dropdown-item"
      >
        {{ dropdownItem.label }}
      </button>
    </dropdown-menu>
  </div>
</template>

<script lang="ts">
import { Component, Mixins, Prop } from 'vue-property-decorator';
import { ValidatorMixin } from './validator-mixin';
import { ValidatorGroup } from '../../types/validators';
import { SubmitDropdownItemsModel } from '../../types/submit';

@Component
export default class Submit extends Mixins(ValidatorMixin) {
  // docs: `Submit button. Gebruiken binnen een <code>validator-group</code>. Wordt gedisabled als er validatie-errors zijn.`,

  @Prop({ type: String, default: 'btn btn-primary' }) readonly buttonClass!: string;
  @Prop(Function) readonly action!: Promise<void>;
  @Prop({ default: false }) readonly disabled!: boolean;
  @Prop(Array) readonly dropdownItems: SubmitDropdownItemsModel[] | undefined;

  validatorGroup: ValidatorGroup | null = null;
  actionRunning = false;

  get isDisabled() {
    return this.disabled || (this.validatorGroup && !this.validatorGroup.isValid) || this.actionRunning;
  }

  created() {
    this.getAndSetValidatorGroup();
  }

  getAndSetValidatorGroup() {
    // can only be done by events, because <validator-group> doesn't need to be the parent of this <submit>
    if (this.validatorEventBus) {
      this.validatorEventBus.$emit('needs-validator-group', (vg) => (this.validatorGroup = vg));
    }
  }

  performAction(action) {
    const promise = action();
    if (!promise || !promise.then) {
      console.warn('The action function of a submit button should return a Promise.');
      return;
    }
    this.actionRunning = true;
    promise.then(
      () => (this.actionRunning = false),
      () => (this.actionRunning = false)
    );
  }
}
</script>

<style lang="scss">
// can't use 'scoped' here unfortunately
.btn-submit {
  &:not(.btn-group) {
    display: inline-block;
  }

  .btn-block & {
    display: block;
  }

  .dropdown-toggle {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;

    &::after {
      margin-left: 0;
    }
  }

  .dropdown-menu {
    bottom: 100%;
    top: auto;
    left: auto;
    right: 0;
  }
}
</style>
