import { Component, Inject, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import {
  ActiveWorkflow,
  DetailsFormTask,
  RequestFormTask,
  ResponseDataActiveWorkflows,
  ResponseDataTask,
  ResponseDataGetTaskByWorkflow,
} from '../../../../interfaces/process-managementv/workflow-management.interface';
import {
  UserResponse,
  UsersResponse,
} from '../../../../interfaces/users.interface';
import {
  MAT_DIALOG_DATA,
  MatDialog,
  MatDialogRef,
} from '@angular/material/dialog';
import {
  ResourcesService,
  ResponseData,
} from '../../../../services/resources.service';
import { InternationalizationService } from '../../../../services/internationalization/internationalization.service';
import { ProcessManagementService } from '../../../../services/process-management/process-management.service';
import { UsersProfilesService } from '../../../../services/users-profiles.service';
import { EncService } from '../../../../services/enc.service';
import { ModulesService } from '../../../../services/modules.service';
import { ModulesInterface } from '../../../../interfaces/modules.interface';
import { lastValueFrom } from 'rxjs';
import { HttpErrorResponse } from '@angular/common/http';
import { AlertComponent } from '../../../resources/dialogs/alert/alert.component';

@Component({
  selector: 'app-form-task',
  templateUrl: './form-task.component.html',
  styleUrl: './form-task.component.css',
  standalone: false,
})
export class FormTaskComponent implements OnInit {
  public isLoading: boolean;
  public typeForm: 'REG' | 'UPD';
  public titleForm: string;
  public formGroup: FormGroup;
  public idWorkflow: string;
  public nextSequence: number = 1;

  public arrUsers: Array<UserResponse>;
  public arrModules: Array<any> = [];
  public arrSubmodules: Array<any> = [];
  public arrFunctions: Array<any> = [];
  public arrActiveWorkflows: Array<ActiveWorkflow> = [];
  public idTask!: string;

  constructor(
    @Inject(MAT_DIALOG_DATA) private detailsFormTask: DetailsFormTask,
    public resourcesService: ResourcesService,
    public interService: InternationalizationService,
    private _processManagementService: ProcessManagementService,
    private _usersProfilesService: UsersProfilesService,
    private _dialog: MatDialog,
    private _dialogRef: MatDialogRef<boolean>,
    private _encService: EncService,
    private _modulesService: ModulesService
  ) {
    this.typeForm = this.detailsFormTask.type;
    this.titleForm =
      this.typeForm === 'REG'
        ? this.interService.get('registro_tarea')
        : this.interService.get('modificacion_tarea');
    this.isLoading = false;
    this.idWorkflow = this.detailsFormTask.idWorkflow || '1';
    this.formGroup = this._createFormGroup();
    this.arrUsers = [];
  }

  private _createFormGroup(): FormGroup {
    return new FormGroup({
      NOMBRE_TAREA: new FormControl(null, Validators.required),
      DESCRIPCION: new FormControl(null, Validators.required),
      SECUENCIA: new FormControl({ value: null, disabled: true }),
      REQUIERE_VALIDACION: new FormControl(false),
      ID_MODULO: new FormControl(null, Validators.required),
      ID_SUBMODULO: new FormControl(
        { value: null, disabled: true },
        Validators.required
      ),
      ID_FUNCION: new FormControl(
        { value: null, disabled: true },
        Validators.required
      ),
      USUARIOS_NOTIFICAR: new FormControl([]),
      USUARIO_VALIDADOR: new FormControl(null),
      REGLA_VALIDACION: new FormControl('NA'),
      ID_WORKFLOW_EJECUTAR: new FormControl(null),
    });
  }

  async ngOnInit() {
    this.isLoading = true;
    await this._getUsers();
    await this._getModules();
    await this._calculateNextSequence();
    // await this.getDataTask();
    this.isLoading = false;

    this.formGroup.controls['REQUIERE_VALIDACION'].valueChanges.subscribe(
      (value) => {
        if (!value) {
          this.formGroup.controls['USUARIO_VALIDADOR'].setValue(null);
          this.formGroup.controls['REGLA_VALIDACION'].setValue('NA');
          this.formGroup.controls['ID_WORKFLOW_EJECUTAR'].setValue(null);
        } else {
          this.formGroup.controls['REGLA_VALIDACION'].setValue('Esperar');
        }
      }
    );

    this.formGroup.controls['REGLA_VALIDACION'].valueChanges.subscribe(
      (value) => {
        if (value === 'Ejecutar') {
          this._getActiveWorkflows();
        } else {
          this.formGroup.controls['ID_WORKFLOW_EJECUTAR'].setValue(null);
        }
      }
    );

    this.formGroup.controls['ID_MODULO'].valueChanges.subscribe((value) => {
      console.log('Valor asignado a MODULO:', value);
      this.arrSubmodules = [];
      this.arrFunctions = [];
      this.formGroup.controls['ID_SUBMODULO'].setValue(null);
      this.formGroup.controls['ID_FUNCION'].setValue(null);

      if (value) {
        this.formGroup.controls['ID_SUBMODULO'].enable();
        setTimeout(() => {
          this._getSubmodules(value);
        }, 100);
      } else {
        this.formGroup.controls['ID_SUBMODULO'].disable();
        this.formGroup.controls['ID_FUNCION'].disable();
      }
    });

    this.formGroup.controls['ID_SUBMODULO'].valueChanges.subscribe((value) => {
      console.log('Valor asignado a ID_SUBMODULO:', value);
      this.arrFunctions = [];
      this.formGroup.controls['ID_FUNCION'].setValue(null);

      if (value) {
        this.formGroup.controls['ID_FUNCION'].enable();
        const moduleId = this.formGroup.controls['ID_MODULO'].value;
        setTimeout(() => {
          this._getFunctions(moduleId, value);
        }, 100);
      } else {
        this.formGroup.controls['ID_FUNCION'].disable();
      }
    });
  }

  private async _getModules() {
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._modulesService.getModules(user, line)).then(
      (responseData: ModulesInterface) => {
        console.log('Respuesta de módulos:', responseData);
        if (!responseData.error) {
          this.arrModules = responseData.response;
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      },
      (httpErrorResponse: HttpErrorResponse) => {
        this.resourcesService.checkErrors(httpErrorResponse);
      }
    );
  }

  private async _getSubmodules(moduleId: string) {
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(
      this._modulesService.getSubmodules(moduleId, user, line)
    ).then(
      (responseData: any) => {
        console.log('Respuesta de submódulos:', responseData);
        if (!responseData.error) {
          this.arrSubmodules = responseData.response;
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      },
      (httpErrorResponse: HttpErrorResponse) => {
        this.resourcesService.checkErrors(httpErrorResponse);
      }
    );
  }

  private async _getFunctions(moduleId: string, submoduleId: string) {
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(
      this._modulesService.getSubmoduleFunctions(
        moduleId,
        submoduleId,
        user,
        line
      )
    ).then(
      (responseData: any) => {
        console.log('Respuesta de funciones:', responseData);
        if (!responseData.error) {
          this.arrFunctions = responseData.response;
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      },
      (httpErrorResponse: HttpErrorResponse) => {
        this.resourcesService.checkErrors(httpErrorResponse);
      }
    );
  }

  private async _calculateNextSequence() {
    if (this.typeForm === 'REG') {
      const user: string = this.resourcesService.getUser();
      const line: number = this.resourcesService.getLineNumber();
      await lastValueFrom(
        this._processManagementService.getTaskByWorkflow(
          this.idWorkflow,
          user,
          line
        )
      ).then(
        (responseData: ResponseDataGetTaskByWorkflow) => {
          if (!responseData.error) {
            this.nextSequence = responseData.response.length + 1;
            this.formGroup.controls['SECUENCIA'].setValue(this.nextSequence);
          }
        },
        (httpErrorResponse: HttpErrorResponse) => {
          this.resourcesService.checkErrors(httpErrorResponse);
        }
      );
    }
  }

  private async _getUsers() {
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._usersProfilesService.getUsers(user, line)).then(
      async (responseData: UsersResponse) => {
        if (!responseData.error) {
          for (let index = 0; index < responseData.response.length; index++) {
            let element = responseData.response[index];
            element.IDUSUARIO = await this._encService.decrypt(
              element.IDUSUARIO
            );
            responseData.response[index] = element;
          }

          this.arrUsers = responseData.response;
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      },
      async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse);
        if (response !== null && response.reload) {
          await this._getUsers();
        }
      }
    );
  }

  //no la modifique para mis propositos por lo que la comentare hasta usarla
  // private async getDataTask() {
  //   if (this.typeForm === 'UPD' && this.detailsFormTask.idTask !== undefined) {
  //     this.idTask = this.detailsFormTask.idTask.toString();

  //     const encTask: string = await this._encService.encrypt(this.idTask);
  //     const user: string = this.resourcesService.getUser();
  //     const line: number = this.resourcesService.getLineNumber();
  //     await lastValueFrom(
  //       this._processManagementService.getTaskById(encTask, user, line)
  //     ).then(
  //       (responseData: ResponseDataTask) => {
  //         if (
  //           !responseData.error &&
  //           Object.keys(responseData.response).length > 0
  //         ) {
  //           this.formGroup.controls['NOMBRE_TAREA'].setValue(
  //             responseData.response.NOMBRE_TAREA
  //           );
  //           this.formGroup.controls['DESCRIPCION'].setValue(
  //             responseData.response.DESCRIPCION
  //           );
  //           this.formGroup.controls['SECUENCIA'].setValue(
  //             responseData.response.SECUENCIA
  //           );

  //           const hasValidation =
  //             responseData.response.USUARIOS_VALIDACION &&
  //             responseData.response.USUARIOS_VALIDACION.length > 0;
  //           this.formGroup.controls['REQUIERE_VALIDACION'].setValue(
  //             hasValidation
  //           );

  //           if (hasValidation) {
  //             const userValidator = this.arrUsers.find(
  //               (user) =>
  //                 user.IDUSUARIO ===
  //                 responseData.response.USUARIOS_VALIDACION[0]
  //             );
  //             this.formGroup.controls['USUARIO_VALIDADOR'].setValue(
  //               userValidator
  //             );
  //           }

  //           const notifyUsers = this.arrUsers.filter((user) =>
  //             responseData.response.NOTIFICAR_USUARIOS.includes(user.IDUSUARIO)
  //           );
  //           this.formGroup.controls['USUARIOS_NOTIFICAR'].setValue(notifyUsers);

  //           this.formGroup.controls['REGLA_VALIDACION'].setValue(
  //             responseData.response.REGLAS_VALIDACION === 'E'
  //               ? 'Ejecutar'
  //               : 'Esperar'
  //           );

  //           // Habilitar controles si tienen valores
  //           if (responseData.response.ID_MODULO) {
  //             this.formGroup.controls['ID_MODULO'].setValue(responseData.response.ID_MODULO);
  //             this.formGroup.controls['ID_SUBMODULO'].enable();

  //             if (responseData.response.ID_SUBMODULO) {
  //               this.formGroup.controls['ID_SUBMODULO'].setValue(responseData.response.ID_SUBMODULO);
  //               this.formGroup.controls['ID_FUNCION'].enable();

  //               if (responseData.response.ID_FUNCION) {
  //                 this.formGroup.controls['ID_FUNCION'].setValue(responseData.response.ID_FUNCION);
  //               }
  //             }
  //           }
  //         } else if (
  //           !responseData.error &&
  //           Object.keys(responseData.response).length === 0
  //         ) {
  //           this.resourcesService.openSnackBar(
  //             `No se encontró información de la tarea.`
  //           );
  //           this._dialogRef.close(false);
  //         } else {
  //           this.resourcesService.openSnackBar(`${responseData.msg}`);
  //           this._dialogRef.close(false);
  //         }
  //       },
  //       async (httpErrorResponse: HttpErrorResponse) => {
  //         let response = this.resourcesService.checkErrors(httpErrorResponse);
  //         if (response !== null && response.reload) {
  //           await this.getDataTask();
  //         }
  //       }
  //     );
  //   }
  // }

  public save() {
    if (this.typeForm === 'REG') {
      this._dialog
        .open(AlertComponent, {
          disableClose: true,
          data: {
            title: this.interService.get('confirmacion'),
            description: this.interService.get('register_task_alert'),
            icon: 'warning',
          },
        })
        .afterClosed()
        .subscribe(async (result) => {
          if (result) {
            await this._registerTask();
          }
        });
    } else if (this.typeForm === 'UPD') {
      this._dialog
        .open(AlertComponent, {
          disableClose: true,
          width: '360px',
          maxWidth: '360px',
          data: {
            title: this.interService.get('confirmacion'),
            description: this.interService.get('update_task_alert'),
            icon: 'warning',
          },
        })
        .afterClosed()
        .subscribe(async (result) => {
          if (result) {
            await this._updateTask();
          }
        });
    } else {
      this.resourcesService.openSnackBar(
        this.interService.get('opcion_no_disponible')
      );
    }
  }

  private async _registerTask() {
    const requestFormTask: RequestFormTask = this._createRequestFormTask();
    await lastValueFrom(
      this._processManagementService.registerTask(requestFormTask)
    ).then(
      (responseData: ResponseData) => {
        if (!responseData.error) {
          this.resourcesService.openSnackBar(this.interService.get('registro_exitoso_tarea'));
          this._dialogRef.close(true);
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      },
      async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse);
        if (response !== null && response.reload) {
          await this._registerTask();
        }
      }
    );
  }

  private _createRequestFormTask(): RequestFormTask {
    const nombreTarea = this.formGroup.controls['NOMBRE_TAREA'].value
      .toString()
      .trim();
    const descripcion = this.formGroup.controls['DESCRIPCION'].value
      .toString()
      .trim();
    const secuencia =
      this.formGroup.controls['SECUENCIA'].value || this.nextSequence;
    const requiereValidacion =
      this.formGroup.controls['REQUIERE_VALIDACION'].value;
    const usuarioValidador = this.formGroup.controls['USUARIO_VALIDADOR'].value;
    const usuariosNotificar =
      this.formGroup.controls['USUARIOS_NOTIFICAR'].value || [];
    const reglaValidacion = this.formGroup.controls['REGLA_VALIDACION'].value;

    const userValidate: string =
      requiereValidacion && usuarioValidador ? usuarioValidador.IDUSUARIO : '';
    const arrUserNotificate: Array<string> = usuariosNotificar.map(
      (user: UserResponse) => user.IDUSUARIO
    );

    const idModulo = this.formGroup.controls['ID_MODULO'].value;
    const idSubmodulo = this.formGroup.controls['ID_SUBMODULO'].value;
    const idFuncion = this.formGroup.controls['ID_FUNCION'].value;
    const idWorkflowEjecutar = this.formGroup.controls['ID_WORKFLOW_EJECUTAR'].value || '';

    const requestFormTask: RequestFormTask = {
      ID_WORKFLOW: this.idWorkflow,
      NOMBRE_TAREA: nombreTarea,
      DESCRIPCION: descripcion,
      SECUENCIA: secuencia,
      REQUIERE_VALIDACION: requiereValidacion,
      ID_MODULO: idModulo,
      ID_SUBMODULO: idSubmodulo,
      ID_FUNCION: idFuncion,
      REGLAS_VALIDACION: reglaValidacion,
      ID_WORKFLOW_EJECUTAR: idWorkflowEjecutar,
      USUARIO_VALIDACION: userValidate,
      NOTIFICAR_USUARIOS: arrUserNotificate,
      USUARIO: this.resourcesService.getUser(),
      NUMERO_LINEA: this.resourcesService.getLineNumber(),
    };

    return requestFormTask;
  }

  private async _updateTask() {
    const encTask: string = await this._encService.encrypt(this.idTask);
    const requestFormTask: RequestFormTask = this._createRequestFormTask();
    await lastValueFrom(
      this._processManagementService.updateTask(encTask, requestFormTask)
    ).then(
      (responseData: ResponseData) => {
        if (!responseData.error) {
          this.resourcesService.openSnackBar(this.interService.get('modificacion_exitosa_tarea'));
          this._dialogRef.close(true);
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      },
      async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse);
        if (response !== null && response.reload) {
          await this._updateTask();
        }
      }
    );
  }

  private async _getActiveWorkflows() {
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(
      this._processManagementService.getActiveWorkflows(user, line)
    ).then(
      (responseData: ResponseDataActiveWorkflows) => {
        if (!responseData.error) {
          this.arrActiveWorkflows = responseData.response;
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      },
      (httpErrorResponse: HttpErrorResponse) => {
        this.resourcesService.checkErrors(httpErrorResponse);
      }
    );
  }
}
