import type { IUserRepository } from '../../../domain/ports/user-repository'
import type { IPasswordHasher } from '../../../domain/ports/password-hasher'
import type { IRefreshTokenRepository } from '../../../domain/ports/refresh-token-repository'
import type { ITokenService } from '../../../domain/ports/token-service'
import type { UserRole } from '../../../domain/entities/user'
import { AppError } from '../../../domain/errors/app-error'

export interface LoginStaffInput {
  email: string
  password: string
}

export interface LoginStaffOutput {
  accessToken: string
  refreshToken: string
  user: {
    id: string
    fullName: string
    email: string
    role: UserRole
  }
}

export class LoginStaff {
  constructor(
    private readonly userRepo: IUserRepository,
    private readonly hasher: IPasswordHasher,
    private readonly tokenService: ITokenService,
    private readonly refreshTokenRepo: IRefreshTokenRepository,
  ) {}

  async execute(input: LoginStaffInput): Promise<LoginStaffOutput> {
    const user = await this.userRepo.findByEmail(input.email)

    // Respuesta ambigua deliberada: no revela si el email existe
    if (!user) {
      throw new AppError('INVALID_CREDENTIALS', 401, 'Credenciales incorrectas')
    }

    const passwordValid = await this.hasher.verify(input.password, user.passwordHash)
    if (!passwordValid) {
      throw new AppError('INVALID_CREDENTIALS', 401, 'Credenciales incorrectas')
    }

    if (!user.isActive) {
      throw new AppError('ACCOUNT_INACTIVE', 403, 'Cuenta desactivada')
    }

    const accessToken = this.tokenService.generateAccessToken({ userId: user.id, role: user.role })
    const rawRefreshToken = this.tokenService.generateOpaqueToken()
    const tokenHash = this.tokenService.hashToken(rawRefreshToken)
    const expiresAt = new Date(Date.now() + this.tokenService.refreshTokenTtlMs())

    await this.refreshTokenRepo.create({ userId: user.id, tokenHash, expiresAt })

    return {
      accessToken,
      refreshToken: rawRefreshToken,
      user: { id: user.id, fullName: user.fullName, email: user.email, role: user.role },
    }
  }
}
