/**
 * register-user.use-case.ts
 * RegisterUserUseCase: lógica para registrar un usuario.
 * - Valida datos
 * - Verifica si el email ya existe
 * - Hashea la contraseña
 * - Crea el usuario
 * - Genera el JWT
 */

import { RegisterUserDto, RegisterUserDtoValidator } from "../../dtos/index.js";
import { AuthRepository } from "../../repositories/auth.repository.js";
import { CustomError } from "../../errors/custom.error.js";
import { BcryptAdapter } from "../../../config/bcrypt.js";
import { JwtAdapter } from "../../../config/jwt.js";

export interface RegisterUserResponse {
  user: {
    id: number;
    email: string;
    name: string;
  };
  token: string;
}

export class RegisterUserUseCase {
  constructor(private repository: AuthRepository) {}

  async execute(data: unknown): Promise<RegisterUserResponse> {
    // Validar DTO
    const dto = RegisterUserDtoValidator.validate(data);

    // Verificar si el email ya existe
    const existingUser = await this.repository.findByEmail(dto.email);
    if (existingUser) {
      throw CustomError.conflict("Email already in use");
    }

    // Hashear la contraseña
    const hashedPassword = await BcryptAdapter.hash(dto.password);

    // Crear el usuario
    const user = await this.repository.create({
      name: dto.name,
      email: dto.email,
      password: hashedPassword,
    });

    // Generar JWT
    const token = JwtAdapter.generate({
      id: user.id,
      email: user.email,
    });

    return {
      user,
      token,
    };
  }
}
