import { Component, Inject, OnInit, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatTableDataSource } from '@angular/material/table';
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
import { WorkflowPasosFormComponent } from './workflow-tasks-form/workflow-pasos-form.component';
import { TranslationComponent } from '../../translation/translation.component';
import { TranslateService } from '@ngx-translate/core';
import { MaterialModule } from '../../material/material.module';
import { WorkflowService } from '../../services/samwf/workflow.service';
import { TaskInterface } from 'src/app/interfaces/samwf/task-interface';
import { TasksJSONInterface } from '../../interfaces/samwf/tasks-json-interface';
import { data } from '@syncfusion/ej2';
import { lastValueFrom, takeLast } from 'rxjs';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ResponseData } from 'src/app/interfaces/response-data';
import { WorkflowUsersComponent } from './workflow-users/workflow-users.component';
import { WorkflowFieldsFormComponent } from './workflow-fields-form/workflow-fields-form.component';

@Component({
  selector: 'app-workflow-detail',
  templateUrl: './workflow-detail.component.html',
  styleUrls: ['./workflow-detail.component.css'],
})
export class WorkflowDetailComponent implements OnInit, MaterialModule {
  displayedColumns: string[] = [
    'sequence',
    'estatus',
    'process',
    'notification',
    'actions',
  ];

  data_empty = false;

  workflow: any = {};

  workflowObject: any = {};

  tasks: any = [];

  idWorkflow: any;

  @ViewChild(MatPaginator) paginator!: MatPaginator;
  dataSource = new MatTableDataSource<any>(this.tasks);

  constructor(
    private router: ActivatedRoute,
    public dialog: MatDialog,
    private routerNavigate: Router,
    private translate: TranslateService,
    private _samwfService: WorkflowService,
    private _snackBar: MatSnackBar
  ) {
    this.idWorkflow = this.router.snapshot.paramMap.get('id');

    translate.setDefaultLang('es');
  }

  ngAfterViewInit(): void {
    this.translate.get('paginador').subscribe((data: any) => {
      this.dataSource.paginator = this.paginator;
      this.paginator._intl.itemsPerPageLabel = data[0];
      this.paginator._intl.firstPageLabel = data[1];
      this.paginator._intl.lastPageLabel = data[2];
      this.paginator._intl.nextPageLabel = data[3];
      this.paginator._intl.previousPageLabel = data[4];
    });

    this.dataSource.filterPredicate = function (data, filter: string): boolean {
      return (
        data.secuencia.toString().toLowerCase().includes(filter) ||
        data.estatus.toString().toLowerCase().includes(filter) ||
        data.accion.accion.toString().toLowerCase().includes(filter)
      );
    };
  }

  ngOnInit(): void {
    this.getTasksWorkflow();
  }

  applyFilter(filterValue: any) {
    this.dataSource.filter = filterValue.target.value.trim().toLowerCase();
  }

  openDialogsByType(action: string, item: any = {}) {
    if (this.workflowObject.isForm == true) {
      this.openDialogFieldsForm(action, item);
    } else {
      this.openDialogTaskForm(action, item);
    }
  }

  // Dialogo
  async openDialogTaskForm(action: string, item: any = {}) {
    const sleep = (ms: number) =>
      new Promise((resolve) => setTimeout(resolve, ms));

    let processArr: any[] = [];

    await lastValueFrom(this._samwfService.getTasks()).then(
      (data: any) => {
        processArr = data;
      },
      (error: any) => {
        console.error(error);

        this._snackBar.open(error.message, 'Cerrar', { duration: 3000 });
      }
    );

    let data = item != null ? JSON.stringify(item) : null;
    let tasks_bd = processArr;
    this.sendArrayTasks(null);

    this.sendArrayTasks(processArr);
    this.routerNavigate.navigate([
      `/workflow/${this.idWorkflow}/tasksFlow`,
      { data, action },
    ]);
  }

  openDialogFieldsForm(action: string, item: any) {
    let dataAction = {
      action: action,
      item: item,
    };

    const dialogRef = this.dialog.open(WorkflowFieldsFormComponent, {
      data: dataAction,
    });

    dialogRef.afterClosed().subscribe((result) => {
      console.log(result);
      let objField = {};
    });
  }

  openDialogUsers(item: any) {
    let dataAction = {
      action: 'Usuarios',
      item: item,
    };

    const dialogRef = this.dialog.open(WorkflowUsersComponent, {
      data: dataAction,
    });

    dialogRef.afterClosed().subscribe((result) => {});
  }

  sendArrayTasks(data: any) {
    this._samwfService.setArray(data);
  }

  backToWorkflows() {
    this.routerNavigate.navigate(['workflow']);
  }

  showDiagram() {
    this.router.params.subscribe((params) => {
      this.routerNavigate.navigate(['workflow/diagrama/', params['id']]);
    });
  }

  deleteTask(task: any, indexTask: any) {
    console.log(this.dataSource.data);
    let filterFlow: any[] = [];
    let filterFlowAux: any[] = [];
    let positionTaskChangeSequence = this.dataSource.data.findIndex(
      (object: any) => {
        return object.sequence === task.changeSequence;
      }
    );

    filterFlow = this.dataSource.data.filter((object: any) => {
      return (
        object.sequence >= task.nextSequence &&
        object.sequence <= task.changeSequence
      );
    });

    for (let index = 0; index < this.dataSource.data.length; index++) {
      if (
        positionTaskChangeSequence > -1 &&
        this.dataSource.data[positionTaskChangeSequence].changeSequence != null
      ) {
        if (
          this.dataSource.data[index].sequence ==
          this.dataSource.data[positionTaskChangeSequence].changeSequence
        ) {
          positionTaskChangeSequence = index;
          if (
            positionTaskChangeSequence > -1 &&
            this.dataSource.data[positionTaskChangeSequence].changeSequence !=
              null
          ) {
            if (
              this.dataSource.data[index].sequence ==
              this.dataSource.data[positionTaskChangeSequence].changeSequence
            ) {
              positionTaskChangeSequence = index;
            }
          }
        }
      }
    }

    if (positionTaskChangeSequence > -1) {
      filterFlowAux = this.dataSource.data.filter((object: any) => {
        return (
          object.sequence > task.changeSequence &&
          object.sequence <=
            this.dataSource.data[positionTaskChangeSequence].sequence
        );
      });

      filterFlow = filterFlow.concat(filterFlowAux);
    }

    const deleteTasks = filterFlow;

    filterFlow.push(task);
    this.filterLevel1(deleteTasks, filterFlow);
  }

  private filterLevel1(deleteTasks: any[], filterFlow: any[]) {
    for (let index = 0; index < filterFlow.length; index++) {
      let positionDelete = this.dataSource.data.findIndex((object: any) => {
        return object.sequence == filterFlow[index].sequence;
      });

      this.dataSource.data = this.dataSource.data.filter(
        (i: any) => i != this.dataSource.data[positionDelete]
      );
    }

    for (let index = 0; index < deleteTasks.length; index++) {
      let positionDelete = this.dataSource.data.findIndex((object: any) => {
        return object.nextSequence == deleteTasks[index].sequence;
      });

      let positionDeleteChange = this.dataSource.data.findIndex(
        (object: any) => {
          return object.changeSequence == deleteTasks[index].sequence;
        }
      );

      if (positionDelete > -1) {
        this.dataSource.data[positionDelete].nextSequence =
          deleteTasks[index].sequence;
      } else if (positionDeleteChange > -1) {
        this.dataSource.data[positionDeleteChange].changeSequence =
          deleteTasks[index].sequence;
      }
    }
    this.filterLevel2();
  }

  private filterLevel2() {
    for (let index = 0; index < this.dataSource.data.length; index++) {
      if (
        this.dataSource.data[index].sequence !== 1000 &&
        this.dataSource.data[index].nextSequence !=
          this.dataSource.data[index + 1].sequence
      ) {
        this.dataSource.data[index].nextSequence =
          this.dataSource.data[index + 1].sequence;
        this.dataSource.data[index].sequence == null;
      }
    }

    this.filterLevel3();
  }

  private filterLevel3() {
    for (let index = 0; index < this.dataSource.data.length; index++) {
      if (
        this.dataSource.data[index].sequence !== 1000 &&
        this.dataSource.data[index].isConditional == true &&
        this.dataSource.data[index].changeSequence !=
          this.dataSource.data[index + 2].sequence
      ) {
        this.dataSource.data[index].changeSequence =
          this.dataSource.data[index + 2].sequence;
      }
    }

    if (this.dataSource.data.length > 2) {
      this.workflowObject.tasks = this.dataSource.data;
      this.asingTaskWorkflow();
    } else {
      this.dataSource.data = this.workflow;

      this._snackBar.open(
        'La tarea no puede ser eliminada, ya que el workflow debe contar con 3 tareas minimo ',
        'Cerrar',
        {
          duration: 3000,
        }
      );
      this.ngOnInit();
    }
    /*     this.workflowObject.tasks = this.dataSource.data;
    this.asingTaskWorkflow(); */
  }

  async disableTask(sequence: any) {
    let taskAux = {
      sequence: sequence,
      id_workflow: parseInt(this.idWorkflow),
    };

    await lastValueFrom(this._samwfService.disableTaskWorklfow(taskAux)).then(
      (data: ResponseData) => {
        if (!data.error) {
          this.ngOnInit();
          this._snackBar.open('!Actualización de tarea exitoso!', 'Cerrar', {
            duration: 3000,
          });
        }
      },
      (error) => {
        console.error(error);
        this._snackBar.open(error.message, 'Cerrar', { duration: 3000 });
      }
    );
    this.ngOnInit();
  }

  private async getTasksWorkflow() {
    await lastValueFrom(this._samwfService.getWorkflow(this.idWorkflow)).then(
      (data: any) => {
        this.workflowObject = data;

        /*         this.workflow = data.tasks.filter(
            (object: any) => object.isAvailable != false
          );
          this.dataSource.data = data.tasks.filter(
            (object: any) => object.isAvailable != false
          ); */

        this.workflow = data.tasks;
        this.dataSource.data = data.tasks;
        console.log(data.tasks);

        this.dataSource.data.length > 0
          ? (this.data_empty = false)
          : (this.data_empty = true);
      },
      (error: any) => {
        console.error(error);

        this._snackBar.open(error.message, 'Cerrar', { duration: 3000 });
      }
    );
  }

  private async asingTaskWorkflow() {
    await lastValueFrom(
      this._samwfService.updateWorkflow(this.workflowObject, this.idWorkflow)
    ).then(
      (data: ResponseData) => {
        console.log(data);
        this._snackBar.open('!Actualización de workflow exitoso!', 'Cerrar', {
          duration: 3000,
        });
      },
      (error) => {
        console.log(error);

        this._snackBar.open(error.message, 'Cerrar', { duration: 3000 });
      }
    );
  }
}

/* objAux = {
  conditionalYes: this.tasksData[positionTaskYes],
  conditionalNo: this.tasksData[positionTaskNo],
  taskCurrent: this.tasksData[positAux].taskCurrent,
  indexYes: this.letras[this.indiceAux] + 1,
  indexNo: this.letras[this.indiceAux] + 2,
  indexPosition: this.tasksData[positAux].indexPosition,
}; */

/* const conditionalsAux = this.fb.group({
  conditionalYes: new FormControl(this.tasksData[positionTaskYes]),
  conditionalNo: new FormControl(this.tasksData[positionTaskNo]),
  taskCurrent: new FormControl(this.tasksData[positAux].taskCurrent),
  indexYes: new FormControl(this.letras[this.indiceAux] + 1),
  indexNo: new FormControl(this.letras[this.indiceAux] + 2),
  indexPosition: new FormControl(this.tasksData[positAux].indexPosition),
});
 */
