import { Component, Inject, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { UserResponse, UsersResponse } from '../../../interfaces/users.interface';
import { lastValueFrom, map, Observable, startWith } from 'rxjs';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { ComponentInformationTextarea, DataDialogComponentTextarea } from '../../../interfaces/forms-management/form-management.interface';
import { ResourcesService } from '../../../services/resources.service';
import { SystemAdminService } from '../../../services/system-admin.service';
import { UsersProfilesService } from '../../../services/users-profiles.service';
import { EncService } from '../../../services/enc.service';
import { MaterialIcon, MaterialIconsResponse } from '../../../interfaces/material-icons.interface';
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-textarea',
    templateUrl: './configurate-textarea.component.html',
    styleUrl: './configurate-textarea.component.css',
    standalone: false
})
export class ConfigurateTextareaComponent implements OnInit {

  public formGroup: FormGroup;
  public isLoading: boolean;
  public arrColumns: string[];
  public arrIdentification: string[];

  public arrIcons: string[];
  public arrUsers: UserResponse[];
  public filteredOptionsIcons!: Observable<string[]>;
  public typeForm: 'R' | 'M';

  constructor(
    @Inject(MAT_DIALOG_DATA) public infoDataForm: DataDialogComponentTextarea,
    public resourcesService: ResourcesService,
    private _systemAdminService: SystemAdminService,
    private _usersProfilesService: UsersProfilesService,
    private _encService: EncService,
    private _dialog: MatDialog,
    private _dialogRef: MatDialogRef<false | ComponentInformationTextarea>,
  ) {
    this.arrColumns = this.infoDataForm.COLUMNS;
    this.arrIdentification = this.infoDataForm.IDS;
    this.isLoading = false;
    
    this.arrIcons = [];
    this.arrUsers = [];
    this.typeForm = this.infoDataForm.TYPE_FORM;
    this.formGroup = this._createFormGroup();
  }
  
  async ngOnInit() {
    this.isLoading = true;
    await this._getMaterialIcons();
    await this._getUsers();
    this._getInformationComponent();
    this.isLoading = false;

    this.filteredOptionsIcons = this.formGroup.controls['ICONO'].valueChanges.pipe(
      startWith(''),
      map((value: any) => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.arrIcons.filter(option => option.toLowerCase().includes(filterValue));
      })
    );
  }

  private _createFormGroup(): FormGroup {
    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),
      PLACEHOLDER: new FormControl(''),
      LONGITUD_CAMPO_MINIMO: new FormControl(null),
      LONGITUD_CAMPO_MAXIMO: new FormControl(null),
      ICONO: new FormControl(null),
      FILAS: new FormControl(2),
      VALOR_DEFECTO: new FormControl(null),
      PATRON_VALIDACION: new FormControl(null),
      MENSAJE_ERROR_VALIDACION: new FormControl({ value: null, disabled: true }, Validators.required),
      PERMISOS: new FormControl([], Validators.required),
      DESHABILITAR: new FormControl(null),
      REQUERIDO: new FormControl(null),
      SOLO_LECTURA: new FormControl(null),
      TAMANO_COLUMNA: new FormControl(12, Validators.required),
    });
  }

  private async _getMaterialIcons() {
    const USER: string = this.resourcesService.getUser();
    const LINE: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._systemAdminService.getMaterialIcons(USER, LINE)).then(
      (responseData: MaterialIconsResponse) => {
        if (!responseData.error) {
          this.arrIcons = responseData.response.map((element: MaterialIcon) => `${ element.name }`);
        } else {
          this.resourcesService.openSnackBar(`${ responseData.msg }`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this._getMaterialIcons();
        }
      }
    );
  }

  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);
          }
          // 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();
        }
      }
    );
  }

  private async _getInformationComponent() {
    if (this.infoDataForm.COMPONENTS !== undefined) {
      const COMPONENTS: ComponentInformationTextarea = 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['PLACEHOLDER'].setValue(COMPONENTS.PLACEHOLDER);
      this.formGroup.controls['LONGITUD_CAMPO_MINIMO'].setValue(COMPONENTS.LONGITUD_CAMPO_MINIMO);
      this.formGroup.controls['LONGITUD_CAMPO_MAXIMO'].setValue(COMPONENTS.LONGITUD_CAMPO_MAXIMO);
      this.formGroup.controls['ICONO'].setValue(COMPONENTS.ICONO);
      this.formGroup.controls['VALOR_DEFECTO'].setValue(COMPONENTS.VALOR_DEFECTO);
      this.formGroup.controls['PATRON_VALIDACION'].setValue(COMPONENTS.PATRON_VALIDACION);
      this.formGroup.controls['MENSAJE_ERROR_VALIDACION'].setValue(COMPONENTS.MENSAJE_ERROR_VALIDACION);  

      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['DESHABILITAR'].setValue(COMPONENTS.DESHABILITAR);
      this.formGroup.controls['REQUERIDO'].setValue(COMPONENTS.REQUERIDO);
      this.formGroup.controls['SOLO_LECTURA'].setValue(COMPONENTS.SOLO_LECTURA);
      this.formGroup.controls['TAMANO_COLUMNA'].setValue(COMPONENTS.TAMANO_COLUMNA);
    }
  }

  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 validatePattern() {
    const pattern: string = this.formGroup.controls['PATRON_VALIDACION'].value;
    if (pattern.length > 0) {
      this.formGroup.controls['MENSAJE_ERROR_VALIDACION'].enable();
      this.formGroup.controls['MENSAJE_ERROR_VALIDACION'].updateValueAndValidity();
    } else {
      this.formGroup.controls['MENSAJE_ERROR_VALIDACION'].setValue(null);
      this.formGroup.controls['MENSAJE_ERROR_VALIDACION'].disable();
      this.formGroup.controls['MENSAJE_ERROR_VALIDACION'].updateValueAndValidity();
    }
  }

  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 validateId() {
    const ID: string = this.formGroup.controls['IDENTIFICADOR'].value;
    if (this.arrIdentification.includes(ID)) {
      this.resourcesService.openSnackBar(`El identicador ya está registrado en otro componente.`);
      return false;
    }
    return true;
  }

  public async openExampleTextarea() {
    const COMPONENT_TEXTAREA: ComponentInformationTextarea = await this._createComponentTextarea();
    this._dialog.open(ExampleComponentComponent, {
      data: {
        TYPE_COMPONENT: 'TEXTAREA',
        COMPONENT: COMPONENT_TEXTAREA
      },
      width: '450px',
      maxWidth: '450px',
    });
  }

  private async _createComponentTextarea(): Promise<ComponentInformationTextarea> {
    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;
    let placeholder = this.formGroup.controls['PLACEHOLDER'].value;
    let longitudCampoMinimo = this.formGroup.controls['LONGITUD_CAMPO_MINIMO'].value;
    let longitudCampoMaximo = this.formGroup.controls['LONGITUD_CAMPO_MAXIMO'].value;
    let filas = this.formGroup.controls['FILAS'].value;
    let icono = this.formGroup.controls['ICONO'].value;
    let valorDefecto = this.formGroup.controls['VALOR_DEFECTO'].value;
    let patronValidacion = this.formGroup.controls['PATRON_VALIDACION'].value;
    let mensajeErrorValidacion = this.formGroup.controls['MENSAJE_ERROR_VALIDACION'].value;
    
    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 deshabilitar = this.formGroup.controls['DESHABILITAR'].value;
    let requerido = this.formGroup.controls['REQUERIDO'].value;
    let soloLectura = this.formGroup.controls['SOLO_LECTURA'].value;
    let tamanoColumna = this.formGroup.controls['TAMANO_COLUMNA'].value;

    const COMPONENT_TEXTAREA: ComponentInformationTextarea = {
      COLUMNA: columna,
      ETIQUETA: etiqueta,
      IDENTIFICADOR: identificador,
      NOMBRE_CAMPO: nombreCampo,
      PLACEHOLDER: placeholder,
      LONGITUD_CAMPO_MINIMO: longitudCampoMinimo,
      LONGITUD_CAMPO_MAXIMO: longitudCampoMaximo,
      FILAS: filas,
      ICONO: icono,
      VALOR_DEFECTO: valorDefecto,
      PATRON_VALIDACION: patronValidacion,
      MENSAJE_ERROR_VALIDACION: mensajeErrorValidacion,
      DESHABILITAR: deshabilitar,
      REQUERIDO: requerido,
      SOLO_LECTURA: soloLectura,
      PERMISOS: PERMISOS_ENC,
      TAMANO_COLUMNA: tamanoColumna,
    }
    return COMPONENT_TEXTAREA;
  }

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