import { Component, ElementRef, EventEmitter, Output, ViewChild } from '@angular/core';
import { MatIconRegistry } from '@angular/material/icon';
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatTableDataSource } from '@angular/material/table';
import { DomSanitizer } from '@angular/platform-browser';
import * as XLSX from 'xlsx';
import { EnviarInfoService } from '../../services/enviar-info.service';
import { UsersService } from '../../services/users.service';
import { Usuario } from './../../interfaces/Usuario.interface';
import { MatDialog } from '@angular/material/dialog';
import { AbstractControl, FormBuilder, FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
import { GradosEducativosService } from '../../services/grados-educativos.service';
import Swal from 'sweetalert2';

@Component({
  selector: 'app-niveles-educativos',
  templateUrl: './catalogo-usuarios.component.html',
  styleUrl: './catalogo-usuarios.component.css'
})
export class CatalogoUsuariosComponent {
  public columnas: string[] = ['idUsuario', 'tipoUsuario', 'nombre', 'grado', 'accesos', 'estado', 'acciones'];
  public dataSource: any;
  public color: string = '';
  public textColor: string = '';

  @ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator;
  @ViewChild('TABLE') table!: ElementRef;


  constructor(private _MatIconRegister: MatIconRegistry,
    private _DomSanitizer: DomSanitizer,
    private paginatorIntl: MatPaginatorIntl,
    private _enviarInfo: EnviarInfoService,
    private userService: UsersService,
    public dialog: MatDialog
  ) {
    this._MatIconRegister.addSvgIcon('excel', this._DomSanitizer.bypassSecurityTrustResourceUrl('assets/icons/excel.svg'));

    //paginador de la tabla angular material a español
    const spanishRangeLabel = (page: number, pageSize: number, length: number): string => {
      if (length === 0 || pageSize === 0) {
        return `0 de ${length}`;
      }
      length = Math.max(length, 0);
      const startIndex = page * pageSize;
      const endIndex = startIndex < length ?
        Math.min(startIndex + pageSize, length) :
        startIndex + pageSize;
      return `${startIndex + 1} - ${endIndex} de ${length}`;
    };
    this.paginatorIntl.nextPageLabel = "Siguiente";
    this.paginatorIntl.previousPageLabel = "Anterior";
    this.paginatorIntl.firstPageLabel = "Ir a la primer página";
    this.paginatorIntl.lastPageLabel = "Ir a la última página";
    this.paginatorIntl.itemsPerPageLabel = "Registros por página";
    this.paginatorIntl.getRangeLabel = spanishRangeLabel;
  }

  ngOnInit(): void {
    this._enviarInfo.currentTextColor.subscribe(textColor => {
      this.textColor = textColor;
    });
    this._enviarInfo.currentColor.subscribe(color => {
      this.color = color;
    });
    this._enviarInfo.tabla$.subscribe(() => {
      this.getUsuarios();
    });
    this.getUsuarios();
  }

  // buscador
  applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    this.dataSource.filter = filterValue.trim().toLowerCase();
  }

  public allInfo: any;
  getUsuarios() {
    return this.userService.getAllUsers().subscribe((response: any) => {
      this.isLoading = false;
      this.allInfo = response
      this.dataSource = new MatTableDataSource<Usuario>(this.allInfo.filter((filtro:any) => filtro.estatus === 'Activo' || filtro.estatus === 'Inactivo'));
      this.dataSource.paginator = this.paginator;
      console.log(response);
      return response;
    })
  }

  public isLoading: boolean = true;
  option(event: string) {
    this.isLoading = true;
    let filteredData: any;

    if (event === 'Activos') {
      filteredData = this.allInfo.filter((filtro:any) => filtro.estatus === 'Activo' || filtro.estatus === 'Inactivo');
    } else if (event === 'Todo') {
      filteredData = this.allInfo;
    }

    this.dataSource = new MatTableDataSource<Usuario>(filteredData);
    this.dataSource.paginator = this.paginator;
    this.isLoading = false;
  }

  // exportar busqueda a excel
  exportAsExcel() {
    const ws: XLSX.WorkSheet = XLSX.utils.table_to_sheet(this.table.nativeElement);
    const wb: XLSX.WorkBook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, 'COLEGIOABC-ConsultaUsuarios');
    XLSX.writeFile(wb, 'Usuarios.xlsx');

  }

  //exportar toda la info a excel
  exportAll() {
    const dataSource = this.dataSource.data;
    const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet(dataSource);
    const wb: XLSX.WorkBook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, 'COLEGIOABC-ConsultaUsuarios');
    XLSX.writeFile(wb, 'Usuarios.xlsx');
  }
  

  deleteLevel(id: string) {

    Swal.fire({
      icon: 'question',
      title: '¿Desea eliminar el usuario?',
      showCancelButton: true,
      allowEscapeKey: false,
      allowOutsideClick: false,
      confirmButtonColor: '#3085d6',
      cancelButtonColor: '#d33',
      confirmButtonText: "Eliminar",
    }).then((result: any) => {
      /* Read more about isConfirmed, isDenied below */
      if (result.isConfirmed) {
        this.userService.eliminarUser(id).subscribe((response: any) => {
          console.log(response);
          Swal.fire({
            icon: 'success',
            title: 'Usuario eliminado',
            confirmButtonColor: 'rgb(237,46,56)',
            confirmButtonText: 'Ok',
          }).then((result: any) => {

            if (result.isConfirmed) {
              this.ngOnInit();
              Swal.close();
            }
          })
        }, (err) => {
          console.log(err);
          Swal.fire({
            icon: 'error',
            title: 'Error al eliminar',
            text: `${err.error.mensaje}`,
          })
          this.ngOnInit();
        }
        )
      } else if (result.dismiss == 'cancel') {
        this.ngOnInit();
      }
    });

  }

  enableLevel(id: string) {
    Swal.fire({
      icon: 'question',
      title: '¿Desea restaurar el usuario?',
      showCancelButton: true,
      allowEscapeKey: false,
      allowOutsideClick: false,
      confirmButtonColor: '#3085d6',
      cancelButtonColor: '#d33',
      confirmButtonText: "Habilitar",
    }).then((result: any) => {

      if (result.value) {
        this.userService.habilitarUser(id).subscribe((response: any) => {
          Swal.fire({
            icon: 'success',
            title: 'Usuario habilitado',
            confirmButtonColor: 'rgb(237,46,56)',
            confirmButtonText: 'Ok',
          }).then((result: any) => {
            if (result.isConfirmed) {
              Swal.close();
              this.ngOnInit();
            }
          })
        }, (err) => {
          console.log(err);
          Swal.fire({
            icon: 'error',
            title: 'Error al habilitar',
            text: `${err.error.message}`,
          })
        }
        )
      } else if (result.dismiss == 'cancel') {
        this.ngOnInit();
      }
    });
  }

  openDialog(id: string) {
    const dialogRef = this.dialog.open(ModalUsuarioEdit, {
      autoFocus: false
    });

    //esto es para actualizar la tabla una vez actualizada la info
    dialogRef.componentInstance.nivelActualizado.subscribe(() => {
      this.getUsuarios();
    });

    dialogRef.componentInstance.setData(id);
  }

  openDialogContra(id: string) {
    const dialogRef = this.dialog.open(ContrasenaModal, {
      autoFocus: false
    });

    dialogRef.componentInstance.setDataC(id);
  }

}


@Component({
  selector: 'dialog-content-example-dialog',
  templateUrl: 'editar.component.html',
  styleUrl: './catalogo-usuarios.component.css'

})

export class ModalUsuarioEdit {
  public isLoading: boolean = true;
  public data: any;
  public grados: any;
  public roles = [
    { value: 'AL', rol: 'AL - Alumno' },
    { value: 'PR', rol: 'PR - Profesor' },
    { value: 'PF', rol: 'PF - Padre de Familia' },
    { value: 'AD', rol: 'AD - Administrador' },
  ]


  public statuses = [
    { value: 'Activo', status: 'Activo' },
    { value: 'Inactivo', status: 'Inactivo' },
  ]

  public validados = [
    { value: 'Si', desc: 'Si - Validado' },
    { value: 'No', desc: 'No - No Validado' },
    { value: 'Ac', desc: 'Ac - Requiere Validación' },
    { value: 'Bq', desc: 'Si - Bloqueado' },
    { value: 'Na', desc: 'Na - No APlica' },
    { value: 'Bt', desc: 'Bt - Baja Temporal' },
    { value: 'Bd', desc: 'Bd - Baja Definitiva' },
  ]
  //esto es para actualizar la tabla
  @Output() nivelActualizado = new EventEmitter<void>();

  public form: FormGroup;
  constructor(public dialog: MatDialog,
    private userService: UsersService,
    private gradosService: GradosEducativosService,
    private fb: FormBuilder,
  ) {
    this.form = this.fb.group({
      primerNombre: ['', Validators.required],
      segundoNombre: [''],
      apellidoPaterno: ['', Validators.required],
      apellidoMaterno: [''],
      idUsuario: [{ value: '', disabled: true }, Validators.required],
      estatus: ['', Validators.required],
      tipoUsuario: ['', Validators.required],
      validado: ['', Validators.required],
      grado: [{ value: '', disabled: true }],
      correo: ['', Validators.email],
      contrasenaHash: [{ value: '', disabled: true }],
      alias: [''],
    });
    this.form.get('tipoUsuario')?.valueChanges.subscribe(value => {
      const gradoControl = this.form.get('grado');
      if (value === 'AL') {
        gradoControl?.enable();
      } else {
        gradoControl?.disable();
      }
    });
    this.getGrados()
  }

  getGrados() {
    return this.gradosService.getHabilitados().subscribe((response) => {
      console.log(response);

      this.grados = response;
    })
  }

  setData(id: any) {
    this.userService.getOne(id).subscribe((response: any) => {
      this.isLoading = false;
      this.data = response;

      // mostrar data en el formulario
      this.form.controls['primerNombre'].setValue(this.data.primerNombre);
      this.form.controls['segundoNombre'].setValue(this.data.segundoNombre);
      this.form.controls['apellidoPaterno'].setValue(this.data.apellidoPaterno);
      this.form.controls['apellidoMaterno'].setValue(this.data.apellidoMaterno);
      this.form.controls['idUsuario'].setValue(this.data.idUsuario);
      this.form.controls['estatus'].setValue(this.data.estatus);
      this.form.controls['tipoUsuario'].setValue(this.data.tipoUsuario);
      this.form.controls['validado'].setValue(this.data.validado);
      this.form.controls['grado'].setValue(this.data.grado);
      this.form.controls['correo'].setValue(this.data.correo);
      this.form.controls['alias'].setValue(this.data.alias);
    })
  }

  editarUsuario() {
    console.log('data' + this.data);
    console.log(this.form.value);
    let info = {
      id: this.data.idUsuario,
      primerNombre: this.form.value.primerNombre,
      segundoNombre: this.form.value.segundoNombre,
      apellidoPaterno: this.form.value.apellidoPaterno,
      apellidoMaterno: this.form.value.apellidoMaterno,
      idUsuario: this.data.idUsuario,
      estatus: this.form.value.estatus,
      tipoUsuario: this.form.value.tipoUsuario,
      validado: this.form.value.validado,
      grado: this.form.value.grado,
      correo: this.form.value.correo,
      alias: this.form.value.alias,
    }
    console.log(info);
    this.userService.actualizarUser(info).subscribe((response: any) => {
      console.log(response);
      Swal.fire({
        icon: 'success',
        title: `${response.mensaje}`
      })
      this.dialog.closeAll();
      this.nivelActualizado.emit();
    }, (err) => {
      console.log(err);
      Swal.fire({
        icon: 'error',
        title: `${err.message}`
      })
    })
  }

  close() {
    this.dialog.closeAll()
  }

  limpiar() {
    this.form.reset();
  }

  campoNoValido(campo: string): boolean {
    if (this.form.get(campo)?.invalid && this.form.get(campo)?.touched) {
      return true;
    } else {
      return false;
    }
  }

  campoVacio(campo: string): boolean {
    if ((this.form.get(campo)?.value === '') && this.form.get(campo)?.touched) {
      return true;
    } else {
      return false;
    }
  }
}

@Component({
  selector: 'dialog-content-example-dialog',
  templateUrl: 'contrasenaModal.component.html',
  styleUrls: ['./catalogo-usuarios.component.css'] 
})
export class ContrasenaModal {
  public userID: string = '';
  public data: any;
  public isLoading: boolean = true;
  public showPassword: boolean = false;
  constructor(public dialog: MatDialog, private userService: UsersService) { }


  public matchingPasswords: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
    const formGroup = control as FormGroup;
    const contrasena1 = formGroup.get('contrasena1')?.value;
    const contrasena2 = formGroup.get('contrasena2')?.value;

    // Si las contraseñas no coinciden, retorna un objeto de error
    return contrasena1 === contrasena2 ? null : { noMatch: true };
  }

  // Definir el formulario con el validador personalizado
  public form = new FormGroup(
    {
      contrasena1: new FormControl<string>('', [Validators.required,Validators.pattern(/^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*\W)(?!.* ).{8,16}$/)]),
      contrasena2: new FormControl<string>('', Validators.required),
    },
    { validators: this.matchingPasswords }
  );

  // Método para verificar si las contraseñas no coinciden
  public contrasIguales(): boolean {
    return this.form.hasError('noMatch');
  }

  campoNoValido(campo: string): boolean {
    if (this.form.get(campo)?.invalid && this.form.get(campo)?.touched) {
      return true;
    } else {
      return false;
    }
  }

  campoVacio(campo: string): boolean {
    if ((this.form.get(campo)?.value === '') && this.form.get(campo)?.touched) {
      return true;
    } else {
      return false;
    }
  }

  toggleVisibility() {
    this.showPassword = !this.showPassword;
  }

  setDataC(id: any) {
    this.userService.getOne(id).subscribe((response: any) => {
      console.log(response);
      this.isLoading = false;
      this.data = response;
      this.userID = this.data.idUsuario;
    });
  }

  enviarContra() {
    if (this.form.invalid) {
      return Object.values(this.form.controls).forEach(control => {
        control.markAllAsTouched();
      });
    }
    
    const info = {
      idUsuario: this.userID,
      contrasenaHash: this.form.get('contrasena1')?.value
    };

    this.userService.changePassword(info).subscribe((response: any) => {
      console.log(response);
      Swal.fire({
        icon: 'success',
        title: `${response.message}`
      })
      this.dialog.closeAll();
    });
  }

  close() {
    this.dialog.closeAll();
  }
}
