export class Filter {
  match = [];
  negate = [];

  constructor(query) {
    query ??= "";
    query = query.trim();

    // https://stackoverflow.com/a/16261693
    for (let match of (query.match(/(?:[^\s"]+|"[^"]*")+/g) ?? [])) {
      const negate = match[0] === '-';
      if (negate) {
        match = match.slice(1);
      }

      if (match[0] === '"' && match[match.length - 1] === '"') {
        match = match.slice(1, match.length - 1);
      }

      match = match.trim().toLocaleLowerCase();

      if (!match) continue;

      if (negate) {
        this.negate.push(match);
      } else {
        this.match.push(match);
      }
    }
  }

  static fromInput(dataValue) {
    if (typeof dataValue === "string") {
      const elem = document.querySelector(`[data-input='${dataValue}']`);
      return new Filter(elem.value);
    }
    return new Filter(dataValue.value);
  }

  test(...data) {
    for (const datum of data) {
      if (typeof datum !== "string") {
        console.trace("cannot test %o", datum);
        continue;
      }

      const normalized = datum.trim().toLocaleLowerCase().trim();
      for (const n of this.negate) {
        if (normalized.includes(n)) {
          return false;
        }
      }
      for (const m of this.match) {
        if (normalized.includes(m)) {
          return true;
        }
      }
    }
    return this.match.length === 0;
  }
}
