import * as Utils from '../../utils';
import { EN_DropDownConst4Filter } from '../../consts';
//Date format for dates in Web API

export class BaseFilter {
  filterPrefix: string = '';
  alwaysUsefilterPrefix: boolean = false;
  useObjectFilter: boolean = true;


  public onPrepare: (retFilter: BaseFilter) => void;
  protected dontConsiderFields = ',filterPrefix,alwaysUsefilterPrefix,dontConsiderFields,useObjectFilter,onPrepare,dontResetFields,';

  public dontResetFields = '';

  public constructor(filterPrefix: string = '', init?: Partial<BaseFilter>) {
    this.filterReset();
    if (init) { Object.assign(this, init); }
    this.filterPrefix = filterPrefix;
  }


  public isFieldEmpty(fldName: string): boolean {
    let isEmpty: boolean;
    const obj: any = this[fldName];
    isEmpty = !obj && !(typeof obj === 'boolean' && obj === false);
    if (!isEmpty) {
      if (obj instanceof Array) isEmpty = obj.length === 0;
      else {
        switch (typeof obj) {
          case 'number':
            isEmpty = (obj === EN_DropDownConst4Filter.AllValueInt);
            break;
          case 'string':
            isEmpty = (obj === EN_DropDownConst4Filter.AllValueString);
            break;
        }
      }
    }
    return isEmpty;
  }


  public initField(fldName: string) {
    if (!this.isFieldEmpty(fldName)) {
      if (this[fldName] instanceof Array) this[fldName] = [];
      else {
        switch (typeof this[fldName]) {
          // case 'number':
          //   Object.assign(this, { [fldName]: 0 });
          //   break;
          case 'string':
            Object.assign(this, { [fldName]: '' });
            break;
          default:
            this[fldName] = null;
            break;
        }
      }
    }
  }


  protected isServiceField(fldName: string): boolean {
    return (',' + this.dontConsiderFields + ',').indexOf(',' + fldName + ',') > -1;
  }


  protected isFixedField(fldName: string): boolean {
    return (',' + this.dontResetFields + ',').indexOf(',' + fldName + ',') > -1;
  }


  public getFilterURL(): any {
    const retFilter: BaseFilter = Object.assign({}, this);
    if (this.doPrepare) this.doPrepare(retFilter);
    let retVal = '';
    // tslint:disable-next-line: forin
    for (const prop in retFilter) {
      if (!retFilter.isServiceField(prop) && retFilter.propertyIsEnumerable(prop) && !retFilter.isFieldEmpty(prop)) {
        let curval: string = '';
        const obj = retFilter[prop];

        if (obj instanceof Array) {
          if (obj.length > 0) curval = obj.join();
        } else curval = Utils.toStringConsiderDateFormat(obj);
        if (curval) retVal += `&${prop}=${curval}`;
      }
    }
    if (retVal.length) retVal = retVal.substring(1);
    if (retVal.length) retVal = retFilter.filterPrefix + '?' + retVal;
    else if (retFilter.alwaysUsefilterPrefix) retVal = retFilter.filterPrefix;

    return retVal;
  }


  getFilter(): any {
    const retFilter: BaseFilter = Object.assign({}, this);
    if (this.doPrepare) this.doPrepare(retFilter);
    delete retFilter.alwaysUsefilterPrefix;
    delete retFilter.filterPrefix;
    delete retFilter.useObjectFilter;
    delete retFilter.dontConsiderFields;
    delete retFilter.dontResetFields;
    return retFilter;
  }

  protected doPrepare(retFilter: BaseFilter) {
    for (const prop in this) {
      if (!this.isServiceField(prop) && this.propertyIsEnumerable(prop) && !this.isFieldEmpty(prop)) {
        const obj = retFilter[prop as string];
        switch (typeof obj) {
          case 'string':
            retFilter[prop as string] = obj.trim();
            break;
        }
      }
    }
    if (this.onPrepare) this.onPrepare(retFilter);
  }


  public filterReset() {
    for (const prop in this) {
      if (!this.isServiceField(prop) && !this.isFixedField(prop) && this.propertyIsEnumerable(prop)) this.initField(prop);
    }
  }
}
