<template>
  <div class="flex w-full flex-col">
    <ts-normal-text v-if="hasTitle" :customClass="'pb-2'">
      <slot name="title" />
    </ts-normal-text>
    <div class="w-full flex flex-row items-center">
      <slot name="outer-prefix" />
      <div
        :class="`flew-grow w-full space-x-2 flex-row flex items-center justify-between ${padding} ${customClass} ${
          validationStatus
            ? 'focus:!border-primaryPurple'
            : '!border-errorColor'
        } rounded`"
      >
        <slot name="inner-prefix" />
        <input
          v-model="content"
          :placeholder="placeholder"
          :type="type"
          @blur="checkValidation()"
          @keypress="isNumber"
          :class="`flex-grow bg-transparent placeholder-gray-600 focus input w-full focus:outline-none `"
        />
        <slot name="inner-suffix" />
      </div>
      <slot name="outer-suffix" />
    </div>
    <div  v-if="!validationStatus" class="w-full flex flex-row justify-end">
	 <ts-normal-text
     
      :customClass="'pt-1 text-right'"
      :color="`text-errorColor`"
    >
      {{ errorMessage }}
    </ts-normal-text>
	</div>
  </div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import TsNormalText from "../TsTypography/normalText.vue";
import { ref, watch } from "vue";
import { FormRule } from "tutorstack-frontend-logic";

export default defineComponent({
  components: {
    TsNormalText,
  },
  props: {
    padding: {
      type: String,
      default: "py-3 px-3",
    },
    placeholder: {
      type: String,
      default: "",
    },
    customClass: {
      type: String,
      default: "",
    },
    hasTitle: {
      type: Boolean,
      default: false,
    },
    name: {
      type: String,
      default: "",
    },
    type: {
      type: String,
      default: "text",
    },
    rules: {
      type: Object as () => FormRule[],
      required: false,
    },
  },
  name: "TsTextField",
  emits: ["update:modelValue"],
  setup(props: any, context: any) {
    const content = ref("");

    watch(content, () => {
      context.emit("update:modelValue", content.value);
    });

    const validationStatus = ref(true);
    const errorMessage = ref("");

    const isRequired = () => {
      if (content.value) {
        validationStatus.value = true;
      } else {
        validationStatus.value = false;
        errorMessage.value = `${props.name} is required`;
      }
    };

    const isGreaterThan = (count: number) => {
      if (content.value.length > count) {
        validationStatus.value = true;
      } else {
        validationStatus.value = false;
        errorMessage.value = `${props.name} must be more than ${count} characters`;
      }
    };

    const isLessThan = (count: number) => {
      if (content.value.length < count) {
        validationStatus.value = true;
      } else {
        validationStatus.value = false;
        errorMessage.value = `${props.name} must be less than ${count} characters`;
      }
    };

    const isEqualsTo = (count: number) => {
      if (content.value.length == count) {
        validationStatus.value = true;
      } else {
        validationStatus.value = false;
        errorMessage.value = `${props.name} must be ${count} characters`;
      }
    };

    const isCondition = (condition: any, errMsg: string) => {
      if (condition) {
        validationStatus.value = true;
      } else {
        validationStatus.value = false;
        errorMessage.value = errMsg;
      }
    };

    const isGreaterThanOrEqualsTo = (count: number) => {
      if (content.value.length >= count) {
        validationStatus.value = true;
      } else {
        validationStatus.value = false;
        errorMessage.value = `${props.name} must be more than ${
          count - 1
        } characters`;
      }
    };

    const isLessThanOrEqualsTo = (count: number) => {
      if (content.value.length <= count) {
        validationStatus.value = true;
      } else {
        validationStatus.value = false;
        errorMessage.value = `${props.name} must be less than ${
          count + 1
        } characters`;
      }
    };

    const isRegex = (regex: any, errMsg: string) => {
      if (content.value.match(regex)) {
        validationStatus.value = true;
      } else {
        validationStatus.value = false;
        errorMessage.value = errMsg;
      }
    };

    const checkValidation = () => {
      if (props.rules) {
        for (let index = 0; index < props.rules.length; index++) {
          const rule = props.rules[index];
          if (rule.type == "isRequired") {
            isRequired();
          }

          if (rule.type == "isGreaterThan") {
            isGreaterThan(rule.value);
          }

          if (rule.type == "isLessThan") {
            isLessThan(rule.value);
          }

          if (rule.type == "isEqualsTo") {
            isEqualsTo(rule.value);
          }

          if (rule.type == "isGreaterThanOrEqualsTo") {
            isGreaterThanOrEqualsTo(rule.value);
          }

          if (rule.type == "isLessThanOrEqualsTo") {
            isLessThanOrEqualsTo(rule.value);
          }

          if (rule.type == "isRegex") {
            isRegex(rule.value, rule.errorMessage);
          }

          if (rule.type == "isCondition") {
            isCondition(rule.value, rule.errorMessage);
          }
        }
      }
    };

    watch(content, () => {
      checkValidation();
    });

    const isNumber = (evt: any) => {
      if (props.type != "tel") return true;

      evt = evt ? evt : window.event;
      var charCode = evt.which ? evt.which : evt.keyCode;
      if (
        charCode > 31 &&
        (charCode < 48 || charCode > 57) &&
        charCode !== 46
      ) {
        evt.preventDefault();
      } else {
        return true;
      }
    };

    return {
      content,
      checkValidation,
      isNumber,
      errorMessage,
      validationStatus,
    };
  },
});
</script>
