import { THIS_EXPR } from '@angular/compiler/src/output/output_ast';
import { AfterViewChecked, ChangeDetectorRef, Component, OnInit, ViewContainerRef } from '@angular/core';
import { FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
import { MatTableDataSource } from '@angular/material';
import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { InitCommonsService, NotificationService, NotificationType } from '@xdf/commons';
import { AuditDialogService, ColumnTemplate, ConfirmationDialogService, DynaDataService, GridTemplate, IFormView, ValidatorUtils } from '@xdf/gallery';
import { NavigationService } from '@xdf/layouts';
import { reduce } from 'rxjs/operators';
import { CalendarService } from '../calendar/services/calendar.service';
import { AdditionalParamDialogDialogService } from './additional-param-dialog/service/additional-param-dialog.service';
import { SchedulerTaskInitialData } from './beans/scheduler-task-initial-data';
import { CronExpressionDialogService } from './cron-expression-dialog/services/cron-expression-dialog.service';
import { processETLService } from './services/processetl.service';

@Component({
  selector: 'byte-scheduler-task',
  templateUrl: './scheduler-task.component.html',
  styleUrls: ['./scheduler-task.component.scss']
})
export class SchedulerTaskComponent extends IFormView implements AfterViewChecked {
  columnTemplateArray: ColumnTemplate[];
  template: GridTemplate;
  title: string;
  sortColumn;
  sortDirection;
  innerContent: any;
  displayedColumns = ['additional_parameter', 'additional_parameter_value'];
  additionalData = new MatTableDataSource<any>();
  additionalParameterData = [];
  checkboxComponents = [];
  disabledFields = [
    'id'
  ]
  regex = /^(((\*|(\d\d?))(\/\d\d?)?)|(\d\d?\-\d\d?))(,(((\*|(\d\d?))(\/\d\d?)?)|(\d\d?\-\d\d?)))*\s(((\*|(\d\d?))(\/\d\d?)?)|(\d\d?\-\d\d?))(,(((\*|(\d\d?))(\/\d\d?)?)|(\d\d?\-\d\d?)))*\s(((\*|(\d\d?))(\/\d\d?)?)|(\d\d?\-\d\d?))(,(((\*|(\d\d?))(\/\d\d?)?)|(\d\d?\-\d\d?)))*\s(\?|(((\*|(\d\d?L?))(\/\d\d?)?)|(\d\d?L?\-\d\d?L?)|L|(\d\d?W))(,(((\*|(\d\d?L?))(\/\d\d?)?)|(\d\d?L?\-\d\d?L?)|L|(\d\d?W)))*)\s(((\*|(\d|10|11|12|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))(\/\d\d?)?)|((\d|10|11|12|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\-(\d|10|11|12|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)))(,(((\*|(\d|10|11|12|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))(\/\d\d?)?)|((\d|10|11|12|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\-(\d|10|11|12|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))))*\s(((\*|([0-7]|MON|TUE|WED|THU|FRI|SAT|SUN)L?)(\/\d\d?)?)|(([0-7]|MON|TUE|WED|THU|FRI|SAT|SUN)L?\-([0-7]|MON|TUE|WED|THU|FRI|SAT|SUN)L?)|([0-7]|MON|TUE|WED|THU|FRI|SAT|SUN)L?#([1-5]))(,(((\*|([0-7]|MON|TUE|WED|THU|FRI|SAT|SUN)L?)(\/\d\d?)?)|(([0-7]|MON|TUE|WED|THU|FRI|SAT|SUN)L?\-([0-7]|MON|TUE|WED|THU|FRI|SAT|SUN)L?)|([0-7]|MON|TUE|WED|THU|FRI|SAT|SUN)L?#([1-5])))*$/;

  listaETL = [];
  listaCalendario = [];

  initialData: SchedulerTaskInitialData;

  constructor(
    protected vcRef: ViewContainerRef,
    protected route: ActivatedRoute,
    protected router: Router,
    protected dynaDataService: DynaDataService,
    protected translate: TranslateService,
    protected notificationService: NotificationService,
    protected auditDialogService: AuditDialogService,
    protected confirmationDialogService: ConfirmationDialogService,
    protected navigationService: NavigationService,
    protected init: InitCommonsService,
    protected validatorUtils: ValidatorUtils,
    private readonly changeDetectorRef: ChangeDetectorRef,
    private additionalParamDialogDialogService: AdditionalParamDialogDialogService,
    protected cronExpressionDialogService: CronExpressionDialogService,
    protected calendarService: CalendarService,
    protected processETL: processETLService 
  ) {
    super(vcRef, route, router, dynaDataService, translate, notificationService, auditDialogService, confirmationDialogService, init);
  }

  ngAfterViewChecked(): void {
    if (this.form.controls['internals'] && this.mode !== 'view') {
      this.form.controls['internals'].enable();
    }
    this.changeDetectorRef.detectChanges();
  }

  conversorCalendar(lista:any[]){
    for(let i=0;i<lista.length;i++){
      this.listaCalendario.push({
        id: (lista[i]['id'] as String).trim(),
        name: lista[i]['name']
      })
    }
  }

  conversorEtl(lista: any[]){
    for(let i=0;i<lista.length;i++){
      this.listaETL.push({
        id: lista[i]['id'],
        description: lista[i]['name']
      })
    }
  }

  protected getFields(): FormGroup {
    let form;
    if (this.mode !== 'new' && this.record) {
      if (this.mode === 'view') {
        this.displayedColumns = ['additional_parameter', 'additional_parameter_value'];
      } else {
        this.displayedColumns = ['additional_parameter', 'additional_parameter_value', 'actions'];
      }
      // console.log(this.record)
      form = new FormGroup({
        id: this.createFormControl('id', true, true),
        description: this.createFormControl('description', true, true),
        businessFlow: this.createFormControl('etlId', true, true),
        calendar: this.createFormControl('calendarID', true, true),
        internals: this.createFormControl('internals', true, false),
        cronExpression: this.createFormControl('cronExpression', true, true, '', [Validators.pattern(this.regex)]),
        stringParameters: this.createFormControl('stringParameters', true, false),
      });
    } else {
      form = new FormGroup({
        id: this.createFormControl('id', false, true),
        description: this.createFormControl('description', false, true),
        businessFlow: this.createFormControl('etlId', false, true),
        calendar: this.createFormControl('calendarID', false, true),
        internals: this.createFormControl('internals', false, false),
        cronExpression: this.createFormControl('cronExpression', false, true,'', [Validators.pattern(this.regex)]),
        stringParameters: this.createFormControl('stringParameters', false, false),
      });
    }
    return form;
  }

  ngOnInit() {
    super.ngOnInit();
    // this.calendarService.getResultList
    this.calendarService.getCalendarList().subscribe(res=>{
      this.conversorCalendar(res)
    })

    this.processETL.getAllProcessETL().subscribe(res=>{
      this.conversorEtl(res)
    })

    
    
    this.initialData = this.route.snapshot.data['initialData'];
    if (this.record && this.record['additional-parameter']) {
      this.additionalParameterData = this.record['additional-parameter'];
    } else {
      this.additionalParameterData = [];
    }
    this.additionalData = new MatTableDataSource(this.additionalParameterData);
  }

  completeForm() {
    this.record['id'] = this.id;
    this.record.calendar
  }

  

  getValidators(validatorList): ValidatorFn[] {
    let validators = [];
    for (let validator of validatorList) {
      validators.push(this.validatorUtils.getValidator(validator, undefined));
    }
    return validators;
  }

  loadData(data) {
    this.record = data;
  }

  private createFormControl(name: string, existRecord?: boolean, required?: boolean, defaultValue?: string, validators?: Array<ValidationErrors>): FormControl {
    if (!defaultValue) defaultValue = '';
    let validatorList = [];
    if (validators) validatorList = validators;
    if (required) validatorList.push(Validators.required);
    let valueaux = existRecord ? this.record[name] : '';
    if (name === 'internals') {
      valueaux = (valueaux === "Y");
    }
    return new FormControl({ value: valueaux, disabled: this.disabledCondition(name) }, validatorList);
  }

  protected disabledCondition(controlName?): boolean {
    const disabled = this.mode === 'view' || this.disabledFields.includes(controlName);
    return disabled;
  }

  updateForm(id, mode) {
    this.mode = mode;
    this.id = id;
    if (this.id) {
      this.dynaDataService.getResult(this.id).subscribe(
        data => {
          this.record = data;
          this.form = this.getFields();
        }
      );
    } else {
      this.record = new Object();
      this.form = this.getFields();
    }
  }

  protected loadSettings() {
    this.title = this.templateDefinition.title;
    this.template = new GridTemplate(this.templateDefinition);
    this.innerContent = this.route.snapshot.data.innerTemplate;
    if (this.innerContent === 'none') {
      this.template.expandRow = false;
      this.innerContent = null;
    }
    if (this.template.expandRow && !this.innerContent) {
      const titleError = this.translate.instant('title.error');
      const error = this.translate.instant('inner.content.notfound.error');
      this.notificationService.showMessage(error, titleError, NotificationType.warning);
      this.template.expandRow = false;
    }
    this.sortColumn = this.template.sortColumnDefault;
    this.sortDirection = this.template.sortColumnDirection;
    this.columnTemplateArray = this.template.columnTemplateArray;
  }

  onRowClicked(record: object): void {
    const keyView = 'view';
    if (this.resourceAuth[keyView]) {
      this.additionalParamDialogDialogService.loadComponent(this.vcRef, "additional_param_view", record, 'view');
    }
  }

  onRowEdited(record: object): void {
    const keyField = 'additional_parameter';
    const keyFieldValue = 'additional_parameter_value';
    const keyRecord = 'record';
    this.additionalParamDialogDialogService.loadComponent(this.vcRef, "additional_param_edit", record, 'edit').subscribe(result => {
      if (result && result['success']) {
        for (let index in this.additionalParameterData) {
          if (this.additionalParameterData[index][keyField] === record[keyField]) {
            this.additionalParameterData[index][keyField] = result[keyRecord][keyField];
            this.additionalParameterData[index][keyFieldValue] = result[keyRecord][keyFieldValue];
            this.additionalData = new MatTableDataSource(this.additionalParameterData);
            break;
          }
        } 
      }
    });
  }
  
  onNewRecord(showCancelButton) {
    this.additionalParamDialogDialogService.loadComponent(this.vcRef, "additional_param_new", undefined, 'new', showCancelButton).subscribe(result => {
      if (result && result['success']) {
        if (!this.additionalParameterData) {
          this.additionalParameterData = [];
        }
        let found = false;
        for (const additionalParameter of this.additionalParameterData) {
          if (additionalParameter['additional_parameter'] === result['record']['additional_parameter']) {
            additionalParameter['additional_parameter_value'] = result['record']['additional_parameter_value'];
            found = true;
            break;
          }
        }
        if (!found) {
          this.additionalParameterData.push(result['record']);
        }
        this.additionalData = new MatTableDataSource(this.additionalParameterData);
      }
    });
  }

  onDeleteRecord(record: object): void {
    const keyField = 'additional_parameter';
    this.confirmationDialogService.loadComponent(this.vcRef, 'additional_param_delete', 'additional_param_delete_message').subscribe(result => {
      if (result) {
        for (let index in this.additionalParameterData) {
          if (this.additionalParameterData[index][keyField] === record[keyField]) {
            this.additionalParameterData.splice(Number(index), 1);
            this.additionalData = new MatTableDataSource(this.additionalParameterData);
            break;
          }
        }  
      }
    });
  }

  onCronExpressionClicked() {
    this.cronExpressionDialogService.loadComponent().subscribe(response => {
      console.log(response);
    });
  }

  submit() {
    console.log(this.record);
    this.processing = true;
    if (this.mode === 'new') {
      let data = {};
      data['id'] = this.form.value['id'];
      data['description'] = this.form.value['description'];
      data['etlId'] = this.form.value['businessFlow'];
      data['calendarID'] = this.form.value['calendar'];
      data['internals'] = this.form.value['internals'] ? "Y" : "N";
      data['cronExpression'] = this.form.value['cronExpression'];
      data['stringParameters'] = this.form.value['stringParameters'];
      this.dynaDataService.create(data).subscribe(res => {
        const title = this.translate.instant('title.information');
        const message = this.translate.instant('message.create.succesful');
        this.notificationService.showMessage(
          message,
          title,
          NotificationType.success
        );
        this.record = new Object();
        this.router.navigate([this.returnUrl]);
        this.form.reset();
        this.processing = false;
      }, error => { this.processing = false });
    } else {
      this.record['description'] = this.form.value['description'];
      this.record['etlId'] = this.form.value['businessFlow'];
      this.record['calendarID'] = this.form.value['calendar'];
      this.record['internals'] = this.form.value['internals'] ? "Y" : "N";
      this.record['cronExpression'] = this.form.value['cronExpression'];
      this.record['stringParameters'] = this.form.value['stringParameters'];
      this.dynaDataService.update(this.record['id'], this.record).subscribe(res => {
        const title = this.translate.instant('title.information');
        const message = this.translate.instant('message.update.succesful');
        this.notificationService.showMessage(
          message,
          title,
          NotificationType.success
        );
        this.form.markAsPristine();
        this.router.navigate([this.returnUrl]);
      });
    }
  }

}
