import { validateTrigger, ValidationController, ValidationRules } from 'aurelia-validation';
import { autoinject, bindable, BindingEngine, customElement, observable } from 'aurelia-framework';
import { HeaderLabel, ImportColumnMapping, ImportConfigMetering, ImportConfigThirdParty, ImportService, ImportSession } from "../../service/import-service";
import Fuse from 'fuse.js';
import { CustomDatasource } from '../step4/import-step-4';
import { ImportDefaultValueType } from '../../../model/common-model';
import { map } from 'jquery';
import { Mappings } from 'diacritic-regex';

@autoinject
@customElement("import-step-3")
export class ImportStep3 {

  listService;
  @bindable
  public session: ImportSession;

  @bindable
  public newStep;
  @bindable
  public cancelSession;
  @bindable
  public configView: any;

  private columnsMapping: Array<ImportColumnMapping>;
  private columns: Array<HeaderLabel>;

  private ImportDefaultValueType: any = ImportDefaultValueType;

  private nbMappingRequiredNotValid: number;

  private separatorDisabled: boolean = true;
  random: number;


  constructor(private importService: ImportService, private bindingEngine: BindingEngine, private validationController: ValidationController) {
  }

  private fuse: any;
  private fuseOption = {
    isCaseSensitive: false,
    minMatchCharLength: 3,
    keys: [
      "index",
      "columnName"
    ]
  };
  blurDefaultValue(mapping: ImportColumnMapping, uiSelect: any) {
    if (mapping.defaultValue?.length > 0) {
      mapping.columnEndIndex = null;
    }
    this.validationController.validate({
      object: mapping,
      propertyName: "columnStartIndex"
    });
    uiSelect.au.controller.viewModel.select2Instance.trigger('selection:update', { data: mapping });
  }
  blurCloseUiSelect(uiSelect: any) {
    uiSelect.au.controller.viewModel.close();
  }
  async bind() {
    this.listService = new CustomDatasource(this.session, this.importService);
    this.random = Date.now();
    this.columns = await this.importService.getHeaderLabel(this.session.id);
    this.fuse = new Fuse(this.columns, this.fuseOption);
    this.columnsMapping = await this.importService.getColumnMapping(this.session.id);
    let isFirstTime = this.columnsMapping.filter(x => x.columnStartIndex == null).length == this.columnsMapping.length;
    const requiredCols = this.columnsMapping.filter(c => c.columnDefinition?.isMandatory);
    ValidationRules.customRule('remote-config-validation', async (val, obj, args) => {
      this.validationController.errors.splice(0);
      this.validationController.reset();
      let result = true;
      const valResults = await this.importService.validateConfig(this.session.contextName, this.session.id, this.columnsMapping, this.session.config);
      if (valResults.isValid) return true;

      valResults.errors.forEach(e => {
        let propertyName = e.fieldName.toLowerCase();
        if (propertyName.indexOf('.') > 0) {
          propertyName = propertyName.split('.')[0];
        }
        const map = this.columnsMapping.find(cm => cm.columnDefinition.propertyName.toLowerCase() == propertyName);
        if (map == null) return;
        if (map != obj) {
          this.validationController.addError(e.error, map, 'columnStartIndex');
        }
        else {
          // current validating object is the one causing the error, should return false
          result = false;
        }
      });
      return result;
    }, "test");

    this.columnsMapping.forEach(c => {
      ValidationRules
        .ensure((p: ImportColumnMapping) => p.columnStartIndex)
        .satisfiesRule('remote-config-validation')
        // .ensure((p: ImportColumnMapping) => p.defaultValue)
        // .satisfiesRule('remote-config-validation')
        .on(c);
    });
    this.validationController.changeTrigger(validateTrigger.changeOrBlur);
    this.columnsMapping.forEach((mapping: ImportColumnMapping) => {

      if (isFirstTime) {
        let fuseResult = this.fuse.search(mapping.columnDefinition.propertyName);
        if (fuseResult.length > 0) {
          mapping.columnStartIndex = fuseResult[0].item.index;
        } else {
          mapping.columnDefinition.columnNames.forEach(column => {
            if (mapping.columnStartIndex == null) {
              let fuseColumnResult = this.fuse.search(column);
              if (fuseColumnResult.length > 0) {
                mapping.columnStartIndex = fuseColumnResult[0].item.index;
              }
            }
          })
        }
      }

    });
  }




  async confirm() {
    if (this.validationController.errors?.length == 0) {
      await this.importService.saveMapping(this.session.id, this.columnsMapping);
      if (this.session.config != null) {
        await this.importService.saveConfig(this.session.contextName, this.session.id, this.session.config);
      }

      this.newStep();
    }
    else {
      alert('error');
    }
  }

  getTemplate(mapping: ImportColumnMapping) {
    if (mapping.columnStartIndex != null) {
      let startIndex = mapping.columnStartIndex == -1 ? (this.columns.length - 1) : mapping.columnStartIndex;
      if (mapping.columnEndIndex != null && mapping.columnEndIndex != "''") {
        return this.columns[startIndex].fullName + " - " + this.columns[mapping.columnEndIndex].fullName
      } else {
        return this.columns[startIndex].fullName;
      }
    } else {
      return ""
    }
  }
}
