import { Component, ElementRef, EventEmitter, Inject, OnInit, Output, ViewChild } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatTableDataSource } from '@angular/material/table';
import { NivelEducativoService } from '../../../Administrador/services/nivel-educativo.service';
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
import { EnviarInfoService } from '../../../Administrador/services/enviar-info.service';
import { MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
import * as XLSX from 'xlsx';
import Swal from 'sweetalert2';
import { AsistenciaService } from '../../services/asistencia.service';
import { MAT_DATE_LOCALE, provideNativeDateAdapter } from '@angular/material/core';
import moment from 'moment';
import { forkJoin, map } from 'rxjs';
import { GradosEducativosService } from '../../../Administrador/services/grados-educativos.service';
import { GruposService } from '../../../Administrador/services/grupos.service';
import { MateriaService } from '../../../Administrador/services/materia.service';
import { ProfesorBitacoraService } from '../../services/profesor-bitacora.service';

@Component({
  selector: 'app-asistencia',
  templateUrl: './asistencia.component.html',
  styleUrl: './asistencia.component.css'
})

export class AsistenciaComponent implements OnInit {
  public checked = false;
  public isLoading: boolean = true;
  public searchInput = new FormControl('');
  public color: string = '';
  public textColor: string = '';
  public columnas: string[] = ['materia', 'fechaLista', 'estado', 'versiones', 'alumnos', 'asistencias', 'faltas', 'faltasJ', 'usuario', 'fechaModificacion', 'acciones'];
  public dataSource = new MatTableDataSource<any>();

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


  constructor(
    private asistenciaService: AsistenciaService,
    private _MatIconRegister: MatIconRegistry,
    private _DomSanitizer: DomSanitizer,
    private paginatorIntl: MatPaginatorIntl,
    private _enviarInfo: EnviarInfoService,
    public dialog: MatDialog
  ) {
    this._MatIconRegister.addSvgIcon('excel', this._DomSanitizer.bypassSecurityTrustResourceUrl('assets/icons/excel.svg'));
    //paginador de tabla 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;
    });

    //suscribirse al subject que manda al servicio
    this._enviarInfo.tabla$.subscribe(() => {
      this.getAsistencias();
    });

    this.getAsistencias()
  }
  public allInfo: any;

  //Traer la información y mostrarla en la tabla
  getAsistencias() {
    return this.asistenciaService.getAsistencias().subscribe((response: any) => {
      console.log(response);
      this.isLoading = false;
      this.allInfo = response
      this.dataSource = new MatTableDataSource<any>(this.allInfo.filter((filtro: any) => filtro.estado === 'Borrador'));
      this.dataSource.paginator = this.paginator;
      return response;

    })
  }

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

    if (event === 'Borradores') {
      filteredData = this.allInfo.filter((filtro: any) => filtro.estado === 'Borrador');
    } else if (event === 'Completas') {
      filteredData = this.allInfo.filter((filtro: any) => filtro.estado === 'Completa');
    }

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


  //filtro de búsqueda
  applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    this.dataSource.filter = filterValue.trim().toLowerCase();
  }




  //exportar búsqueda 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-ConsultaNiveles');
    XLSX.writeFile(wb, 'Niveles_Educativos.xlsx');

  }
  //exportar toda la data 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-ConsultaNiveles');
    XLSX.writeFile(wb, 'Niveles_Educativos.xlsx');
  }

  openDialog() {
    const dialogRef = this.dialog.open(ModalAsistenciaEdit, {})
    
  }

  editar(data: any) {
    const dialogRef = this.dialog.open(ModalLista, { disableClose: true ,
      data: { al: JSON.parse(data.listaAsistencia), id: data.idAsistencia, estado: data.estado, act: 'edit' }
    });
    dialogRef.componentInstance.listaActualizada.subscribe(() => {
      this.getAsistencias();
    });
  }

  eliminar(id: number) {
    Swal.fire({
      icon: 'question',
      title: '¿Desea eliminar la lista de asistencia?',
      showCancelButton: true,
      allowOutsideClick: false,
      allowEscapeKey: false,
      confirmButtonColor: '#3085d6',
      cancelButtonColor: '#d33',
      confirmButtonText: "Eliminar",
    }).then((result) => {
      if (result.isConfirmed) {
        this.asistenciaService.eliminar(id).subscribe((response: any) => {
          Swal.fire(
            {icon: 'success',
            title: `${response.mensaje}`,}
          )
          this.getAsistencias();
        }, (err) => {
          Swal.fire({
            icon: 'error',
            title: 'Error al eliminar',
            text: `${err.error.message}`,
          })
        });
      }
    })
  }





}


@Component({
  selector: 'dialog-content-example-dialog',
  templateUrl: 'modalAsistencia.component.html',
  styleUrl: './asistencia.component.css',
  providers: [provideNativeDateAdapter(),
  { provide: MAT_DATE_LOCALE, useValue: 'en-GB' }
  ],
})

export class ModalAsistenciaEdit {

  // public data: any;

  public widowWidth!: number;
  public todayDate: Date = new Date();
  public materias: any;
  public grupos: any;
  public horasDelDia: any = this.generarHorasDelDia();
  public isLoading: boolean = true;
  public filtrados: any;
  public info: any;
  public junto: any;
  public todos: any;
  public dataUsuarios: any;
  public alumnos: any;
  private userData = JSON.parse(localStorage.getItem('userDataS') ? localStorage.getItem('userDataS') || '' : localStorage.getItem('userData') || '');
  public form = new FormGroup({
    gradoGrupo: new FormControl<string>('', Validators.required),
    materia: new FormControl<string>('', Validators.required),
    fechaInicio: new FormControl<string>('', Validators.required),
    horaInicio: new FormControl<string>('', Validators.required),
  })
  //esto es para actualizar la tabla
  @Output() nivelActualizado = new EventEmitter<void>();
  constructor(
    public dialog: MatDialog,
    private asistenciaService: AsistenciaService,
    private profesorService: ProfesorBitacoraService,
    private gradosService: GradosEducativosService,
    private gruposService: GruposService,
    private materiasService: MateriaService,
    @Inject(MAT_DIALOG_DATA) public data: any
  ) {
    this.gradosGrupos();
    this.materiasS();
    this.getAlumnos();
  }

  gradosGrupos() {
    forkJoin({
      grados: this.gradosService.getHabilitados(),
      grupos: this.gruposService.getHabilitados()
    }).subscribe(({ grados, grupos }: any) => {
      this.todos = grados.concat(grupos);

      this.junto = this.todos.map((data: any) => {
        return {
          id: data.nombreGrado || data.idGrupo,
          nombre: data.nombreGrado || data.nombreGrupo
        }
      })
      this.isLoading = false;
    });
  }

  materiasS() {
    this.materiasService.getHabilitados().subscribe((response: any) => {
      this.materias = response;

      this.isLoading = false;
    })
  }

  onGradoGrupo(event: any) {
    this.filtrados = this.materias.filter((materia: any) => materia.idGradoGrupoRelacionado === event);
    this.alumnos = this.dataUsuarios.filter((alumno: any) => alumno.grado == event || alumno.idGrupo == event);
  }

  getAlumnos() {
    this.profesorService.getAlum().subscribe((data: any) => {
      this.dataUsuarios = data;

    });
  }

  convertToDatetime() {
    // Obtener valores del formulario
    const fechaInicio: any = this.form.get('fechaInicio')?.value;
    const horaInicio: any = this.form.get('horaInicio')?.value;

    let fechaHoraInicio: string | undefined;

    if (fechaInicio && horaInicio) {
      // Formatear fecha en 'YYYY-MM-DD'
      var formattedDate = moment(fechaInicio).format("YYYY-MM-DD");
      fechaHoraInicio = `${formattedDate} ${horaInicio}`;

    } else {
      console.error('Fecha de inicio o hora de inicio no válidas.');
    }


    this.info = {
      titulo: this.form.get('gradoGrupo')?.value,
      idMateria: this.form.get('materia')?.value,
      ulActualizacion: moment(new Date()).format('YYYY-MM-DD HH:mm:ss'),
      idFechaHora: fechaHoraInicio,
      tAlumnos: this.alumnos.length,
      listaAsistencia: JSON.stringify({}),
      idUsuario: this.userData[0]
    };
  }

  save() {
    this.convertToDatetime()
    console.log(this.info);

    if (this.form.invalid) {
      Swal.fire({
        icon: 'error',
        title: 'Error al crear asistencia',
        text: 'Por favor, llene todos los campos requeridos.'
      })
      this.form.markAllAsTouched();
      return;
    }

    this.asistenciaService.crear(this.info).subscribe((response: any) => {
      console.log(response);
      // Swal.fire({
      //   icon: 'success',
      //   title: `${response.mensaje}`,
      // });
      //abrir otro modal
      this.dialog.closeAll();
      this.dialog.open(ModalLista, { disableClose: true,
        data: { al: this.alumnos, id: response.idLista }
      });

    }, (err) => {
      console.log(err);
      Swal.fire({
        icon: 'error',
        title: 'Error al crear asistencia',
        text: `${err.error.message}`,
      })
    });
  }

  generarHorasDelDia(): { hora24: string, hora12: string }[] {
    const horas: { hora24: string, hora12: string }[] = [];
    let hora: number = 0;
    let minutos: number = 0;

    for (let i = 0; i < 48; i++) {
      let ampm = 'am';
      let hora12: number = hora;

      if (hora === 0) {
        hora12 = 12;
      } else if (hora === 12) {
        ampm = 'pm';
      } else if (hora > 12) {
        hora12 = hora - 12;
        ampm = 'pm';
      }

      const horaFormateada24 = `${hora.toString().padStart(2, '0')}:${minutos.toString().padStart(2, '0')}:00`;
      const horaFormateada12 = `${hora12.toString().padStart(2, '0')}:${minutos.toString().padStart(2, '0')} ${ampm}`;

      horas.push({ hora24: horaFormateada24, hora12: horaFormateada12 });

      minutos += 30;
      if (minutos === 60) {
        minutos = 0;
        hora++;
      }
    }

    return horas;
  }

  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)?.invalid) && this.form.get(campo)?.touched) {
      return true;
    } else {
      return false;
    }
  }
}


@Component({
  selector: 'dialog-content-example-dialog',
  templateUrl: 'listaAsistencia.component.html',
  styleUrl: './asistencia.component.css',
  providers: [provideNativeDateAdapter(),
  { provide: MAT_DATE_LOCALE, useValue: 'en-GB' }
  ],
})

export class ModalLista {
  public dataUsuarios: any;
  public isLoading: boolean = true;
  public form = new FormGroup({
    estado: new FormControl<string>('', Validators.required),
    comentario: new FormControl<string>('', Validators.required),

  })
  @Output() listaActualizada = new EventEmitter<void>();
  constructor(
    public dialog: MatDialog,
    @Inject(MAT_DIALOG_DATA) public data: any,
    private asistenciaService: AsistenciaService,
    private profesorService: ProfesorBitacoraService,
    private _enviarInfoService: EnviarInfoService
  ) {
    console.log(data);
    if (data.act === 'edit') {
      this.getAlumnos();
    } else {
      this.dataUsuarios = data.al;
      this.isLoading = false;
      for (let i = 0; i < data.al.length; i++) {
        this.onCheckboxChange(i, 'asistencia');
      }
    }

  }

  getAlumnos() {
    const ids = this.data.al;
    this.form.controls['estado'].setValue(this.data.estado);
    this.profesorService.getAlum().subscribe((data: any) => {
      this.dataUsuarios = data.filter((alumno: any) => ids.hasOwnProperty(alumno.idUsuario));
      this.isLoading = false;
      this.dataUsuarios.forEach((alumno: any) => {
        const estado = ids[alumno.idUsuario].A;
        const comentario = ids[alumno.idUsuario].C;
        alumno.asistencia = estado === 'A';
        alumno.falta = estado === 'F';
        alumno.fJustificada = estado === 'FJ';
        alumno.comentario = comentario;
        this.form.controls['comentario'].setValue(alumno.comentario);
      });
      console.log(this.dataUsuarios);
    });
  }

  onCheckboxChange(index: number, field: string) {
    this.dataUsuarios[index].asistencia = false;
    this.dataUsuarios[index].falta = false;
    this.dataUsuarios[index].fJustificada = false;

    if (field === 'asistencia') {
      this.dataUsuarios[index].asistencia = true;
      // this.data.al[index].A = 'A';
    } else if (field === 'falta') {
      this.dataUsuarios[index].falta = true;
      // this.data.al[index].A = 'F';
    } else if (field === 'fJustificada') {
      this.dataUsuarios[index].fJustificada = true;
      // this.data.al[index].A = 'FJ';
    }
  }

  updateLista() {
    const jsonData = this.generateJsonData();
    console.log(jsonData);

    const parsedData = JSON.parse(jsonData);
    let tAsistencia = 0;
    let tFaltas = 0;
    let tJustificadas = 0;

    for (const key in parsedData) {
      if (parsedData[key].A === 'A') {
        tAsistencia++;
      } else if (parsedData[key].A === 'F') {
        tFaltas++;
      } else if (parsedData[key].A === 'FJ') {
        tJustificadas++;
      }
    }

    let info = {
      listaAsistencia: jsonData,
      estado: this.form.get('estado')?.value,
      tAsistencia: tAsistencia,
      tFalta: tFaltas,
      tJustificada: tJustificadas,
      idLista: this.data.id
    };

    console.log(info);

    this.asistenciaService.actualizarRegistro(info).subscribe((response: any) => {
      console.log(response);
      Swal.fire({
        icon: 'success',
        title: `${response.mensaje}`,
      });
      this.dialog.closeAll();
      this._enviarInfoService.notifyCambioTabla();
    })
  }

  generateJsonData() {
    const result: any = {};
    this.dataUsuarios.forEach((alumno: any) => {
      result[alumno.idUsuario] = {
        A: alumno.asistencia ? 'A' : alumno.falta ? 'F' : 'FJ',
        C: alumno.comentario
      };
    });
    return JSON.stringify(result, null, 2);
  }
}