import { AfterViewInit, Component, Inject, OnInit, ViewChild } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { UserResponse, UsersResponse } from '../../../interfaces/users.interface';
import { MatStepper } from '@angular/material/stepper';
import { MatTableDataSource } from '@angular/material/table';
import { ComponentInformationRadio, DataDialogComponentRadio, FormDataPersonality, TypeFormDataPersonality } from '../../../interfaces/forms-management/form-management.interface';
import { MatPaginator } from '@angular/material/paginator';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { ResourcesService } from '../../../services/resources.service';
import { UsersProfilesService } from '../../../services/users-profiles.service';
import { EncService } from '../../../services/enc.service';
import { lastValueFrom } from 'rxjs';
import { HttpErrorResponse } from '@angular/common/http';
import { ExampleComponentComponent } from '../example-component/example-component.component';
import { AlertComponent } from '../../resources/dialogs/alert/alert.component';

@Component({
    selector: 'app-configurate-radio',
    templateUrl: './configurate-radio.component.html',
    styleUrl: './configurate-radio.component.css',
    standalone: false
})
export class ConfigurateRadioComponent implements OnInit, AfterViewInit {

  public isLoading: boolean;
  public formGroup: FormGroup;
  public arrColumns: string[];
  public arrUsers: UserResponse[];

  @ViewChild('stepper') stepper!: MatStepper;
  public getIndexStep: number;

  public formGroupValues: FormGroup;
  public dataSourceValues: MatTableDataSource<FormDataPersonality>;
  @ViewChild(MatPaginator) paginator!: MatPaginator;
  public displayedColumnsValue: string[];
  public typeFormDataValues: TypeFormDataPersonality;
  public isLoadingValue: boolean;
  public typeForm: 'R' | 'M';

  constructor(
    @Inject(MAT_DIALOG_DATA) public infoDataForm: DataDialogComponentRadio,
    public resourcesService: ResourcesService,
    private _usersProfilesService: UsersProfilesService,
    private _encService: EncService,
    private _dialog: MatDialog,
    private _dialogRef: MatDialogRef<false | ComponentInformationRadio>,
  ) {
    this.isLoading = false;
    this.formGroup = this._createFormGroup();
    this.arrColumns = infoDataForm.COLUMNS;
    this.arrUsers = [];
    this.formGroupValues = this._createFormGroupValues();
    this.typeFormDataValues = { TYPE_FORM: 'R' };
    this.dataSourceValues = new MatTableDataSource<FormDataPersonality>();
    this.displayedColumnsValue = [ 'NO', 'VALOR', 'NOMBRE', 'ACCIONES' ];
    this.getIndexStep = 0;
    this.isLoadingValue = false;
    this.typeForm = this.infoDataForm.TYPE_FORM;
  }
  
  async ngOnInit() {
    this.isLoading = true;
    await this._getUsers();
    await this._getInformationComponent();
    this.isLoading = false;
  }
  
  ngAfterViewInit() {
    this.dataSourceValues.paginator = this.paginator;
  }

  private _createFormGroup() {
    return new FormGroup({
      COLUMNA: new FormControl(null, Validators.required),
      ETIQUETA: new FormControl(null, Validators.required),
      IDENTIFICADOR: new FormControl(null, Validators.required),
      NOMBRE_CAMPO: new FormControl(null, Validators.required),
      REQUERIDO: new FormControl(null),
      DESHABILITAR: new FormControl(null),
      PERMISOS: new FormControl([], Validators.required),
      TAMANO_COLUMNA: new FormControl(12, Validators.required),
    });
  }

  private _createFormGroupValues() {
    return new FormGroup({
      VALOR_CAMPO: new FormControl(null, Validators.required),
      NOMBRE_CAMPO: new FormControl(null, Validators.required),
    });
  }

  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 ) {
          this.arrUsers = [];
          for(const user of responseData.response){
            user.IDUSUARIO = await this._encService.decrypt(user.IDUSUARIO);
            this.arrUsers.push(user);
          }
        } else {
          this.resourcesService.openSnackBar(`${ responseData.msg }`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this._getUsers();
        }
      }
    );
  }

  private async _getInformationComponent() {
    if (this.infoDataForm.COMPONENTS !== undefined) { 
      const COMPONENTS: ComponentInformationRadio = this.infoDataForm.COMPONENTS;

      this.formGroup.controls['COLUMNA'].setValue(COMPONENTS.COLUMNA);
      if (this.infoDataForm.ENABLED) {
        this.formGroup.controls['COLUMNA'].enable();
      } else {
        this.formGroup.controls['COLUMNA'].disable();
      }
      this.formGroup.controls['ETIQUETA'].setValue(COMPONENTS.ETIQUETA);
      this.formGroup.controls['IDENTIFICADOR'].setValue(COMPONENTS.IDENTIFICADOR);
      this.formGroup.controls['NOMBRE_CAMPO'].setValue(COMPONENTS.NOMBRE_CAMPO);
      this.formGroup.controls['REQUERIDO'].setValue(COMPONENTS.REQUERIDO);
      this.formGroup.controls['DESHABILITAR'].setValue(COMPONENTS.DESHABILITAR);
      let USER_PERMISSION: string[] = [];
      for (const userPermission of COMPONENTS.PERMISOS) {
        const USER: string = await this._encService.decrypt(userPermission);
        USER_PERMISSION.push(USER);
      }
      this.formGroup.controls['PERMISOS'].setValue(USER_PERMISSION);
      this.formGroup.controls['TAMANO_COLUMNA'].setValue(COMPONENTS.TAMANO_COLUMNA);

      this.dataSourceValues.data = COMPONENTS.DATOS_VALORES;
    }
  }

  public updateColumnsNumber(accion: '+' | '-') {
    let columnNumber: number = this.formGroup.controls['TAMANO_COLUMNA'].value;
    if (accion === '+') {
      if (columnNumber < 12) {
        columnNumber += 1;
      }
    } else if (accion === '-') {
      if (columnNumber > 1) {
        columnNumber -= 1;
      }
    } else {
      this.resourcesService.openSnackBar(`Opción no disponible`);
      return;
    }
    this.formGroup.controls['TAMANO_COLUMNA'].setValue(columnNumber)
  }

  public selectionChange(event: any) {
    this.getIndexStep = event.selectedIndex;
    if (event.selectedIndex === 0) {
      this.stepper.next();
    } else if (event.selectedIndex === 1) {
      this.stepper.previous();
    }
  }

  public allPermission() {
    const COUNT_USER: number = this.arrUsers.length;
    const USER_PERMISSION: string[] = this.formGroup.controls['PERMISOS'].value;
    const COUNT_PERMISSION: number = USER_PERMISSION.length;

    return COUNT_PERMISSION === COUNT_USER;
  }

  public somePermission() {
    const COUNT_USER: number = this.arrUsers.length;
    const USER_PERMISSION: string[] = this.formGroup.controls['PERMISOS'].value;
    const COUNT_PERMISSION: number = USER_PERMISSION.length;
    return COUNT_PERMISSION < COUNT_USER && COUNT_PERMISSION > 0;
  }

  public selectedAll(isChecked: boolean) {
    if (isChecked) {
      const USERS: string[] = this.arrUsers.map((user: UserResponse) => `${ user.IDUSUARIO }`);
      this.formGroup.controls['PERMISOS'].setValue(USERS);
    } else {
      this.formGroup.controls['PERMISOS'].setValue([]);
    }
  }

  public addDataValue() {
    this.isLoadingValue = true;
    const FORM_VALUES = this.formGroupValues.value;
    let dataSourceValues: FormDataPersonality[] = this.dataSourceValues.data;
    dataSourceValues.push(FORM_VALUES);
    this.dataSourceValues.data = dataSourceValues;
    this.formGroupValues.reset();
    this.isLoadingValue = false;
  }

  public updateDataValue() {
    this.isLoadingValue = true;
    if (this.typeFormDataValues.INDEX !== undefined) {
      const index: number = this.typeFormDataValues.INDEX;
      const FORM_VALUES = this.formGroupValues.value;
      let dataSourceValues: FormDataPersonality[] = this.dataSourceValues.data;
      dataSourceValues[index] = FORM_VALUES;
      this.dataSourceValues.data = dataSourceValues;
      this.formGroupValues.reset();
      this.typeFormDataValues.TYPE_FORM = 'R';
    } else {
      this.resourcesService.openSnackBar(`Opción no disponible`);
    }
    this.isLoadingValue = false;
  }
  
  public editDataValue(index: number) {
    this.isLoadingValue = true;
    const FORM_VALUES = this.dataSourceValues.data[index];
    this.formGroupValues.setValue(FORM_VALUES);
    this.typeFormDataValues.TYPE_FORM = 'M';
    this.typeFormDataValues.INDEX = index;
    this.isLoadingValue = false;
  }
  
  public deleteDataValue(index: number) {
    let dataSourceValues: FormDataPersonality[] = this.dataSourceValues.data.filter(
      (formDataPersonality: FormDataPersonality, indexValue: number) => indexValue !== index);
    this.dataSourceValues.data = dataSourceValues;
  }

  public nextStep() {
    this.stepper.next();
    this.getIndexStep = 1;
  }
  
  public previousStep() {
    this.stepper.previous();
    this.getIndexStep = 0;
  }

  public validateId() {
    const ID: string = this.formGroup.controls['IDENTIFICADOR'].value;
    if (this.infoDataForm.IDS.includes(ID)) {
      this.resourcesService.openSnackBar(`El identicador ya está registrado en otro componente.`);
      return false;
    }
    return true;
  }
  
  public async openExampleRadio() {
    const COMPONENT_RADIO: ComponentInformationRadio = await this._createComponentRadio();
    this._dialog.open(ExampleComponentComponent, {
      data: {
        TYPE_COMPONENT: 'RADIO',
        COMPONENT: COMPONENT_RADIO
      },
      width: '450px',
    });
  }

  private async _createComponentRadio(): Promise<ComponentInformationRadio> {

    let columna = this.formGroup.controls['COLUMNA'].value;
    columna = columna.toString().trim();
    let etiqueta = this.formGroup.controls['ETIQUETA'].value;
    etiqueta = etiqueta.toString().trim();
    let identificador = this.formGroup.controls['IDENTIFICADOR'].value;
    identificador = identificador.toString().trim();
    let nombreCampo = this.formGroup.controls['NOMBRE_CAMPO'].value;
    nombreCampo = nombreCampo.toString().trim();
    let permisos = this.formGroup.controls['PERMISOS'].value;
    let PERMISOS_ENC: string[] = [];
    permisos.forEach(async (user: string) => {
      const ENC_USER: string = await this._encService.encrypt(user);
      PERMISOS_ENC.push(ENC_USER);
    });

    let requerido = this.formGroup.controls['REQUERIDO'].value;
    let deshabilitar = this.formGroup.controls['DESHABILITAR'].value;
    let tamanoColumna = this.formGroup.controls['TAMANO_COLUMNA'].value;

    const DATA_SOURCE_VALUES:FormDataPersonality[] = this.dataSourceValues.data;


    const COMPONENT_RADIO: ComponentInformationRadio = {
      COLUMNA: columna,
      ETIQUETA: etiqueta,
      IDENTIFICADOR: identificador,
      NOMBRE_CAMPO: nombreCampo,
      PERMISOS: PERMISOS_ENC,
      REQUERIDO: requerido,
      DESHABILITAR: deshabilitar,
      TAMANO_COLUMNA: tamanoColumna,
      DATOS_VALORES: DATA_SOURCE_VALUES
    }

    return COMPONENT_RADIO;
  }

  public async saveComponent() {
    this._dialog.open(AlertComponent, {
      data: {
        title: 'Confirmación',
        description: '¿Está seguro de registrar el componente RADIO?',
        icon: 'warning',
      },
      disableClose: true,
    }).afterClosed().subscribe(async (response) => {
      if (response) {
        const COMPONENT_RADIO: ComponentInformationRadio = await this._createComponentRadio();
        
        this._dialogRef.close(COMPONENT_RADIO);
      }
    });
  }
}
