import { Component, OnInit, ViewChild } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { ModuleInterface, ModulesInterface } from '../../interfaces/modules.interface';
import { ComponentInformationCheckbox, ComponentInformationInput, ComponentInformationRadio, ComponentInformationSelect, ComponentInformationTextarea, DataDynamicForm, DataFormComponents, GetFormById, GetTableColumns, GetTables, InformationValidate, RequestForm, ResponseDataGetFormById, ResponseDataGetTables } from '../../interfaces/forms-management/form-management.interface';
import { MatStepper } from '@angular/material/stepper';
import { ResourcesService, ResponseData } from '../../services/resources.service';
import { ModulesService } from '../../services/modules.service';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute } from '@angular/router';
import { EncService } from '../../services/enc.service';
import { DynamicFormService } from '../../services/forms-management/dynamic-form.service';
import { lastValueFrom } from 'rxjs';
import { HttpErrorResponse } from '@angular/common/http';
import { TableManagementFormComponent } from './table-management-form/table-management-form.component';
import { FormColumnsComponent } from './form-columns/form-columns.component';
import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
import { ValidateWhereComponent } from './validate-where/validate-where.component';
import { GenerateDynamicFormComponent } from './generate-dynamic-form/generate-dynamic-form.component';
import { AlertComponent } from '../resources/dialogs/alert/alert.component';
import { ConfigurateInputComponent } from './configurate-input/configurate-input.component';
import { ConfigurateSelectComponent } from './configurate-select/configurate-select.component';
import { ConfigurateCheckboxComponent } from './configurate-checkbox/configurate-checkbox.component';
import { ConfigurateRadioComponent } from './configurate-radio/configurate-radio.component';
import { ConfigurateTextareaComponent } from './configurate-textarea/configurate-textarea.component';
import { ExampleComponentComponent } from './example-component/example-component.component';

@Component({
    selector: 'app-forms-management-form',
    templateUrl: './forms-management-form.component.html',
    styleUrl: './forms-management-form.component.css',
    standalone: false
})
export class FormsManagementFormComponent implements OnInit {

  public isLoading: boolean;

  public formGroupUbication: FormGroup;
  public arrModules: ModuleInterface[];
  public isLoadingFieldModule: boolean;
  
  public formGroupDatabase: FormGroup;
  public arrTablesName: GetTables[];
  public isLoadingFieldTableName: boolean;
  public arrColumnsTable: GetTables[];

  public arrFormItem: string[];
  public arrDataForm: DataFormComponents[];

  public arrColumnsSelected: string[];
  public arrIdentifiers: string[];
  public arrColumnsPersonality: GetTableColumns[];

  public arrInformationValidate: InformationValidate[];

  public title: string;
  public idForm!: string;
  public typeForm!: 'R'|'M';

  public arrDisabledColumns: string[];

  @ViewChild('stepper') stepper!: MatStepper;

  constructor(
    public resourcesService: ResourcesService,
    private _modulesService: ModulesService,
    private _dialog: MatDialog,
    private _activatedRoute: ActivatedRoute,
    private _encService: EncService,
    private _dynamicFormService: DynamicFormService,
  ) {
    this.isLoading = true;

    this.formGroupUbication = this._createFormGroupUbication();
    this.arrModules = [];
    this.isLoadingFieldModule = false;
    this.arrTablesName = [];
    this.isLoadingFieldTableName = false;
    this.arrColumnsTable = [];
    this.formGroupDatabase = this._createFormGroupDatabase();
    this.arrFormItem = ['INPUT', 'SELECT', 'CHECKBOX', 'RADIO', 'TEXTAREA'];
    this.arrDataForm = [];
    this.arrColumnsSelected = [];
    this.arrIdentifiers = [];
    this.arrColumnsPersonality = [];
    this.arrInformationValidate = [];
    this.title = '...';
    this.arrDisabledColumns = [];
  }
  
  async ngOnInit() {
    this.isLoading = true;
    await this._getModules();
    await this._getTablesName();
    await this._getInfoForm();
    this.isLoading = false;

    this.formGroupDatabase.controls['TABLA'].valueChanges.subscribe((table: string[]) => {
      if (table.length === 0) {
        this.formGroupDatabase.controls['COLUMNAS'].disable();
      } else {
        this.formGroupDatabase.controls['COLUMNAS'].enable();
      }
      this.arrColumnsTable = this.arrTablesName.filter((element: GetTables) => table.includes(element.NOMBRE_TABLA) );
    });

    this.formGroupDatabase.controls['COLUMNAS'].valueChanges.subscribe((arrColumnSelected) => {
      
      let arrRemoveDataForm: number[] = [];
      for (let index = 0; index < this.arrDataForm.length; index++) {
        const DATA_FORM: DataFormComponents = this.arrDataForm[index];
        if (DATA_FORM.COMPONENT.COLUMNA.includes('(personalizado)')) {

          let exists: boolean = false;

          for (const COLUMNS of arrColumnSelected) {
            if (DATA_FORM.COMPONENT.COLUMNA === COLUMNS) {
              exists = true;
            }
          }
          if (!exists) {
            arrRemoveDataForm.push(index);
          }
        }
      }

      if (arrRemoveDataForm.length > 0) {
        let msg: string = 'El componente ';
        for (const INDEX_REMOVE of arrRemoveDataForm) {
          const COMPONENTE: string = this.arrDataForm[INDEX_REMOVE].TYPE_COMPONENT;
          const ETIQUETA: string = this.arrDataForm[INDEX_REMOVE].COMPONENT.ETIQUETA;
          const COLUMNA: string = this.arrDataForm[INDEX_REMOVE].COMPONENT.COLUMNA;

          msg += ` ${COMPONENTE} con el nombre ${ETIQUETA}, `;
          this.deleteDataForm(INDEX_REMOVE);

          const COLUMNS_CONTROL: string[] = this.formGroupDatabase.controls['COLUMNAS'].value;
          const FITLER_COLUMNS:string[] = COLUMNS_CONTROL.filter((column) => column !== COLUMNA )
          this.formGroupDatabase.controls['COLUMNAS'].setValue(FITLER_COLUMNS);

        }
        msg = msg.substring(0, msg.length - 2);
        msg += ' serán removidos debído a que su columna fue eliminada.';
        this.resourcesService.openSnackBar(msg);
      }
      
    })
  }

  private _createFormGroupUbication(): FormGroup {
    return new FormGroup({
      MODULO: new FormControl(null, Validators.required),
      REGISTRO_FORMULARIO: new FormControl(null, Validators.required),
      MODIFICA_FORMULARIO: new FormControl(null, Validators.required),
    });
  }

  private _createFormGroupDatabase(): FormGroup {
    return new FormGroup({
      TABLA: new FormControl([], Validators.required),
      COLUMNAS: new FormControl({ value: [], disabled: true }, Validators.required),
    });
  }

  private async _getModules() {
    this.isLoadingFieldModule = true;
    const USER: string = this.resourcesService.getUser();
    const LINE: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._modulesService.getModules(USER, LINE)).then(
      (responseData: ModulesInterface) => {
        if ( !responseData.error ) {
          console.log(responseData.response);
          this.arrModules = responseData.response;
        } else {
          this.resourcesService.openSnackBar(`${ responseData.msg }`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this._getModules();
        }
      }
    );
    this.isLoadingFieldModule = false;
  }

  private async _getTablesName() {
    const USER: string = this.resourcesService.getUser();
    const LINE: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._dynamicFormService.getTables(USER, LINE)).then(
      (responseData: ResponseDataGetTables) => {        
        if (!responseData.error) {
          this.arrTablesName = responseData.response;
          this.formGroupDatabase.controls['COLUMNAS'].enable();
          this.arrColumnsTable = responseData.response;
          
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this._getTablesName();
        }
      }
    );
  }

  private async _getInfoForm() {
    const FORM:string | null = this._activatedRoute.snapshot.paramMap.get('form');
    if (FORM !== null) {
      
      const STR_FORM: string = await this._encService.decrypt(FORM);
      const DATA_FORM = JSON.parse(STR_FORM);

      this.typeForm = DATA_FORM.TYPE_FORM;
      
      if (this.typeForm === 'R') {
        this.title = `Creación de formulario dinámico`;
      } else if (this.typeForm === 'M') {
        this.title = `Modificación del formulario dinámico`;
        this.idForm = DATA_FORM.ID_FORM;

        await this._getFormById(this.idForm);
      } else {
        this.resourcesService.openSnackBar(`Opción del tipo de formulario no disponible.`);
        this.resourcesService.goBack();
      }

    } else {
      this.resourcesService.openSnackBar(`Ocurrió un error al obtener los datos del formulario.`);
      this.resourcesService.goBack();
    }
  }

  private async _getFormById(idForm: string) {

    const ID_FORM: string = await this._encService.encrypt(idForm);
    const USUARIO: string = this.resourcesService.getUser();
    const NUMERO_LINEA: number = this.resourcesService.getLineNumber();

    await lastValueFrom(this._dynamicFormService.getFormById(ID_FORM, USUARIO, NUMERO_LINEA)).then(
      (responseData: ResponseDataGetFormById) => {
        if (!responseData.error) {

          const GETFORM: GetFormById = responseData.response;

          this.formGroupUbication.controls['MODULO'].setValue(GETFORM.ID_MODULO);
          this.formGroupUbication.controls['REGISTRO_FORMULARIO'].setValue(GETFORM.TITULO_REGISTRO);
          this.formGroupUbication.controls['MODIFICA_FORMULARIO'].setValue(GETFORM.TITULO_MODIFICACION);

          this.formGroupDatabase.controls['TABLA'].setValue(GETFORM.DATOS_FORMULARIO.DATA_BASE.TABLA);
          
          this.arrDisabledColumns = GETFORM.DATOS_FORMULARIO.DATA_BASE.COLUMNAS
          this.formGroupDatabase.controls['COLUMNAS'].setValue(GETFORM.DATOS_FORMULARIO.DATA_BASE.COLUMNAS);
          this.arrColumnsPersonality = GETFORM.DATOS_FORMULARIO.PERSONALITY_COLUMNS;

          this.arrDataForm = GETFORM.DATOS_FORMULARIO.COMPONENTS;
          this.arrInformationValidate = GETFORM.DATOS_FORMULARIO.INFO_VALIDATE;
          
          this.arrColumnsSelected = [... GETFORM.DATOS_FORMULARIO.DATA_BASE.COLUMNAS];
          this.arrIdentifiers = GETFORM.DATOS_FORMULARIO.COMPONENTS.map((dataFormComponents: DataFormComponents) => dataFormComponents.COMPONENT.IDENTIFICADOR);
          
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this._getFormById(idForm);
        }
      }
    );
  }

  private deleteDataForm(index: number) {
    const DATA_FORM: DataFormComponents[] = this.arrDataForm.filter((dataForm: DataFormComponents, idxDataForm: number) => idxDataForm !== index);
    this.arrDataForm = DATA_FORM;
  }

  public openCreateTable () {
    this._dialog.open(TableManagementFormComponent, {
      data: {
        TYPE_ACTION: 'R'
      },
      width: '400px',
      minWidth: '400px',
      disableClose: true,
    }).afterClosed().subscribe(async (response) => {
      if (response) {
        await this._getTablesName()
      }
    })
  }

  public disabledColumnNative(dataColumn: string) {

    if (this.typeForm === 'M') {
      return !dataColumn.includes(`(personalizado)`)
    }

    return false;
  }

  public formColumns() {

    if (!this.isLoading) {
      const ARR_TABLES_SELECTED: string[] = this.formGroupDatabase.controls['TABLA'].value;
      const ARR_COLUMNS_GENERAL: GetTables[] = this.arrColumnsTable;
      const ARR_TABLE_COLUMNS: GetTableColumns[] = this.arrColumnsPersonality;
  
      this._dialog.open(FormColumnsComponent, {
        data: {
          TABLES_SELECTED: ARR_TABLES_SELECTED,
          COLUMNS_GENERAL: ARR_COLUMNS_GENERAL,
          INFO_PERSONALITY: ARR_TABLE_COLUMNS,
        },
        disableClose: true,
        width: '450px',
      minWidth: '450px',
      }).afterClosed().subscribe((response: false | GetTableColumns[]) => {
        
        if (response) {
          this.arrColumnsPersonality = response;
          let arrRemoveDataForm: number[] = [];
          for (let index = 0; index < this.arrDataForm.length; index++) {
            const DATA_FORM: DataFormComponents = this.arrDataForm[index];
            if (DATA_FORM.COMPONENT.COLUMNA.includes('(personalizado)')) {

              let exists: boolean = false;

              for (const TABLE_COLUMNS of this.arrColumnsPersonality) {
                for (const FORM_COLUMNS of TABLE_COLUMNS.COLUMNS) {
                  if (DATA_FORM.COMPONENT.COLUMNA === FORM_COLUMNS.COLUMN) {
                    exists = true;
                  }
                }
              }

              if (!exists) {
                arrRemoveDataForm.push(index);
              }
            }
          }

          if (arrRemoveDataForm.length > 0) {
            let msg: string = 'El componente ';
            for (const INDEX_REMOVE of arrRemoveDataForm) {
              const COMPONENTE: string = this.arrDataForm[INDEX_REMOVE].TYPE_COMPONENT;
              const ETIQUETA: string = this.arrDataForm[INDEX_REMOVE].COMPONENT.ETIQUETA;
              const COLUMNA: string = this.arrDataForm[INDEX_REMOVE].COMPONENT.COLUMNA;

              msg += ` ${COMPONENTE} con el nombre ${ETIQUETA}, `;
              this.deleteDataForm(INDEX_REMOVE);

              const COLUMNS_CONTROL: string[] = this.formGroupDatabase.controls['COLUMNAS'].value;
              const FITLER_COLUMNS:string[] = COLUMNS_CONTROL.filter((column) => column !== COLUMNA )
              this.formGroupDatabase.controls['COLUMNAS'].setValue(FITLER_COLUMNS);

            }
            msg = msg.substring(0, msg.length - 2);
            msg += ' serán removidos debído a que su columna fue eliminada.';
            this.resourcesService.openSnackBar(msg);
          }
        }
      });
    }
  }

  public dropItems(event: CdkDragDrop<string[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex,
      );
    }
  }

  public registerColumnsValidation() {

    const TABLE_CONTROL: string[] = this.formGroupDatabase.controls['TABLA'].value;
    const COLUMN_CONTROL: string[] = this.formGroupDatabase.controls['COLUMNAS'].value;

    
    let arrTables: string[] = [];
    for(const TABLE of TABLE_CONTROL) {

      let exists: boolean = false;
      for(const INFO_VALIDATE of this.arrInformationValidate) {
        if (INFO_VALIDATE.TABLA === TABLE) {
          exists = true;
        }
      }

      if (!exists) {
        arrTables.push(TABLE)
      }
      
    }

    if (arrTables.length === 0) {
      this.resourcesService.openSnackBar(`Las valdaciones de las tablas seleccionadas ya fueron completadas.`);
      return;
    }

    this._dialog.open(ValidateWhereComponent, {
      data: {
        TABLES: arrTables,
        COLUMNS: COLUMN_CONTROL,
      }
    }).afterClosed().subscribe((response) => {
      if (response) {
        this.arrInformationValidate.push(response);
        
      }
    });
  }

  public validaeColumnsValidation(): boolean {
    const TABLE_CONTROL: string[] = this.formGroupDatabase.controls['TABLA'].value;
    let arrTables: string[] = [];
    for(const TABLE of TABLE_CONTROL) {

      let exists: boolean = false;
      for(const INFO_VALIDATE of this.arrInformationValidate) {
        if (INFO_VALIDATE.TABLA === TABLE) {
          exists = true;
        }
      }

      if (!exists) {
        arrTables.push(TABLE)
      }
    }
    return arrTables.length === 0;
  }

  public deleteColumnsValidation(idxTable: number) {
    const VALIDTE_INFORMATION: InformationValidate[] = this.arrInformationValidate.filter((informationValidate: InformationValidate, index: number) => idxTable !== index);
    this.arrInformationValidate = VALIDTE_INFORMATION;
  }

  public openGenerateExampleRegister() {

    const DATA_DYNAMIC_FORM: DataDynamicForm = {
      TYPE_FORM: 'R',
      TYPE_DIALOG: 'EXAMPLE',
      INFO_FORM: {
        TITLE: this.formGroupUbication.controls['REGISTRO_FORMULARIO'].value,
        COMPONENTS: this.arrDataForm,
      },
      DEFAULT_VALUE: [],
    }

    this._dialog.open(GenerateDynamicFormComponent, {
      data: DATA_DYNAMIC_FORM,
      disableClose: true,
      width: '800px',
      minWidth: '800px',
    }).afterClosed().subscribe((response) => {

    });
  }

  public openGenerateExampleUpdate() {
    const DATA_DYNAMIC_FORM: DataDynamicForm = {
      TYPE_FORM: 'M',
      TYPE_DIALOG: 'EXAMPLE',
      INFO_FORM: {
        TITLE: this.formGroupUbication.controls['MODIFICA_FORMULARIO'].value,
        COMPONENTS: this.arrDataForm,
      },
      DEFAULT_VALUE: []
    }

    this._dialog.open(GenerateDynamicFormComponent, {
      data: DATA_DYNAMIC_FORM,
      disableClose: true,
      width: '800px',
      minWidth: '800px',
    }).afterClosed().subscribe((response) => {

    });
  }

  public save() {
    this._dialog.open(AlertComponent, {
      data: {
        title: `Confirmación`,
        description: `¿Está seguro de guardar los datos del formuario?`,
        icon: `warning`
      }
    }).afterClosed().subscribe(async (response) => {
      if (response) {
        if (this.typeForm === 'R') {
          await this.registerForm();
        } else if (this.typeForm === 'M') { 
          await this.updateForm();
        } else {
          this.resourcesService.openSnackBar(`Opción no disponible`)
        }
      }
    })
  }

  public async registerForm () {
    const REQUEST_FORM = await this._createRequestForm();
    await lastValueFrom(this._dynamicFormService.registerForms(REQUEST_FORM)).then(
      (responseData: ResponseData) => {
        if (!responseData.error) {
          this.resourcesService.openSnackBar(`¡Registro exitoso!`);
          this.resourcesService.goBack();
        } else {
          this.resourcesService.openSnackBar(`${ responseData.msg }`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.registerForm();
        }
      }
    );
  }

  private async _createRequestForm(): Promise<RequestForm> {

    let MODULO = this.formGroupUbication.controls['MODULO'].value;
    MODULO = await this._encService.decrypt(MODULO);
    let REGISTRO_FORMULARIO = this.formGroupUbication.controls['REGISTRO_FORMULARIO'].value;
    REGISTRO_FORMULARIO = REGISTRO_FORMULARIO.toString().trim();
    let MODIFICA_FORMULARIO = this.formGroupUbication.controls['MODIFICA_FORMULARIO'].value;
    MODIFICA_FORMULARIO = MODIFICA_FORMULARIO.toString().trim();
    let TABLA = this.formGroupDatabase.controls['TABLA'].value;
    let COLUMNAS = this.formGroupDatabase.controls['COLUMNAS'].value;

    const DATA_FORM = this.arrDataForm;
    const INFO_VALIDATE = this.arrInformationValidate;
    const PERSONALITY_COLUMNS = this.arrColumnsPersonality;

    const REQUEST_DATA: RequestForm = {
      MODULO: MODULO,
      REGISTRO_FORMULARIO: REGISTRO_FORMULARIO,
      MODIFICA_FORMULARIO: MODIFICA_FORMULARIO,
      TABLA: TABLA,
      COLUMNAS: COLUMNAS,
      DATA_FORM: DATA_FORM,
      INFO_VALIDATE: INFO_VALIDATE,
      PERSONALITY_COLUMNS: PERSONALITY_COLUMNS,
      NUMERO_LINEA: this.resourcesService.getLineNumber(),
      USUARIO: this.resourcesService.getUser()
    }

    return REQUEST_DATA;
  }

  public async updateForm () {
    const REQUEST_FORM = await this._createRequestForm();
    const ID_FORM: string = await this._encService.encrypt(this.idForm);
    await lastValueFrom(this._dynamicFormService.updateForms(ID_FORM, REQUEST_FORM)).then(
      (responseData: ResponseData) => {
      if (!responseData.error) {
        this.resourcesService.openSnackBar(`¡Modificación exitosa!`);
        this.resourcesService.goBack();
      } else {
        this.resourcesService.openSnackBar(`${ responseData.msg }`);
      }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.updateForm();
        }
      }
    );
  }

  public drop(event: CdkDragDrop<DataFormComponents[]>) {
    
    if (event.container.id === 'cdk-drop-list-1' && event.previousContainer.id === 'cdk-drop-list-0') {
      
      this.arrFormItem = ['INPUT', 'SELECT', 'CHECKBOX', 'RADIO', 'TEXTAREA'];
      // Se obtiene el tipo de componente
      const TYPE_FORM: string = this.arrFormItem[event.previousIndex];

      // Se obtiene el arreglo de las columnas seleccionadas
      const COLUMN_FORM: string[] = this.formGroupDatabase.controls['COLUMNAS'].value;
      // Se obtiene las columas disponibles, quitando las columnas seleccionadas
      const COLUMNS = COLUMN_FORM.filter((columnForm: string) => !this.arrColumnsSelected.includes(columnForm));


      let isEnabled: boolean = true;

      switch (TYPE_FORM) {
        case 'INPUT':
          this._dialog.open(ConfigurateInputComponent, {
            data: {
              COLUMNS: COLUMNS,
              IDS: this.arrIdentifiers,
              TYPE_FORM: this.typeForm,
              ENABLED: isEnabled,
            },
            disableClose: true,
            width: '850px',
            minWidth: '850px',
          }).afterClosed().subscribe((response: false | ComponentInformationInput) => {
            if (response) {
              this._move(event);
              this.arrDataForm[event.currentIndex] = {
                TYPE_COMPONENT: TYPE_FORM,
                COMPONENT: response
              }
              this.arrColumnsSelected.push(response.COLUMNA);
              this.arrIdentifiers.push(response.IDENTIFICADOR);
            }
          });
          break;
        case 'SELECT':
          this._dialog.open(ConfigurateSelectComponent, {
            data: {
              COLUMNS: COLUMNS,
              IDS: this.arrIdentifiers,
              TYPE_FORM: this.typeForm,
              ENABLED: isEnabled,
            },
            disableClose: true,
            width: '850px',
            minWidth: '850px',
          }).afterClosed().subscribe((response: false | ComponentInformationSelect) => {
            if (response) {
              this._move(event);
              this.arrDataForm[event.currentIndex] = {
                TYPE_COMPONENT: TYPE_FORM,
                COMPONENT: response
              }
              this.arrColumnsSelected.push(response.COLUMNA);
              this.arrIdentifiers.push(response.IDENTIFICADOR);
            }
          });
          break;
        case 'CHECKBOX':
          this._dialog.open(ConfigurateCheckboxComponent, {
            data: {
              COLUMNS: COLUMNS,
              IDS: this.arrIdentifiers,
              TYPE_FORM: this.typeForm,
              ENABLED: isEnabled,
            },
            disableClose: true,
            width: '850px',
            minWidth: '850px',
          }).afterClosed().subscribe((response) => {
            if (response) {
              this._move(event);
              this.arrDataForm[event.currentIndex] = {
                TYPE_COMPONENT: TYPE_FORM,
                COMPONENT: response
              }
              this.arrColumnsSelected.push(response.COLUMNA);
              this.arrIdentifiers.push(response.IDENTIFICADOR);
            }
          });
          break;
        case 'RADIO':
          this._dialog.open(ConfigurateRadioComponent, {
            data: {
              COLUMNS: COLUMNS,
              IDS: this.arrIdentifiers,
              TYPE_FORM: this.typeForm,
              ENABLED: isEnabled,
            },
            disableClose: true,
            width: '850px',
            minWidth: '850px',
          }).afterClosed().subscribe((response) => {
            if (response) {
              this._move(event);
              this.arrDataForm[event.currentIndex] = {
                TYPE_COMPONENT: TYPE_FORM,
                COMPONENT: response
              }
              this.arrColumnsSelected.push(response.COLUMNA);
              this.arrIdentifiers.push(response.IDENTIFICADOR);
            }
          });
          break;
        case 'TEXTAREA':
          this._dialog.open(ConfigurateTextareaComponent, {
            data: {
              COLUMNS: COLUMNS,
              IDS: this.arrIdentifiers,
              TYPE_FORM: this.typeForm,
              ENABLED: isEnabled,
            },
            disableClose: true,
            width: '850px',
            minWidth: '850px',
          }).afterClosed().subscribe((response) => {
            if (response) {              
              this._move(event);
              this.arrDataForm[event.currentIndex] = {
                TYPE_COMPONENT: TYPE_FORM,
                COMPONENT: response
              }
              this.arrColumnsSelected.push(response.COLUMNA);
              this.arrIdentifiers.push(response.IDENTIFICADOR);
            }
          });
          break;
        default:
          this.resourcesService.openSnackBar(`Opción no disponible`);
          return;
      }

    } else {
      this._move(event);
    }
  }

  private _move(event: CdkDragDrop<DataFormComponents[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex,
      );
    }
    this.arrFormItem = ['INPUT', 'SELECT', 'CHECKBOX', 'RADIO', 'TEXTAREA'];
  }

  public updateDataForm(index: number) {

    // Se obtiene el tipo de componente
    const TYPE_FORM: string = this.arrDataForm[index].TYPE_COMPONENT;

    // Se obtiene el arreglo de las columnas seleccionadas
    const COLUMN_FORM: string[] = this.formGroupDatabase.controls['COLUMNAS'].value;
    // Se obtiene el nombre de la columnas seleccionada
    const COLUMNA_SELECTED: string = this.arrDataForm[index].COMPONENT.COLUMNA;
    // Se obtiene las columas disponibles, quitando las columnas seleccionadas
    const COLUMNS: string[] = COLUMN_FORM.filter((columnForm: string) => !this.arrColumnsSelected.includes(columnForm) || columnForm === COLUMNA_SELECTED);

    // Se obtiene el identificador del componente
    const ID_SELECTED: string = this.arrDataForm[index].COMPONENT.IDENTIFICADOR;
    // Se obtiene los identificadores, quitando el del componente
    const IDS: string[] = this.arrIdentifiers.filter((id: string) => id !== ID_SELECTED);   
    
    let isEnabled: boolean = false;
    if (this.arrDataForm[index].COMPONENT.COLUMNA.includes('(personalizado)')) {
      isEnabled = true;
    }

    switch (TYPE_FORM) {
      case 'INPUT':
        this._dialog.open(ConfigurateInputComponent, {
          data: {
            COLUMNS: COLUMNS,
            IDS: IDS,
            COMPONENTS: this.arrDataForm[index].COMPONENT,
            TYPE_FORM: this.typeForm,
            ENABLED: isEnabled,
          },
          disableClose: true,
          width: '850px',
          minWidth: '850px',
        }).afterClosed().subscribe((response: false | ComponentInformationInput) => {
          if (response) {
            const INDEX_COLUMN: number = this.arrColumnsSelected.findIndex((column: string) => column === this.arrDataForm[index].COMPONENT.COLUMNA)
            this.arrColumnsSelected[INDEX_COLUMN] = response.COLUMNA;

            const INDEX_ID: number = this.arrIdentifiers.findIndex((id: string) => id === this.arrDataForm[index].COMPONENT.IDENTIFICADOR)
            this.arrIdentifiers[INDEX_ID] = response.IDENTIFICADOR;

            this.arrDataForm[index] = {
              TYPE_COMPONENT: TYPE_FORM,
              COMPONENT: response
            }
          }
        });
        break;
      case 'SELECT':
        this._dialog.open(ConfigurateSelectComponent, {
          data: {
            COLUMNS: COLUMNS,
            IDS: IDS,
            COMPONENTS: this.arrDataForm[index].COMPONENT,
            TYPE_FORM: this.typeForm,
            ENABLED: isEnabled,
          },
          disableClose: true,
          width: '850px',
          minWidth: '850px',
        }).afterClosed().subscribe((response) => {
          if (response) {
            const INDEX_COLUMN: number = this.arrColumnsSelected.findIndex((column: string) => column === this.arrDataForm[index].COMPONENT.COLUMNA)
            this.arrColumnsSelected[INDEX_COLUMN] = response.COLUMNA;

            const INDEX_ID: number = this.arrIdentifiers.findIndex((id: string) => id === this.arrDataForm[index].COMPONENT.IDENTIFICADOR)
            this.arrIdentifiers[INDEX_ID] = response.IDENTIFICADOR;

            this.arrDataForm[index] = {
              TYPE_COMPONENT: TYPE_FORM,
              COMPONENT: response
            }
          }
        });
        break;
      case 'CHECKBOX':
        this._dialog.open(ConfigurateCheckboxComponent, {
          data: {
            COLUMNS: COLUMNS,
            IDS: IDS,
            COMPONENTS: this.arrDataForm[index].COMPONENT,
            TYPE_FORM: this.typeForm,
            ENABLED: isEnabled,
          },
          disableClose: true,
          width: '850px',
          minWidth: '850px',
        }).afterClosed().subscribe((response) => {
          if (response) {
            const INDEX_COLUMN: number = this.arrColumnsSelected.findIndex((column: string) => column === this.arrDataForm[index].COMPONENT.COLUMNA)
            this.arrColumnsSelected[INDEX_COLUMN] = response.COLUMNA;

            const INDEX_ID: number = this.arrIdentifiers.findIndex((id: string) => id === this.arrDataForm[index].COMPONENT.IDENTIFICADOR)
            this.arrIdentifiers[INDEX_ID] = response.IDENTIFICADOR;

            this.arrDataForm[index] = {
              TYPE_COMPONENT: TYPE_FORM,
              COMPONENT: response
            }
          }
        });
        break;
      case 'RADIO':
        this._dialog.open(ConfigurateRadioComponent, {
          data: {
            COLUMNS: COLUMNS,
            IDS: IDS,
            COMPONENTS: this.arrDataForm[index].COMPONENT,
            TYPE_FORM: this.typeForm,
            ENABLED: isEnabled,
          },
          disableClose: true,
          width: '850px',
          minWidth: '850px',
        }).afterClosed().subscribe((response) => {
          if (response) {
            const INDEX_COLUMN: number = this.arrColumnsSelected.findIndex((column: string) => column === this.arrDataForm[index].COMPONENT.COLUMNA)
            this.arrColumnsSelected[INDEX_COLUMN] = response.COLUMNA;

            const INDEX_ID: number = this.arrIdentifiers.findIndex((id: string) => id === this.arrDataForm[index].COMPONENT.IDENTIFICADOR)
            this.arrIdentifiers[INDEX_ID] = response.IDENTIFICADOR;

            this.arrDataForm[index] = {
              TYPE_COMPONENT: TYPE_FORM,
              COMPONENT: response
            }
          }
        });
        break;
      case 'TEXTAREA':
        this._dialog.open(ConfigurateTextareaComponent, {
          data: {
            COLUMNS: COLUMNS,
            IDS: IDS,
            COMPONENTS: this.arrDataForm[index].COMPONENT,
            TYPE_FORM: this.typeForm,
            ENABLED: isEnabled,
          },
          disableClose: true,
          width: '850px',
          minWidth: '850px',
        }).afterClosed().subscribe((response) => {
          if (response) {
            const INDEX_COLUMN: number = this.arrColumnsSelected.findIndex((column: string) => column === this.arrDataForm[index].COMPONENT.COLUMNA)
            this.arrColumnsSelected[INDEX_COLUMN] = response.COLUMNA;

            const INDEX_ID: number = this.arrIdentifiers.findIndex((id: string) => id === this.arrDataForm[index].COMPONENT.IDENTIFICADOR)
            this.arrIdentifiers[INDEX_ID] = response.IDENTIFICADOR;

            this.arrDataForm[index] = {
              TYPE_COMPONENT: TYPE_FORM,
              COMPONENT: response
            }
          }
        });
        break;
      default:
        this.resourcesService.openSnackBar(`Opción no disponible`);
        return;
    }
  }

  public openExample(index: number) {

    const TYPE_COMPONENT: "SELECT" | "INPUT" | "CHECKBOX" | "RADIO" | "TEXTAREA" = this.arrDataForm[index].TYPE_COMPONENT;
    switch (TYPE_COMPONENT) {
      case "INPUT":
        const COMPONENT_INPUT:ComponentInformationInput = this.arrDataForm[index].COMPONENT as ComponentInformationInput;
        this._dialog.open(ExampleComponentComponent, {
          data: {
            TYPE_COMPONENT: TYPE_COMPONENT,
            COMPONENT: COMPONENT_INPUT
          },
          width: '500px',
          minWidth: '500px',
        });

        break;
      case "SELECT":
        const COMPONENT_SELECT:ComponentInformationSelect = this.arrDataForm[index].COMPONENT as ComponentInformationSelect;
        this._dialog.open(ExampleComponentComponent, {
          data: {
            TYPE_COMPONENT: TYPE_COMPONENT,
            COMPONENT: COMPONENT_SELECT
          },
          width: '500px',
          minWidth: '500px',
        });

        break;
      case "CHECKBOX":
        const COMPONENT_CHECKBOX:ComponentInformationCheckbox = this.arrDataForm[index].COMPONENT as ComponentInformationCheckbox;
        this._dialog.open(ExampleComponentComponent, {
          data: {
            TYPE_COMPONENT: TYPE_COMPONENT,
            COMPONENT: COMPONENT_CHECKBOX
          },
          width: '500px',
          minWidth: '500px',
        });
        
        break;
      case "RADIO":
        const COMPONENT_RADIO:ComponentInformationRadio = this.arrDataForm[index].COMPONENT as ComponentInformationRadio;
        this._dialog.open(ExampleComponentComponent, {
          data: {
            TYPE_COMPONENT: TYPE_COMPONENT,
            COMPONENT: COMPONENT_RADIO
          },
          width: '500px',
          minWidth: '500px',
        });
        
        break;
      case "TEXTAREA":
        const COMPONENT_TEXTAREA:ComponentInformationTextarea = this.arrDataForm[index].COMPONENT as ComponentInformationTextarea;
        this._dialog.open(ExampleComponentComponent, {
          data: {
            TYPE_COMPONENT: TYPE_COMPONENT,
            COMPONENT: COMPONENT_TEXTAREA
          },
          width: '500px',
          minWidth: '500px',
        });

        break;
    
      default:
        break;
    }
  }

  public alertDeleteDataForm(index: number) {
    this._dialog.open(AlertComponent, {
      data: {
        title: `Confirmación`,
        description: `¿Está seguro de eliminar el componente?`,
        icon: `warning`
      },
      disableClose: true,
    }).afterClosed().subscribe((result) => {
      if (result) {
        this.deleteDataForm(index);
      }
    });
  }
}
