

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";
import {
  upsertUser,
  DEFAULT_ROUTE_ID,
  DEFAULT_COLONIA,
} from "../../../data/mocks/users.mock.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,
    });

    // Registrar al user en el "mock de servicio" con ruta default,
    // así el simulador le manda notificaciones desde el primer momento.
    // (En Bloque B1 el user elegirá su colonia/ruta real.)
    upsertUser({
      id: user.id,
      name: user.name,
      email: user.email,
      colonia: DEFAULT_COLONIA,
      routeId: DEFAULT_ROUTE_ID,
    });

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

    return {
      user,
      token,
    };
  }
}
