import { ChangeDetectorRef, Component, OnInit, Inject } from '@angular/core';
import { CommonModule, DOCUMENT } from '@angular/common';
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
import { finalize } from 'rxjs/operators';
import { AuthService } from '../../services/auth';
import { AppHeaderComponent } from '../shared/app-header/app-header';
import { JobsService } from '../../services/jobs';
import { PacienteService } from '../../services/paciente';

@Component({
  selector: 'app-autorizaciones-por-fecha',
  standalone: true,
  imports: [CommonModule, ReactiveFormsModule, FormsModule, AppHeaderComponent],
  templateUrl: './autorizaciones-por-fecha.html',
  styleUrls: ['./autorizaciones-por-fecha.css']
})
export class AutorizacionesPorFechaComponent implements OnInit {
  filtroForm: FormGroup;
  autorizaciones: any[] = [];
  isLoading = false;
  errorMessage: string | null = null;
  successMessage: string | null = null;
  limiteAutorizaciones = 500;
  avisoAutorizaciones = false;
  descargandoZip = false;
  descargandoPdf = false;
  actualizandoEstado: Record<string, boolean> = {};
  actualizandoMasivo = false;
  estadoMasivo: 'pendiente' | 'autorizado' | 'no_autorizado' = 'autorizado';
  esAdmin = false;
  filtroNumero = '';
  autorizacionesFiltradas: any[] = [];

  // Para saber si ya buscamos algo
  hayResultados = false;

  // Fechas en formato yyyy-MM-dd para usar en la API
  private fechaInicioApi: string | null = null;
  private fechaFinApi: string | null = null;

  constructor(
    private fb: FormBuilder,
    private authService: AuthService,
    private jobsService: JobsService,
    private pacienteService: PacienteService,
    private cdr: ChangeDetectorRef,
    @Inject(DOCUMENT) private document: Document
  ) {
    this.filtroForm = this.fb.group({
      fecha_inicio: ['', Validators.required],
      fecha_fin: ['', Validators.required]
    });
  }

  ngOnInit(): void {
    this.esAdmin = this.authService.isAdministrador();

    // Rango por defecto: últimos 30 días
    const hoy = new Date();
    const hace30Dias = new Date(hoy.getTime() - 30 * 24 * 60 * 60 * 1000);

    this.filtroForm.patchValue({
      fecha_inicio: this.formatDateForInput(hace30Dias),
      fecha_fin: this.formatDateForInput(hoy)
    });
  }

  // ========= BÚSQUEDA =========
  buscarAutorizaciones(): void {
    this.limpiarMensajes();

    if (!this.fecha_inicio?.value || !this.fecha_fin?.value) {
      this.errorMessage = 'Debes seleccionar ambas fechas.';
      return;
    }

    const inicio = new Date(this.fecha_inicio.value);
    const fin = new Date(this.fecha_fin.value);

    if (inicio > fin) {
      this.errorMessage = 'La fecha de inicio no puede ser mayor que la fecha de fin.';
      return;
    }

    // Guardamos las fechas ya formateadas para reutilizarlas
    this.fechaInicioApi = this.formatDateForInput(inicio);
    this.fechaFinApi = this.formatDateForInput(fin);

    this.isLoading = true;
    this.autorizaciones = [];
    this.autorizacionesFiltradas = [];
    this.hayResultados = false;

    this.authService
      .getAutorizacionesPorFecha(
        this.fechaInicioApi!,
        this.fechaFinApi!,
        this.limiteAutorizaciones,
        0
      )
      .pipe(finalize(() => {
        this.isLoading = false;
        this.cdr.detectChanges();
      }))
      .subscribe({
        next: (data) => {
          this.autorizaciones = data || [];
          this.aplicarFiltroNumero();
          this.hayResultados = this.autorizaciones.length > 0;
          this.avisoAutorizaciones =
            this.autorizaciones.length >= this.limiteAutorizaciones;

          if (!this.hayResultados) {
            this.successMessage = 'No hay autorizaciones en ese rango de fechas.';
          }
        },
        error: (err) => {
          console.error(err);
          this.errorMessage =
            err?.error?.error || 'Error consultando las autorizaciones.';
        }
      });
  }

  // ========= PDF INDIVIDUAL =========
  descargarPdf(autorizacion: any): void {
    this.limpiarMensajes();

    if (!this.puedeDescargarPdfAutorizacion(autorizacion)) {
      this.errorMessage = 'Autorizacion pendiente o no autorizada.';
      return;
    }

    const numeroAutorizacion = String(autorizacion?.numero_autorizacion || '');
    if (!numeroAutorizacion) {
      this.errorMessage = 'Numero de autorizacion invalido.';
      return;
    }
    this.descargandoPdf = true;

    this.authService.crearJobPdfAutorizacion(numeroAutorizacion).subscribe({
      next: (job) => {
        this.jobsService.pollJob(job.id).subscribe({
          next: (estado) => {
            if (estado.status === 'completed') {
              const fileName =
                estado.result?.fileName || `autorizacion_${numeroAutorizacion}.pdf`;

              this.jobsService.downloadJobFile(job.id).subscribe({
                next: (blob) => {
                  const url = window.URL.createObjectURL(blob);
                  const a = document.createElement('a');
                  a.href = url;
                  a.download = fileName;
                  document.body.appendChild(a);
                  a.click();
                  document.body.removeChild(a);
                  window.URL.revokeObjectURL(url);

                  this.successMessage = 'PDF descargado correctamente.';
                  this.finalizarDescargaPdf();
                },
                error: (error) => {
                  console.error(error);
                  this.errorMessage = 'Error descargando el PDF.';
                  this.finalizarDescargaPdf();
                }
              });
            }

            if (estado.status === 'failed') {
              this.errorMessage =
                estado.error?.message ||
                'Error generando el PDF de la autorizaci?n.';
              this.finalizarDescargaPdf();
            }
          },
          error: (error) => {
            console.error(error);
            this.errorMessage = 'Error consultando el estado del PDF.';
            this.finalizarDescargaPdf();
          }
        });
      },
      error: (error) => {
        console.error(error);
        this.errorMessage = 'Error solicitando la generaci?n del PDF.';
        this.finalizarDescargaPdf();
      }
    });
  }

  // ========= ESTADO DE AUTORIZACION =========
  actualizarEstadoAutorizacion(
    autorizacion: any,
    estado: 'pendiente' | 'autorizado' | 'no_autorizado'
  ): void {
    if (!this.esAdmin) {
      return;
    }

    if (!autorizacion) return;

    const numero = String(autorizacion.numero_autorizacion || '');
    if (!numero) return;

    if (this.actualizandoEstado[numero]) {
      return;
    }

    this.actualizandoEstado[numero] = true;
    const estadoPrevio = autorizacion.estado_autorizacion || 'pendiente';
    autorizacion.estado_autorizacion = estado;

    this.pacienteService
      .actualizarEstadoAutorizacion(numero, estado)
      .pipe(
        finalize(() => {
          this.actualizandoEstado[numero] = false;
          this.cdr.detectChanges();
        })
      )
      .subscribe({
        next: (resp) => {
          autorizacion.estado_autorizacion =
            resp?.autorizacion?.estado_autorizacion || estado;
        },
        error: (err) => {
          console.error(err);
          autorizacion.estado_autorizacion = estadoPrevio;
          this.errorMessage =
            err?.error?.error || 'Error actualizando el estado.';
        }
      });
  }

  aplicarEstadoMasivo(): void {
    this.limpiarMensajes();

    if (!this.esAdmin) {
      this.errorMessage = 'No tienes permisos para actualizar estados.';
      return;
    }

    if (!this.fechaInicioApi || !this.fechaFinApi) {
      this.errorMessage = 'Primero realiza una busqueda por fechas.';
      return;
    }

    const confirmacion = confirm(
      `¿Seguro que deseas aplicar "${this.getEstadoAutorizacionLabel(this.estadoMasivo)}" a todas las autorizaciones del rango?`
    );
    if (!confirmacion) {
      return;
    }

    this.actualizandoMasivo = true;

    this.pacienteService
      .actualizarEstadoAutorizacionesMasivo(
        this.fechaInicioApi,
        this.fechaFinApi,
        this.estadoMasivo
      )
      .subscribe({
        next: (resp) => {
          const total = resp?.actualizados ?? 0;
          this.autorizaciones = this.autorizaciones.map((aut) => ({
            ...aut,
            estado_autorizacion: this.estadoMasivo,
          }));
          this.aplicarFiltroNumero();
          this.successMessage = `Se actualizaron ${total} autorizaciones.`;
          this.actualizandoMasivo = false;
          this.cdr.detectChanges();
        },
        error: (err) => {
          console.error(err);
          this.errorMessage =
            err?.error?.error || 'Error actualizando estados.';
          this.actualizandoMasivo = false;
          this.cdr.detectChanges();
        }
      });
  }

  // ========= USUARIO =========
  logout(): void {
    this.authService.logout();
  }

  isLoggedIn(): boolean {
    return this.authService.isLoggedIn();
  }

  getCurrentUser(): any {
    return this.authService.getCurrentUser();
  }

  puedeDescargarPdfAutorizacion(autorizacion: any): boolean {
    if (this.esAdmin) {
      return true;
    }
    const estado = String(autorizacion?.estado_autorizacion || 'pendiente').toLowerCase();
    return estado === 'autorizado';
  }

  // ========= ZIP CON TODAS LAS AUTORIZACIONES =========
  descargarTodosLosPdfs(): void {
    this.limpiarMensajes();

    if (!this.esAdmin) {
      this.errorMessage = 'No tienes permisos para descargar todos los PDFs.';
      return;
    }

    if (!this.autorizaciones || this.autorizaciones.length === 0) {
      this.errorMessage = 'No hay autorizaciones para descargar.';
      return;
    }

    if (!this.fechaInicioApi || !this.fechaFinApi) {
      this.errorMessage = 'Primero realiza una b?squeda por fechas.';
      return;
    }

    this.descargandoZip = true;

    this.authService
      .crearJobZipAutorizaciones(this.fechaInicioApi, this.fechaFinApi)
      .subscribe({
        next: (job) => {
          this.jobsService.pollJob(job.id).subscribe({
            next: (estado) => {
              if (estado.status === 'completed') {
                const fileName =
                  estado.result?.fileName ||
                  `autorizaciones_${this.fechaInicioApi}_${this.fechaFinApi}.zip`;

                this.jobsService.downloadJobFile(job.id).subscribe({
                  next: (blob) => {
                    const url = window.URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = fileName;
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                    window.URL.revokeObjectURL(url);

                    this.successMessage = 'ZIP descargado correctamente.';
                    this.finalizarDescargaZip();
                  },
                  error: (error) => {
                    console.error(error);
                    this.errorMessage = 'Error descargando el ZIP.';
                    this.finalizarDescargaZip();
                  }
                });
              }

              if (estado.status === 'failed') {
                this.errorMessage =
                  estado.error?.message ||
                  'Error generando el ZIP de autorizaciones.';
                this.finalizarDescargaZip();
              }
            },
            error: (error) => {
              console.error(error);
              this.errorMessage = 'Error consultando el estado del ZIP.';
              this.finalizarDescargaZip();
            }
          });
        },
        error: (error) => {
          console.error(error);
          this.errorMessage = 'Error solicitando el ZIP de autorizaciones.';
          this.finalizarDescargaZip();
        }
      });
  }

  // ========= NAVEGACIÓN =========
  volverAtras(): void {
    this.document.defaultView?.history.back();
  }

  // ========= UTILIDADES =========
  private formatDateForInput(date: Date): string {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
  }

  formatDate(dateString: string): string {
    const date = new Date(dateString);
    return date.toLocaleDateString('es-ES', {
      year: 'numeric',
      month: 'short',
      day: 'numeric'
    });
  }

  formatDateTime(dateString: string): string {
    const date = new Date(dateString);
    return date.toLocaleDateString('es-ES', {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    });
  }

  getTipoAutorizacionLabel(tipo: string | null | undefined): string {
    const normalizado = String(tipo || '').toLowerCase();
    if (normalizado === 'consultas_externas') {
      return 'Consultas externas';
    }
    if (normalizado === 'brigadas_ambulancias_hospitalarios') {
      return 'Brigadas/Ambulancias/Hospitalarios';
    }
    return tipo ? String(tipo) : '';
  }

  getTipoServicioLabel(tipo: string | null | undefined): string {
    const normalizado = String(tipo || '').toLowerCase();
    if (normalizado === 'brigadas') {
      return 'Brigadas';
    }
    if (normalizado === 'ambulancias') {
      return 'Ambulancias';
    }
    if (normalizado === 'hospitalarios') {
      return 'Hospitalarios';
    }
    return tipo ? String(tipo) : '';
  }

  getEstadoAutorizacionLabel(estado: string | null | undefined): string {
    const normalizado = String(estado || 'pendiente').toLowerCase();
    if (normalizado === 'autorizado') {
      return 'Autorizado';
    }
    if (normalizado === 'no_autorizado') {
      return 'No autorizado';
    }
    return 'Pendiente';
  }

  getCoberturaLabel(autorizacion: any): string {
    if (autorizacion?.cup_cubierto === true) {
      return 'Cubre';
    }
    if (autorizacion?.cup_cubierto === false) {
      return 'No cubre';
    }
    if (autorizacion?.cup_descripcion || autorizacion?.cup_nivel) {
      return 'Cubre';
    }
    return 'No cubre';
  }

  esCupCubierto(autorizacion: any): boolean {
    return this.getCoberturaLabel(autorizacion) === 'Cubre';
  }

  onFiltroNumeroChange(valor: string): void {
    this.filtroNumero = valor || '';
    this.aplicarFiltroNumero();
  }

  private aplicarFiltroNumero(): void {
    const filtro = this.filtroNumero.trim().toLowerCase();
    if (!filtro) {
      this.autorizacionesFiltradas = [...this.autorizaciones];
      return;
    }
    this.autorizacionesFiltradas = this.autorizaciones.filter((aut) =>
      String(aut?.numero_autorizacion || '').toLowerCase().includes(filtro)
    );
  }

  limpiarMensajes(): void {
    this.errorMessage = null;
    this.successMessage = null;
  }

  // ========= GETTERS DEL FORM =========
  get fecha_inicio() {
    return this.filtroForm.get('fecha_inicio');
  }

  get fecha_fin() {
    return this.filtroForm.get('fecha_fin');
  }

  // ========= ERRORES DE FORM =========
  getFechaInicioErrorMessage(): string {
    if (this.fecha_inicio?.hasError('required')) {
      return 'La fecha de inicio es requerida';
    }
    return '';
  }

  getFechaFinErrorMessage(): string {
    if (this.fecha_fin?.hasError('required')) {
      return 'La fecha de fin es requerida';
    }
    if (this.fecha_fin?.hasError('fechaInvalida')) {
      return 'La fecha de fin debe ser posterior a la fecha de inicio';
    }
    return '';
  }

  validarFechas(): void {
    const fechaInicio = this.filtroForm.get('fecha_inicio')?.value;
    const fechaFin = this.filtroForm.get('fecha_fin')?.value;

    if (fechaInicio && fechaFin && new Date(fechaFin) < new Date(fechaInicio)) {
      this.filtroForm.get('fecha_fin')?.setErrors({ fechaInvalida: true });
    } else {
      this.filtroForm.get('fecha_fin')?.setErrors(null);
    }
  }

  // ========= EXPORTAR A CSV SIMPLE =========
  exportarAExcel(): void {
    if (!this.esAdmin) {
      this.errorMessage = 'No tienes permisos para exportar.';
      return;
    }

    const dataset = this.autorizacionesFiltradas;

    if (dataset.length === 0) {
      this.errorMessage = 'No hay datos para exportar.';
      return;
    }

    const headers = [
      'Numero Autorizacion',
      'Version',
      'Fecha',
      'Interno',
      'Nombre Paciente',
      'Tipo autorizacion',
      'Tipo servicio',
      'CUPS',
      'Nivel',
      'IPS',
      'Municipio',
      'Departamento',
      'Autorizante',
      'Establecimiento',
      'Estado'
    ];

    const separator = ';';
    const csvContent = [
      headers.map((header) => this.csvValue(header)).join(separator),
      ...dataset.map((aut) =>
        [
          this.csvValue(aut.numero_autorizacion),
          this.csvValue(aut.version || ''),
          this.csvValue(this.formatDateTime(aut.fecha_autorizacion)),
          this.csvValue(aut.interno),
          this.csvValue(aut.nombre_paciente),
          this.csvValue(this.getTipoAutorizacionLabel(aut.tipo_autorizacion)),
          this.csvValue(this.getTipoServicioLabel(aut.tipo_servicio)),
          this.csvValue(aut.cup_codigo || ''),
          this.csvValue(aut.cup_nivel || ''),
          this.csvValue(aut.nombre_ips),
          this.csvValue(aut.municipio),
          this.csvValue(aut.departamento),
          this.csvValue(aut.nombre_autorizante),
          this.csvValue(aut.nombre_establecimiento),
          this.csvValue(this.getEstadoAutorizacionLabel(aut.estado_autorizacion))
        ].join(separator)
      )
    ].join('\n');

    const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
    const link = document.createElement('a');
    const url = URL.createObjectURL(blob);

    link.setAttribute('href', url);
    link.setAttribute(
      'download',
      `autorizaciones_${this.formatDateForInput(new Date())}.csv`
    );
    link.style.visibility = 'hidden';

    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);

    this.successMessage = 'Archivo CSV exportado correctamente.';
  }

  private finalizarDescargaPdf(): void {
    this.descargandoPdf = false;
    this.cdr.detectChanges();
  }

  private finalizarDescargaZip(): void {
    this.descargandoZip = false;
    this.cdr.detectChanges();
  }

  private csvValue(value: unknown): string {
    const raw = value === null || value === undefined ? '' : String(value);
    const escaped = raw.replace(/"/g, '""');
    return `"${escaped}"`;
  }

  trackByAutorizacion(_index: number, item: any): string {
    return item?.numero_autorizacion ?? _index.toString();
  }
}
