import {
  Component,
  OnDestroy,
  ViewChild,
  ChangeDetectorRef,
  AfterViewInit,
} from '@angular/core';
import { MaterialModule } from '../material/material.module';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { WorkflowInterface } from '../interfaces/samwf/workflow-interface';
import { WorkflowService } from '../services/samwf/workflow.service';
import { MatPaginator } from '@angular/material/paginator';
import { MatTableDataSource } from '@angular/material/table';
import { ModulosInterface } from '../interfaces/samwf/modulos-interface';
import { Observable, lastValueFrom } from 'rxjs';
import { ResponseData } from '../interfaces/response-data';
import { MatSnackBar } from '@angular/material/snack-bar';
import { WorkflowFormComponent } from './workflow-form/workflow-form.component';
import { OnInit } from '@angular/core';

@Component({
  selector: 'app-workflow',
  templateUrl: './workflow.component.html',
  styleUrls: ['./workflow.component.css'],
})
export class WorkflowComponent implements OnInit, MaterialModule, OnDestroy {
  workflows: any[] = [];
  data_empty = false;
  obs: Observable<any>;
  dataSource: MatTableDataSource<any> = new MatTableDataSource<any>(
    this.workflows
  );

  loading = false;
  @ViewChild(MatPaginator) paginator: MatPaginator;

  constructor(
    public dialog: MatDialog,
    private router: Router,
    private translate: TranslateService,
    private _samwfService: WorkflowService,
    private changeDetectorRef: ChangeDetectorRef,
    private _snackBar: MatSnackBar
  ) {
    this.dataSource.data.length > 0
      ? (this.data_empty = false)
      : (this.data_empty = true);
  }

  ngOnInit(): void {
    this.getWorkflows();
    this.changeDetectorRef.detectChanges();
    this.dataSource.paginator = this.paginator;
    this.obs = this.dataSource.connect();
  }

  ngOnDestroy() {
    if (this.dataSource) {
      this.dataSource.disconnect();
    }
  }

  updatePaginator() {
    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];
    });
  }

  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.name.toString().toLowerCase().includes(filter) ||
        data.description.toString().toLowerCase().includes(filter) ||
        data.created_at.toString().includes(filter)
      );
    };
  }

  private async getWorkflows() {
    await lastValueFrom(this._samwfService.getWorkflows()).then(
      (data: any) => {
        this.workflows = data;
        this.loading = false;
        this.dataSource.data = data;
        this.dataSource.data.length > 0
          ? (this.data_empty = false)
          : (this.data_empty = true);
      },
      (error: any) => {
        console.log(error);
        this.loading = true;
        this._snackBar.open(
          'Continuamos buscando la información, espere un momento.',
          'Cerrar',
          { duration: 3000 }
        );
        this.ngOnInit();
      }
    );
  }

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

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

    let modules: ModulosInterface[] = [];
    await lastValueFrom(this._samwfService.getModules()).then(
      (data: any) => {
        modules = data;
      },
      (error: any) => console.log(error)
    );

    await sleep(300);

    let dataAction = {
      action: action,
      item: item,
      modules: modules,
    };

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

    dialogRef.afterClosed().subscribe((result: any) => {
      if (result) {
        if (action == 'Registrar') {
          result.id_module = result.module;
          this.registerWorkflow(result);
        } else {
          result.id_module = result.module;
          result.isAvailable = item.isAvailable;
          this.modifyWorkflow(result, item.id);
        }
      }
    });
  }

  public async registerWorkflow(workflow: WorkflowInterface) {
    await lastValueFrom(this._samwfService.registerWorkflow(workflow)).then(
      (data: ResponseData) => {
        if (!data.error) {
          this._snackBar.open('!Registro de workflow existoso!', 'Cerrar', {
            duration: 3000,
          });
        }
      },
      (error) => {
        console.log(error);
        this._snackBar.open(error.message, 'Cerrar', { duration: 3000 });
      }
    );
    this.ngOnInit();
  }

  public async modifyWorkflow(workflow: WorkflowInterface, idW: number) {
    await lastValueFrom(this._samwfService.updateWorkflow(workflow, idW)).then(
      (data: ResponseData) => {
        if (!data.error) {
          this._snackBar.open('!Modificación de workflow existoso!', 'Cerrar', {
            duration: 3000,
          });
        }
      },
      (error) => {
        console.log(error);

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

  public async updateStateWorkflow(item: any) {
    await lastValueFrom(this._samwfService.updateStateWorkflow(item.id)).then(
      (data: ResponseData) => {
        if (!data.error) {
          this.ngOnInit();
          this._snackBar.open('!Modificación de estado existoso!', 'Cerrar', {
            duration: 3000,
          });
        }
      },
      (error) => {
        console.log(error);

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

  public async updateTypeWorkflow(item: any) {
    await lastValueFrom(this._samwfService.updateTypeWorkflow(item.id)).then(
      (data: ResponseData) => {
        if (!data.error) {
          this.ngOnInit();
          this._snackBar.open(
            '!Modificación de tipo de worklow existoso!',
            'Cerrar',
            {
              duration: 3000,
            }
          );
        }
      },
      (error) => {
        console.log(error);

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

  detailWorkflow(item: any) {
    this.router.navigate(['/workflow', item.id]);
  }

  versionsHistory(item: any) {
    this.router.navigate(['workflow/versions-history', item.id]);
  }
}
