import { CONSTANT } from "./constants";

class Utils  {
    public getType = (dialect, dbType) => {
        if (dialect === "mssql") return CONSTANT.MSSQL_DATATYPES_MAP[dbType];
        else if (dialect === "mysql") {
            let lowerCaseDbType = dbType.toLowerCase();
            if (lowerCaseDbType.startsWith("int") || lowerCaseDbType.startsWith("bigint") || lowerCaseDbType.indexOf("decimal") > -1) return "number";
            else if (lowerCaseDbType.startsWith("longtext") || lowerCaseDbType.startsWith("varchar") || lowerCaseDbType.startsWith("nvarchar") || lowerCaseDbType.startsWith("mediumtext") || lowerCaseDbType.startsWith("shorttext")) return "string";
            else if (lowerCaseDbType.indexOf("date") > -1 || lowerCaseDbType.indexOf("time") > -1) return "Date";
            else if (lowerCaseDbType.indexOf("tinyint") > -1 || lowerCaseDbType.indexOf("bit") > -1) return "boolean";
            else {
                console.log("Type not registered (please make PR and add this property): ", dbType);
            }
        }
    }

    public isTableAllowed = (tableName, skipTables) => {
        const matches = skipTables.filter((skipTable) => skipTable === tableName);

        return matches.length ? false : true;
    }

    public isLookup = (propertyName, lookup) => {

        if (lookup && lookup.tableName && lookup.identifier) {
            if (propertyName.includes(lookup.identifier)) return true;
        }

        return false;
    }
    /***
     * if start, slice out start; if end, slice out end. if nothing happens, send back propertyName + "_alias";
     */
    public makeLookupPropName = (propertyName, lookup) => {
        return propertyName.replace(lookup.sliceOut, "")
    }

    public makeLookupPropName_v1 = (propertyName, lookup) => {
        let ret = propertyName;

        let startLen = lookup.start.length;
        let endIndex = propertyName.indexOf(lookup.end);
        
        if (endIndex > -1) {

            if (lookup.start && endIndex > -1) {
                ret = propertyName.slice(startLen);
            }

            if (lookup.end && endIndex > -1) {
                ret = propertyName.slice(0, endIndex);
            }
        }

        // return ret === propertyName ? this.lowerCase(ret + "Object") : this.lowerCase(ret);
        return ret === propertyName ? this.lowerCaseFirstLetter(ret.slice(0, ret.length - 3)) : this.lowerCaseFirstLetter(ret);
    }

    public pluralize = (modelName: string) => {
        const lastChar = modelName.charAt(modelName.length - 1);
        const specialPlurlizeCase = CONSTANT.SPECIAL_PLURALIZE_CASES[modelName.toLowerCase()];

        if (specialPlurlizeCase) {
            modelName = specialPlurlizeCase;
        } else if (lastChar === "y") {
            modelName = modelName.slice(0, modelName.length - 1) + "ies";
        } else if (lastChar === "s") {
            modelName += "es";
        } else {
            modelName += "s";
        }

        return this.lowerCaseFirstLetter(modelName);
    }

    public lowerCaseFirstLetter = (value: string) => {
        const lowerCaseFirstChar = value.charAt(0).toLowerCase();
        
        return lowerCaseFirstChar + value.slice(1);
    }

    public capitalizeFirstLetter(value: string) {
        return  value.charAt(0).toUpperCase() + value.slice(1);
    }

    public isMapTable = (tableName: string, mapTableIdentifiers: Array<string>) => {
        let ret = false;

        if (mapTableIdentifiers.length) {
            const matches = mapTableIdentifiers.filter((x) => tableName.indexOf(x) > -1);

            if (matches.length === mapTableIdentifiers.length) ret = true;
        }

        return ret;
    }

    public isPrimaryKey = (property, isPrimaryKey, primaryKeyIdentifier) => {
        let ret = false;
        
        if (primaryKeyIdentifier) {
            if (property === primaryKeyIdentifier) ret = true;
        } else {
            ret = isPrimaryKey;
        }

        return ret;
    }

    // public createModelName = (name) => {
    //     return name + "Model";
    // }

}

export default new Utils();