import { Component, Prop, Vue } from 'vue-property-decorator';
import TextInput from './text/index.vue';
import { BaseInput, InputType } from './base';
import PasswordInput from './password/index.vue';
import EmailInput from './email/index.vue';

const inputComponentsMap: { [key in InputType]: typeof Vue } = {
  text: TextInput,
  password: PasswordInput,
  email: EmailInput,
};

@Component({
  components: { TextInput },
})
export default class RInput extends BaseInput {
  @Prop({ type: String, default: 'text' }) public readonly type!: InputType;
  @Prop({ type: Array, default: () => [] }) public readonly rules!: Array<
    (val: string) => boolean | string
  >;

  @Prop({ type: Boolean, default: false })
  public readonly validateOnBlur!: boolean;

  public isValid = true;
  public errorMessage = '';

  get hasError(): boolean {
    return !this.isValid;
  }

  get component(): any {
    return inputComponentsMap[this.type];
  }

  public validate(): void {
    // @ts-ignore
    const currentValue = this.$refs.component.$refs.input.value;

    this.isValid = this.rules.every((rule) => {
      const result = rule(currentValue);
      if (typeof result === 'string') {
        this.errorMessage = result;
        return false;
      } else {
        return result;
      }
    });

    if (this.isValid) {
      this.errorMessage = '';
    }
  }

  public onBlur(): void {
    if (this.validateOnBlur) {
      this.validate();
    }
  }

  public onInput(event: Event): void {
    const target = event.target as HTMLInputElement;
    const value = target.value;
    this.validate();
    this.$emit('input', value);
  }
}
