<?php

namespace App\Services\Security;

class Pbkdf2Hasher
{
    public function hash(string $password, string $algo = 'sha256', int $iterations = 100000, int $length = 64): string
    {
        $salt = random_bytes(16);
        $saltHex = bin2hex($salt);

        $derived = hash_pbkdf2($algo, $password, $salt, $iterations, $length, true);
        $derivedHex = bin2hex($derived);

        return implode('$', [$algo, $iterations, $saltHex, $derivedHex]);
    }

    public function verify(string $password, string $storedHash): bool
    {
        $parts = explode('$', $storedHash);
        if (count($parts) !== 4) {
            return false;
        }

        [$algo, $iterations, $saltHex, $derivedHex] = $parts;
        if (strlen($saltHex) % 2 !== 0 || strlen($derivedHex) % 2 !== 0) {
            return false;
        }

        $salt = hex2bin($saltHex);
        $derived = hex2bin($derivedHex);
        if ($salt === false || $derived === false) {
            return false;
        }

        $length = strlen($derived);
        $calc = hash_pbkdf2($algo, $password, $salt, (int) $iterations, $length, true);

        return hash_equals($derived, $calc);
    }
}
