import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { InternationalizationService } from '../../../../services/internationalization/internationalization.service';
import { ResourcesService } from '../../../../services/resources.service';
import { EncService } from '../../../../services/enc.service';
import { lastValueFrom } from 'rxjs';
import { ProcessManagementService } from '../../../../services/process-management/process-management.service';
import { GetTaskByWorkflow, ResponseDataGetTaskByWorkflow } from '../../../../interfaces/process-managementv/workflow-management.interface';
import { DOCUMENT } from '@angular/common';
import { EFConnectionBehavior, EFMarkerType } from '@foblex/flow'

interface FlowTasksInterface{
  isNode: boolean;
  isConnection: boolean;
  label: string | null;
  inputID: string | null;
  outputID: string | null;
  positionX: number;
  positionY: number;
}
@Component({
  selector: 'app-view-graphic-workflow',
  standalone: false,
  templateUrl: './view-graphic-workflow.component.html',
  styleUrls: [
    './view-graphic-workflow.component.css',
    './component.scss'
  ],
  //changeDetection: ChangeDetectionStrategy.OnPush
})
export class ViewGraphicWorkflowComponent implements OnInit {
  isLoading: boolean;
  hasError: boolean;
  errorStr: string;
  tasks: GetTaskByWorkflow[];
  flowTasks: FlowTasksInterface[];
  flowConnections: FlowTasksInterface[];

  public eConnectionBehaviour = EFConnectionBehavior;
  protected readonly eMarkerType = EFMarkerType;

  constructor(
    @Inject(DOCUMENT) private _document: Document,
    @Inject(MAT_DIALOG_DATA) private _data: any,
    public interService: InternationalizationService,
    private _resourcesService: ResourcesService,
    private _encService: EncService,
    private _processManagementService: ProcessManagementService,
  ) {
    this.isLoading = true;
    this.hasError = false;
    this.errorStr = '';
    this.tasks = [];
    this.flowTasks = [];
    this.flowConnections = [];
  }

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

  async getTaskByWorkflow(){
    try{
      this.isLoading = true;
      const ENC_WORKFLOW: string = await this._encService.encrypt(this._data.idWorkflow.toString());
      const USER: string = this._resourcesService.getUser();
      const LINE: number = this._resourcesService.getLineNumber();

      let tasks: ResponseDataGetTaskByWorkflow = await lastValueFrom(this._processManagementService.getTaskByWorkflow(ENC_WORKFLOW, USER, LINE));
      if(tasks.error){
        this._resourcesService.openSnackBar(tasks.msg);
        this.getTaskByWorkflow();
      }else{
        let flowContainer = this._document.getElementById('flow-container')!;
        let flowContainerWidth = flowContainer.clientWidth;
        let flowContainerMaxWidth = flowContainerWidth - 64;
        let flowTasksArr: FlowTasksInterface[] = [];
        let flowConnectionsArr: FlowTasksInterface[] = [];
        let position = 0;
        let positionY = 16;

        flowContainer.addEventListener('mouseover', () => {
          flowContainer.classList.add('flow-container-hover');
          flowContainer.classList.remove('flow-container-active');
        });

        flowContainer.addEventListener('mouseleave', () => {
          flowContainer.classList.remove('flow-container-hover');
          flowContainer.classList.remove('flow-container-active');
        });

        flowContainer.addEventListener('mousedown', () => {
          flowContainer.classList.add('flow-container-active');
          flowContainer.classList.remove('flow-container-hover');
        });

        flowContainer.addEventListener('mouseup', () => {
          flowContainer.classList.add('flow-container-hover');
          flowContainer.classList.remove('flow-container-active');
        });

        for(const task of tasks.response){
          let positionX = 32;
          if(position % 3 == 0){
            positionX = 32;
            if(position > 0) positionY = positionY + 70 + 48;
          }else if(position % 3 == 1){
            positionX = (flowContainerMaxWidth / 2) - (170 / 2);
          }else{
            positionX = flowContainerMaxWidth - 170;
          }
          
          if(position <= 0){
            let firstTask: FlowTasksInterface = {
              isNode: true,
              isConnection: false,
              label: task.NOMBRE_TAREA,
              inputID: null,
              outputID: `${task.ID_TAREA}|${task.SECUENCIA}|O`,
              positionX: positionX,
              positionY: positionY
            };

            flowTasksArr.push(firstTask);
          }else if(position > 0 && position < tasks.response.length - 1){
            let prevTask = tasks.response[position - 1];
            let connectionTask: FlowTasksInterface = {
              isNode: false,
              isConnection: true,
              label: null,
              inputID: `${task.ID_TAREA}|${task.SECUENCIA}|I`,
              outputID: `${prevTask.ID_TAREA}|${prevTask.SECUENCIA}|O`,
              positionX: 0,
              positionY: 0
            }

            flowConnectionsArr.push(connectionTask);
            let nodeTask: FlowTasksInterface = {
              isNode: true,
              isConnection: false,
              label: task.NOMBRE_TAREA,
              inputID: `${task.ID_TAREA}|${task.SECUENCIA}|I`,
              outputID: `${task.ID_TAREA}|${task.SECUENCIA}|O`,
              positionX: positionX,
              positionY: positionY
            };

            flowTasksArr.push(nodeTask);
          }else{
            let prevTask = tasks.response[position - 1];
            let connectionTask: FlowTasksInterface = {
              isNode: false,
              isConnection: true,
              label: null,
              inputID: `${task.ID_TAREA}|${task.SECUENCIA}|I`,
              outputID: `${prevTask.ID_TAREA}|${prevTask.SECUENCIA}|O`,
              positionX: 0,
              positionY: 0
            }

            flowConnectionsArr.push(connectionTask);
            let lastTask: FlowTasksInterface = {
              isNode: true,
              isConnection: false,
              label: task.NOMBRE_TAREA,
              inputID: `${task.ID_TAREA}|${task.SECUENCIA}|I`,
              outputID: null,
              positionX: positionX,
              positionY: positionY
            }

            flowTasksArr.push(lastTask);
          }
          
          position++;
        }

        this.flowTasks = flowTasksArr;
        this.flowConnections = flowConnectionsArr;
        
        this.isLoading = false;
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }

      this.getTaskByWorkflow();
    }
  }
}
