import {includes, isEmpty, nth, split, trim} from "lodash";
import {INVALID_EMPTY, INVALID_SEPARATOR_FORMAT, INVALID_VALUE_FORMAT} from "../constants/messages";

export default  class ItemsValidator {
    static isValidBrackets(str: string) {
        const stack = [];
        const bracketMap: Record<string, string> = {
            ')': '(',
            ']': '[',
            '}': '{',
        };
        const bracketList = ['(', ')', '[', ']', '{', '}'];
        for (const char of str) {
            if (bracketList.includes(char)) {
                if (stack.length > 0 && bracketMap[char] === stack[stack.length - 1]) {
                    stack.pop();
                } else {
                    stack.push(char);
                }
            }
        }
        return stack.length === 0;
    }


    static isValidExpToParse(text: string) {
        if (isEmpty(trim(text)) || trim(text)?.length < 5) {
            return false;
        }

        if (text.match(/[+\-*,\/]\s*$/g) || text.match(/^\s*[*\/]/g)) {
            return false;
        }

        if (text.match(/[*+\-/][+*\-/]/)) {
            return false;
        }

        if (!text.match(/[a-zA-Z\u0430-\u044f]/)) {
            if (text.match(/\s*[-,+]\s*$/)) {
                return false;
            }

            if (!text.match(/([\w)][*+-/][(\w])/g)) {
                return false;
            }

            if (text.replace(/\s*([+-/])\s*/g, '$1').match(/([^\d)][-*+/][^(\d])/g)) {
                return false;
            }
        } else {
            if (!text.match(/[\w'`\\\/\u0430-\u044f\s.,\]\[]+\s*-\s*[\d()\]\[+\/*\-]+\s*\n*/g)) {
                return false;
            }
        }

        if (!ItemsValidator.isValidBrackets(text)) {
            return false;
        } else if (text.match(/\(/g)) {
            if (!text.match(/(\([\d+\-*/]{3,}\))|(\[[\d,+\-*/]+])/g)) {
                return false;
            } else if (text.match(/([^+\-/*\s]\s*\()|(\)\s*[^+\-/*\n\s])/g)) {
                return false;
            }
        } else if (text.match(/\[/g) && !text.match(/\[[\d,\s]+]/g)) {
            return false;
        }
        return true;
    }

    static getInvalidMessage(text: string) {
        if (isEmpty(trim(text)) || text.match(/\s*\+\s*$/)) {
            return INVALID_EMPTY;
        }
        if (!includes(text, '-')) {
            return INVALID_SEPARATOR_FORMAT;
        }
        const splitted = split(text, '-');
        const value = nth(splitted, 1);
        if (!value || (value && !/\d+/g.test(value))) {
            return INVALID_VALUE_FORMAT;
        }

        return undefined;
    }
}