import {
  BadRequestException,
  Injectable,
  NotFoundException,
  UnauthorizedException,
} from '@nestjs/common';
import { CreateUsuarioDto } from './dto/create-usuario.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Tipo_Usuario, Usuario } from './entities/usuario.entity';
import { Repository } from 'typeorm';
import * as bcrypt from 'bcryptjs';

@Injectable()
export class UsuariosService {
  constructor(
    @InjectRepository(Usuario)
    private readonly usuarioRepository: Repository<Usuario>,

    @InjectRepository(Tipo_Usuario)
    private readonly tipoUsuarioRepository: Repository<Tipo_Usuario>,
  ) {}

  async usuarios() {
    return await this.usuarioRepository.find({ relations: ['tipoUsuario'] });
  }

  async actualizarUsuario(
    id: number,
    datos: {
      nombre?: string;
      contraseñaN?: string;
      id_tipo_usuario?: number;
      contraseñaV?: string;
    },
  ) {
    // Buscar al usuario
    const usuario = await this.usuarioRepository.findOne({
      where: { id_usuario: id },
      relations: ['tipoUsuario'],
    });

    if (!usuario) {
      throw new NotFoundException('Usuario no encontrado');
    }

    // Actualizar nombre
    if (datos.nombre) {
      usuario.nombre = datos.nombre;
    }

    // Actualizar contraseña con hash
    if (datos.contraseñaN && datos.contraseñaV) {
      const contraseñaValida = await bcrypt.compare(
        datos.contraseñaV,
        usuario.contraseña,
      );

      if (!contraseñaValida) {
        throw new UnauthorizedException('Contraseña inválida');
      }

      const hashed = await bcrypt.hash(datos.contraseñaN, 10);
      usuario.contraseña = hashed;
    }

    // Actualizar tipo de usuario
    if (datos.id_tipo_usuario) {
      const tipo = await this.tipoUsuarioRepository.findOne({
        where: { id_tipo_usuario: datos.id_tipo_usuario },
      });

      if (!tipo) {
        throw new BadRequestException('El tipo de usuario no existe');
      }

      usuario.tipoUsuario = tipo;
    }

    // Guardar cambios
    return await this.usuarioRepository.save(usuario);
  }

  async create(createUsuarioDto: CreateUsuarioDto) {
    let user = await this.usuarioRepository.create({
      nombre: createUsuarioDto.nombre,
      contraseña: createUsuarioDto.contraseña,
      tipoUsuario: {
        id_tipo_usuario: createUsuarioDto.tipoUsuario,
      },
    });

    return await this.usuarioRepository.save(user);
  }
  async findOneByName(nombre: string) {
    return await this.usuarioRepository.findOne({
      where: { nombre },
      relations: ['tipoUsuario'],
    });
  }

  async createUser(tipoUsuario: string) {
    let user = await this.tipoUsuarioRepository.create({
      tipo_usuario: tipoUsuario,
    });
    return await this.tipoUsuarioRepository.save(user);
  }
}
