<template>
  <widget-wrapper v-bind="$props" ref="widget" v-slot="{ inputEvents }">
    <InputLabel
      v-if="inputLabel === undefined"
      :label="fieldNode.label ? fieldNode.label : ''"
    />
    <q-input
      class="string-input"
      input-class="string-input__input"
      outlined
      :autogrow="inputType === 'textarea'"
      filled
      :type="inputType"
      :error="hasError"
      :error-message="errorMessage"
      :label="inputLabel"
      :readonly="isReadonly"
      :value="currentValue"
      :maxlength="maxLength"
      :reverseFillMask="reverseFillMask"
      @input="inputEvents.input"
      :clearable="value !== ''"
      :mask="inputMask"
      :rules="maskRule"
    />
  </widget-wrapper>
</template>

<script lang="ts">
import { Component, Prop } from 'vue-property-decorator';
import { mixins } from 'vue-class-component';
import {
  ValidatedField,
  SubscriberWidget,
  createIMaskTokens,
  convertToFormMask,
  InputLabel,
  WidgetWrapper, FormWidget
} from '@devsun/form-generator/dist';
import { Field } from '@devsun/eva-models';

@Component({
  components: {
    WidgetWrapper,
    InputLabel,
  },
})
export default class StringInput extends mixins(
  SubscriberWidget,
  ValidatedField,
  FormWidget,
) {
  @Prop() maxLength?: number;
  @Prop() setDefault?: string;
  @Prop() reverseFillMask?: boolean;

  get isReadonly(): boolean {
    if (this.fieldNode.simlink) {
      return true;
    }
    return this.fieldNode.readonly;
  }

  // todo NumberInput component
  get inputType(): string {
    switch (this.fieldNode.rawAttrs.view) {
      case Field.View.textarea:
        return 'textarea';
      case Field.View.integer:
        return 'number';
      case Field.View.float:
        return 'number';
      default:
        return 'text';
    }
  }

  get currentValue(): string {
    if (this.fieldNode.simlink) {
      let simlinkValue: any = 'this.simlinkValue';
      if (Array.isArray(simlinkValue)) {
        if (simlinkValue.length > 1) {
          console.error('multiple values for simlink value not supported yet');
        }
        simlinkValue = simlinkValue[0];
      }
      if (simlinkValue === void 0 || simlinkValue === null) {
        return '';
      }
      if (typeof simlinkValue !== 'string') {
        console.error(
          '[StringInput] simlinkValue is not a string for ',
          this.fieldNode.fieldName,
          simlinkValue
        );
        simlinkValue = simlinkValue.toString();
      }
      return simlinkValue;
    }
    if (this.value && Array.isArray(this.value.__id)) {
      return this.value.__id[0];
    }
    this.value.__id && (this.value.__id = this.value.__id.trim());
    this.value.content && (this.value.content = this.value.content.trim());
    return this.value ? (this.value.__id as string) : '';
  }

  get inputMask() {
    return this.maskConfig?.type === 'mask' ? this.maskConfig?.mask : '';
  }

  get maskRule() {
    if (this.maskConfig?.type === 'regexp') {
      const validateRule = (val) => {
        const pattern = new RegExp(this.maskConfig?.mask);
        return (val ? pattern.test(val) : true) || 'Invalid format';
      };
      return [validateRule];
    } else {
      return [];
    }
  }

  get maskConfig() {
    if (this.fieldNode.props?.customMask) {
      return {
        type: 'regexp',
        mask: convertToFormMask(this.fieldNode.props.customMask).value,
      };
    } else if (this.fieldNode.masks?.length > 0) {
      const mask = this.fieldNode.masks[this.fieldNode.masks.length - 1];
      if (mask.regexp) {
        return {
          type: 'regexp',
          mask: mask.value,
        };
      }
      return {
        type: 'mask',
        definitions: createIMaskTokens(),
        mask: mask.value,
        lazy: false,
      };
    } else {
      return null;
    }
  }

  get inputLabel() {
    return this.fieldNode.rawAttrs.props?.isLabelAbove
      ? undefined
      : this.fieldNode.label ?? '';
  }

  mounted(): void {
    this.setDefaultValue();
  }

  setDefaultValue(): void {
    if (this.setDefault === undefined || this.value.__id) return;

    this.$refs.widget?.inputEvents?.input(this.setDefault);
  }
}
</script>

<style>
.string-input {
  margin-top: 12px;
  padding-bottom: 20px;
}

.string-input__input::-webkit-scrollbar {
  display: none;
}
</style>
