import { AddressInfo } from "../models";

export class StringUtils {
  static compare(aval: string, bval: string) {
    return aval ? aval.localeCompare(bval) : -1;
  }

  // Sorting function for SemVer
  // Returns 1 if a is greater, -1 if b is greater, 0 if equal
  public static compareSemVer(a: string, b: string): number {
    if (a === b) {
      return 0;
    }

    var a_components = a.split(".");
    var b_components = b.split(".");

    var len = Math.min(a_components.length, b_components.length);

    // loop while the components are equal
    for (var i = 0; i < len; i++) {
      // A bigger than B
      if (parseInt(a_components[i]) > parseInt(b_components[i])) {
        return 1;
      }

      // B bigger than A
      if (parseInt(a_components[i]) < parseInt(b_components[i])) {
        return -1;
      }
    }

    // If one's a prefix of the other, the longer one is greater.
    if (a_components.length > b_components.length) {
      return 1;
    }

    if (a_components.length < b_components.length) {
      return -1;
    }

    // Otherwise they are the same.
    return 0;
  }

  public static isNullOrWhitespace(input: string): boolean {
    return !input || !input.trim();
  }

  public static getTrimmedValue(input: string, emptyFormat: string = ''): string {
    if (input) {
      input = input.trim();
    }
    if (input) return input;
    return emptyFormat;
  }

  public static removeNewLines(input: string): string {
    if (input) {
      input = input.replace(/[\r\n]+/g, '');
    }
    return input;
  }

  public static firstIsVowel(s: string): boolean {
    if (s) {
      return ['a', 'e', 'i', 'o', 'u'].indexOf(s[0].toLowerCase()) !== -1
    }
    return false;
  }

  public static makeCommaSeparatedString(arr: string[], useOxfordComma: boolean,
    conjunctionWord: string = "and") {
    arr = arr.filter(s => s);
    const listStart = arr.slice(0, -1).join(', ');
    const listEnd = arr.slice(-1);
    const conjunction =
      arr.length <= 1
        ? ""
        : useOxfordComma && arr.length > 2
          ? `, ${conjunctionWord} `
          : ` ${conjunctionWord} `;

    return [listStart, listEnd].join(conjunction);
  }



  public static getFormattedTerm(input: string, emptyFormatter: string = 'Empty'): string {
    if (false == this.isNullOrWhitespace(input)) {
      return input.trim();
    }
    return emptyFormatter;
  }
  public static camelToTitle(camelCase: string): string {
    // no side-effects
    return camelCase
      // inject space before the upper case letters
      .replace(/([A-Z])/g, function (match) {
        return " " + match;
      })
      // replace first char with upper case
      .replace(/^./, function (match) {
        return match.toUpperCase();
      }).trim();
  }
  public static getCapitalLetters(str: string) {
    return str.replace(/[^A-Z]+/g, "");
  }

  /**
   * status could be `info` , `primary` , `danger` , `warning` , `success`
   */
  public static getHtmlBadge(text: string, badgeStatus: string, mergingClass = 'mr-1') {
    return `<label class="badge badge-${badgeStatus} ${mergingClass} my-0 py-1">${text}</label>`;

  }

  public static getHtmlInnerText(htmlText: string) {
    return htmlText ? htmlText.replace(/<[^>]+>/g, '') : '';


  }

  /**
   * Try to parse city sate zip string like `Monrovia, CA  91016` to AddressInfo, if failed will return `null` instead.
   */
  public static tryParseCityStateZip(cityStateZip: string): AddressInfo {

    let addressInfo = {} as AddressInfo;
    var regex = /([\w\s]*),\s*([A-Z]{2})\s*(\d*-?\d*)/g;
    var match = regex.exec(cityStateZip);
    if (match) {
      addressInfo = {
        city: match[1],
        state: match[2],
        zip: match[3]
      } as AddressInfo;
      return addressInfo;
    } else {
      return {} as AddressInfo;
    }
  }

  public static getCityStateZipString(addressInfo: AddressInfo): string {
    let result = '';
    if (false == this.isNullOrWhitespace(addressInfo.city)) {
      result += `${addressInfo.city}, `;
    }
    if (false == this.isNullOrWhitespace(addressInfo.state)) {
      result += `${addressInfo.state} `;
    }
    if (false == this.isNullOrWhitespace(addressInfo.zip)) {
      result += addressInfo.zip;
    }
    return result;
  }

  public static getFullAddressString(addressInfo: AddressInfo): string {

    if (addressInfo && StringUtils.isNullOrWhitespace(addressInfo.address)) {
      return 'No Subject Property Entered';
    }
    else {
      return `${addressInfo.address}, ${this.getCityStateZipString(addressInfo)}`
    }
  }
  public static toUpperString(prop: any) {
    if (prop) {
      if (typeof prop === 'string') return prop.toUpperCase();
      return prop.toString().toUpperCase();
    } else {
      return '';
    }
  }
  public static toLowerString(prop: any) {
    if (prop) {
      if (typeof prop === 'string') return prop.toLowerCase();
      return prop.toString().toLowerCase();
    } else {
      return '';
    }
  }
  public static truncateString(str: string, maxLength: number) {
    if (str && str.length > maxLength) {
      return str.slice(0, maxLength);
    } else {
      return str;
    }
  }
  public static insertAt(str: string, insertValue: string, index: number) {
    return [str.slice(0, index), insertValue, str.slice(index)].join('');
  }
  public static replaceAll(str: string, find: string, replace: string) {
    return str.replace(new RegExp(find, 'g'), replace);
  }
  public static safeLocaleCompare(a: string, b: string, sortDirection: string = 'asc') {
    if (sortDirection == 'asc' && a)
      return b ? a.localeCompare(b) : -1;
    else if (b)
      return a ? b.localeCompare(a) : 1;
    else return 0;
  }
}
