import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {
  AuthService,
  ActualizarUsuarioPayload,
  RegisterRequest,
  Rol
} from '../../services/auth';
import {
  Autorizante,
  ActualizarAutorizantePayload,
  CrearAutorizantePayload,
  PacienteService
} from '../../services/paciente';
import { Router } from '@angular/router';
import { AppHeaderComponent } from '../shared/app-header/app-header';

interface AutorizanteEdicion {
  nombre: string;
  telefono: string;
  cargo: string;
  guardando: boolean;
  mensaje: string | null;
  error: string | null;
}

interface UsuarioEdicion {
  username: string;
  nombre_completo: string;
  email: string;
  id_rol: number;
  password: string;
  guardando: boolean;
  mensaje: string | null;
  error: string | null;
}

@Component({
  selector: 'app-usuarios',
  standalone: true,
  imports: [CommonModule, FormsModule, AppHeaderComponent],
  templateUrl: './usuarios.html',
  styleUrls: ['./usuarios.css'],
})
export class UsuariosComponent implements OnInit {

  usuarios: any[] = [];
  roles: Rol[] = [];
  autorizantes: Autorizante[] = [];
  autorizanteEdicion: Record<number, AutorizanteEdicion> = {};
  usuarioEdicion: Record<number, UsuarioEdicion> = {};

  cargandoUsuarios = false;
  errorUsuarios: string | null = null;
  limiteUsuarios = 200;
  avisoUsuarios = false;

  cargandoAutorizantes = false;
  errorAutorizantes: string | null = null;

  creando = false;
  mensajeOk: string | null = null;
  mensajeError: string | null = null;

  creandoAutorizante = false;
  mensajeAutorizanteOk: string | null = null;
  mensajeAutorizanteError: string | null = null;


  nuevoUsuario: RegisterRequest = {
    username: '',
    email: '',
    password: '',
    nombre_completo: '',
    id_rol: 2,   // por defecto administrativo_sede
    sedes: []
  };

  nuevoAutorizante = {
    numero_documento: '',
    tipo_documento: 'CC',
    nombre: '',
    telefono: '',
    cargo: '',
    activo: true
  };

  constructor(
    private authService: AuthService,
    private cdr: ChangeDetectorRef,
    private pacienteService: PacienteService,
    private router: Router
  ) {}

  ngOnInit(): void {
    // si no es admin, lo saco
    if (!this.authService.isAdministrador()) {
      this.router.navigate(['/dashboard']);
      return;
    }

    this.cargarRoles();
    this.cargarUsuarios();
    this.cargarAutorizantesAdmin();
  }

  // ========= HEADER =============

  getNombreUsuario(): string {
    const user = this.authService.getCurrentUser();
    return user?.nombre_completo || 'Usuario';
  }

  getNombreRolFormateado(): string {
    const user = this.authService.getCurrentUser();
    const rol = user?.nombre_rol || '';

    switch (rol) {
      case 'administrador':
        return 'Administrador';
      case 'administrativo_sede':
        return 'Administrativo de Sede';
      default:
        return rol || 'Sin rol';
    }
  }

  logout(): void {
    this.authService.logout();
  }

  volverDashboard(): void {
    this.router.navigate(['/dashboard']);
  }

  // ========= CARGA DE ROLES / USUARIOS =============

  cargarRoles(): void {
    this.authService.getRoles().subscribe({
      next: (roles) => {
        this.roles = roles;
        this.cdr.detectChanges();
      },
      error: (err) => {
        console.error(err);
        this.cdr.detectChanges();
      }
    });
  }

  cargarUsuarios(): void {
    this.cargandoUsuarios = true;
    this.errorUsuarios = null;

    this.authService.getUsuarios(this.limiteUsuarios, 0).subscribe({
      next: (usuarios) => {
        this.usuarios = usuarios;
        this.prepararEdicionUsuarios();
        this.avisoUsuarios = usuarios.length >= this.limiteUsuarios;
        this.cargandoUsuarios = false;
        this.cdr.detectChanges();
      },
      error: (err) => {
        console.error(err);
        this.errorUsuarios = 'Error cargando usuarios.';
        this.cargandoUsuarios = false;
        this.cdr.detectChanges();
      }
    });
  }

  // ========= CREAR USUARIO =============

  crearUsuario(): void {
    this.mensajeOk = null;
    this.mensajeError = null;

    if (!this.nuevoUsuario.username ||
        !this.nuevoUsuario.email ||
        !this.nuevoUsuario.password ||
        !this.nuevoUsuario.nombre_completo) {
      this.mensajeError = 'Completa todos los campos obligatorios.';
      return;
    }

    this.nuevoUsuario.sedes = [];

    this.creando = true;

    this.authService.register(this.nuevoUsuario).subscribe({
      next: (resp: any) => {
        this.mensajeOk = resp?.mensaje || 'Usuario creado correctamente.';
        this.creando = false;

        // Limpiar formulario
        this.nuevoUsuario = {
          username: '',
          email: '',
          password: '',
          nombre_completo: '',
          id_rol: 2,
          sedes: []
        };

        // Recargar lista sin refrescar la página
        this.cargarUsuarios();
        this.cdr.detectChanges();
      },
      error: (err) => {
        console.error(err);
        this.mensajeError = err?.error?.error || 'Error creando el usuario.';
        this.creando = false;
        this.cdr.detectChanges();
      }
    });
  }

  // ========= CREAR AUTORIZANTE =============

  crearAutorizante(): void {
    this.mensajeAutorizanteOk = null;
    this.mensajeAutorizanteError = null;

    if (!this.nuevoAutorizante.numero_documento ||
        !this.nuevoAutorizante.tipo_documento ||
        !this.nuevoAutorizante.nombre) {
      this.mensajeAutorizanteError = 'Completa los campos obligatorios.';
      return;
    }

    const numero = Number(this.nuevoAutorizante.numero_documento);
    if (!Number.isFinite(numero)) {
      this.mensajeAutorizanteError = 'El numero de documento debe ser numerico.';
      return;
    }

    const payload: CrearAutorizantePayload = {
      numero_documento: numero,
      tipo_documento: this.nuevoAutorizante.tipo_documento,
      nombre: this.nuevoAutorizante.nombre,
      telefono: this.nuevoAutorizante.telefono || undefined,
      cargo: this.nuevoAutorizante.cargo || undefined,
      activo: this.nuevoAutorizante.activo
    };

    this.creandoAutorizante = true;

    this.pacienteService.crearAutorizante(payload).subscribe({
      next: (resp: any) => {
        this.mensajeAutorizanteOk =
          resp?.mensaje || 'Autorizante creado correctamente.';
        this.creandoAutorizante = false;

        this.nuevoAutorizante = {
          numero_documento: '',
          tipo_documento: 'CC',
          nombre: '',
          telefono: '',
          cargo: '',
          activo: true
        };

        this.cargarAutorizantesAdmin();
        this.cdr.detectChanges();
      },
      error: (err) => {
        console.error(err);
        this.mensajeAutorizanteError =
          err?.error?.error || 'Error creando el autorizante.';
        this.creandoAutorizante = false;
        this.cdr.detectChanges();
      }
    });
  }

  cambiarEstadoAutorizante(a: Autorizante, activo: boolean): void {
    if (!confirm(`¿Seguro que deseas ${activo ? 'activar' : 'desactivar'} al autorizante "${a.nombre}"?`)) {
      return;
    }

    this.pacienteService.actualizarEstadoAutorizante(a.numero_documento, activo).subscribe({
      next: (resp: any) => {
        if (resp?.autorizante) {
          a.activo = resp.autorizante.activo;
        } else {
          a.activo = activo;
        }
        this.cdr.detectChanges();
      },
      error: (err) => {
        console.error(err);
        alert('Error actualizando estado del autorizante.');
      }
    });
  }

  cargarAutorizantesAdmin(): void {
    this.cargandoAutorizantes = true;
    this.errorAutorizantes = null;

    this.pacienteService.obtenerAutorizantesAdmin().subscribe({
      next: (autorizantes) => {
        this.autorizantes = autorizantes;
        this.prepararEdicionAutorizantes();
        this.cargandoAutorizantes = false;
        this.cdr.detectChanges();
      },
      error: (err) => {
        console.error(err);
        this.errorAutorizantes = 'Error cargando autorizantes.';
        this.cargandoAutorizantes = false;
        this.cdr.detectChanges();
      }
    });
  }

  // ========= ACTIVAR / DESACTIVAR =============

  cambiarEstadoUsuario(u: any, activo: boolean): void {
    if (!confirm(`¿Seguro que deseas ${activo ? 'activar' : 'desactivar'} al usuario "${u.username}"?`)) {
      return;
    }

    this.authService.actualizarEstadoUsuario(u.id_usuario, activo).subscribe({
      next: () => {
        // Actualizamos en memoria para que se vea de una
        u.activo = activo;
      },
      error: (err) => {
        console.error(err);
        alert('Error actualizando estado del usuario.');
      }
    });
  }

  trackByUsuario(_index: number, usuario: any): number | string {
    return usuario?.id_usuario ?? usuario?.username ?? _index;
  }

  trackByAutorizante(_index: number, autorizante: Autorizante): number | string {
    return autorizante?.numero_documento ?? _index;
  }

  private prepararEdicionAutorizantes(): void {
    const edicion: Record<number, AutorizanteEdicion> = {};
    this.autorizantes.forEach((a) => {
      edicion[a.numero_documento] = {
        nombre: a.nombre || '',
        telefono: a.telefono || '',
        cargo: a.cargo || '',
        guardando: false,
        mensaje: null,
        error: null
      };
    });
    this.autorizanteEdicion = edicion;
  }

  private prepararEdicionUsuarios(): void {
    const edicion: Record<number, UsuarioEdicion> = {};
    this.usuarios.forEach((u) => {
      edicion[u.id_usuario] = {
        username: u.username || '',
        nombre_completo: u.nombre_completo || '',
        email: u.email || '',
        id_rol: u.id_rol || 0,
        password: '',
        guardando: false,
        mensaje: null,
        error: null
      };
    });
    this.usuarioEdicion = edicion;
  }

  guardarAutorizante(a: Autorizante): void {
    const edicion = this.autorizanteEdicion[a.numero_documento];
    if (!edicion) {
      return;
    }

    edicion.mensaje = null;
    edicion.error = null;

    const nombreNuevo = (edicion.nombre || '').trim();
    const telefonoNuevo = (edicion.telefono || '').trim();
    const cargoNuevo = (edicion.cargo || '').trim();
    const nombreActual = (a.nombre || '').trim();
    const telefonoActual = (a.telefono || '').trim();
    const cargoActual = (a.cargo || '').trim();

    if (!nombreNuevo) {
      edicion.error = 'El nombre no puede quedar vacio.';
      return;
    }

    if (
      nombreNuevo === nombreActual &&
      telefonoNuevo === telefonoActual &&
      cargoNuevo === cargoActual
    ) {
      edicion.mensaje = 'Sin cambios.';
      return;
    }

    const payload: ActualizarAutorizantePayload = {};
    if (nombreNuevo !== nombreActual) {
      payload.nombre = nombreNuevo;
    }
    if (telefonoNuevo !== telefonoActual) {
      payload.telefono = telefonoNuevo.length ? telefonoNuevo : null;
    }
    if (cargoNuevo !== cargoActual) {
      payload.cargo = cargoNuevo.length ? cargoNuevo : null;
    }

    edicion.guardando = true;

    this.pacienteService.actualizarDatosAutorizante(a.numero_documento, payload).subscribe({
      next: (resp: any) => {
        const actualizado = resp?.autorizante;
        if (actualizado) {
          a.nombre = actualizado.nombre;
          a.telefono = actualizado.telefono;
          a.cargo = actualizado.cargo;
        } else {
          a.nombre = payload.nombre || a.nombre;
          a.telefono = payload.telefono ?? undefined;
          a.cargo = payload.cargo ?? undefined;
        }
        edicion.nombre = a.nombre || '';
        edicion.telefono = a.telefono || '';
        edicion.cargo = a.cargo || '';
        edicion.guardando = false;
        edicion.mensaje = 'Actualizado.';
        this.cdr.detectChanges();
      },
      error: (err) => {
        console.error(err);
        edicion.guardando = false;
        edicion.error = err?.error?.error || 'Error actualizando autorizante.';
        this.cdr.detectChanges();
      }
    });
  }

  guardarUsuario(u: any): void {
    const edicion = this.usuarioEdicion[u.id_usuario];
    if (!edicion) {
      return;
    }

    edicion.mensaje = null;
    edicion.error = null;

    const usernameNuevo = (edicion.username || '').trim();
    const nombreNuevo = (edicion.nombre_completo || '').trim();
    const emailNuevo = (edicion.email || '').trim();
    const rolNuevo = Number(edicion.id_rol);
    const usernameActual = (u.username || '').trim();
    const nombreActual = (u.nombre_completo || '').trim();
    const emailActual = (u.email || '').trim();
    const rolActual = Number(u.id_rol);
    const passwordNueva = edicion.password || '';

    if (!usernameNuevo) {
      edicion.error = 'El usuario no puede quedar vacio.';
      return;
    }

    if (!nombreNuevo) {
      edicion.error = 'El nombre no puede quedar vacio.';
      return;
    }

    if (!emailNuevo) {
      edicion.error = 'El email no puede quedar vacio.';
      return;
    }

    if (!Number.isFinite(rolNuevo) || rolNuevo <= 0) {
      edicion.error = 'El rol no es valido.';
      return;
    }

    const payload: ActualizarUsuarioPayload = {};
    if (usernameNuevo !== usernameActual) {
      payload.username = usernameNuevo;
    }
    if (nombreNuevo !== nombreActual) {
      payload.nombre_completo = nombreNuevo;
    }
    if (emailNuevo !== emailActual) {
      payload.email = emailNuevo;
    }
    if (rolNuevo !== rolActual) {
      payload.id_rol = rolNuevo;
    }
    if (passwordNueva) {
      payload.password = passwordNueva;
    }

    if (!payload.username && !payload.password && !payload.nombre_completo && !payload.email && !payload.id_rol) {
      edicion.mensaje = 'Sin cambios.';
      return;
    }

    edicion.guardando = true;

    this.authService.actualizarUsuario(u.id_usuario, payload).subscribe({
      next: (resp: any) => {
        const actualizado = resp?.usuario;
        if (actualizado?.username) {
          u.username = actualizado.username;
        } else if (payload.username) {
          u.username = payload.username;
        }
        if (actualizado?.nombre_completo) {
          u.nombre_completo = actualizado.nombre_completo;
        } else if (payload.nombre_completo) {
          u.nombre_completo = payload.nombre_completo;
        }
        if (actualizado?.email) {
          u.email = actualizado.email;
        } else if (payload.email) {
          u.email = payload.email;
        }
        if (actualizado?.id_rol) {
          u.id_rol = actualizado.id_rol;
          const rolEncontrado = this.roles.find((r) => r.id_rol === actualizado.id_rol);
          if (rolEncontrado) {
            u.nombre_rol = rolEncontrado.nombre_rol;
          }
        } else if (payload.id_rol) {
          u.id_rol = payload.id_rol;
          const rolEncontrado = this.roles.find((r) => r.id_rol === payload.id_rol);
          if (rolEncontrado) {
            u.nombre_rol = rolEncontrado.nombre_rol;
          }
        }
        edicion.username = u.username || '';
        edicion.nombre_completo = u.nombre_completo || '';
        edicion.email = u.email || '';
        edicion.id_rol = u.id_rol || rolNuevo;
        edicion.password = '';
        edicion.guardando = false;
        edicion.mensaje = 'Actualizado.';
        this.cdr.detectChanges();
      },
      error: (err) => {
        console.error(err);
        edicion.guardando = false;
        edicion.error = err?.error?.error || 'Error actualizando usuario.';
        this.cdr.detectChanges();
      }
    });
  }
}
