<template>
  <div class="flex w-full flex-col space-y-2">
    <ts-normal-text>
      <slot name="title" />
    </ts-normal-text>
    <textarea
      :rows="rows"
      v-model="content"
      :class="`focus:outline-none border-[1px] resize-none border-gray-200 ${
        validationStatus ? 'focus:!border-primaryPurple' : '!border-errorColor'
      } rounded ${padding} placeholder-slate-500`"
      :placeholder="placeholder"
      @blur="checkValidation()"
    >
    </textarea>
    <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 TsNormalText from "../TsTypography/normalText.vue";
import { onMounted, ref, watch } from "vue";
import { FormRule } from "tutorstack-frontend-logic";

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

    onMounted(() => {
      if (props.modelValue) {
        content.value = props.modelValue;
      }
    });

    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();
      context.emit("update:modelValue", content.value);
    });

    const showError = (message: string) => {
      validationStatus.value = false;
      errorMessage.value = message;
    };

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