const bcrypt = require('bcryptjs');
const JwtService = require('../../services/JwtService');

const jwtService = new JwtService();

/**
 * Register User Command Handler
 * Handles user registration business logic
 */
class RegisterUserCommandHandler {
  constructor(prisma, emailService) {
    this.prisma = prisma;
    this.emailService = emailService;
  }

  /**
   * Execute user registration command
   * @param {RegisterUserCommand} command 
   * @returns {Promise<Object>} { user, token }
   */
  async handle(command) {
    const { name, email, password } = command;

    // Validáció
    if (!name || !email || !password) {
      throw new Error('Name, email and password are required');
    }

    if (password.length < 6) {
      throw new Error('Password must be at least 6 characters long');
    }

    // Email formátum ellenőrzés
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
      throw new Error('Invalid email format');
    }

    // Ellenőrizzük, hogy létezik-e már a user
    const existingUser = await this.prisma.user.findUnique({
      where: { email }
    });

    if (existingUser) {
      throw new Error('User with this email already exists');
    }

    // Jelszó hashelése (bcrypt)
    const hashedPassword = await bcrypt.hash(password, 10);

    // User létrehozása
    const user = await this.prisma.user.create({
      data: {
        name,
        email,
        password: hashedPassword
      }
    });

    // Welcome email küldése (async, nem várunk rá)
    if (this.emailService) {
      this.emailService.sendWelcomeEmail(email, name).catch(err => {
        console.error('❌ Failed to send welcome email:', err.message);
      });
    }

    // JWT token generálása
    const token = jwtService.generateToken({
      userId: user.id,
      email: user.email
    });

    // Jelszót ne adjuk vissza a response-ban
    const { password: _, ...userWithoutPassword } = user;

    return {
      user: userWithoutPassword,
      token
    };
  }
}

module.exports = RegisterUserCommandHandler;
