/**
 * RegisterUser use case. Orchestrates domain + ports; knows no HTTP.
 * FEAT-199: creates unconfirmed user, generates confirmation token, sends confirmation email.
 */
import type { PasswordHasher, UserRepository } from '../domain/ports.js';
import type { User } from '../domain/user.js';
import { normalizeEmail } from '../domain/user.js';

export interface RegisterInput {
  email: string;
  password: string;
}

export interface RegisterDeps {
  users: UserRepository;
  hasher: PasswordHasher;
  generateToken: () => string;
  /** Best-effort: delivery failure must NOT block registration. */
  sendConfirmationEmail?: (input: { email: string; confirmUrl: string }) => Promise<void>;
  /** Build absolute confirmation URL from raw token. */
  buildConfirmUrl: (token: string) => string;
}

export class RegisterUser {
  constructor(private readonly deps: RegisterDeps) {}

  async execute(input: RegisterInput): Promise<User> {
    const email = normalizeEmail(input.email);
    const passwordHash = await this.deps.hasher.hash(input.password);
    const confirmationToken = this.deps.generateToken();
    const user = await this.deps.users.create({ email, passwordHash, confirmationToken });
    if (this.deps.sendConfirmationEmail) {
      void this.deps.sendConfirmationEmail({
        email,
        confirmUrl: this.deps.buildConfirmUrl(confirmationToken),
      }).catch((err: unknown) => {
        console.error('confirmation_email_failed', err);
      });
    }
    return user;
  }
}
