<?php
/**
 * Verificación y hash de contraseñas (compatible con WordPress y PHP nativo).
 */

final class JB_Password {

	/**
	 * @param string $password Contraseña en texto plano.
	 * @param string $hash     Hash almacenado.
	 * @return bool
	 */
	public static function verify( $password, $hash ) {
		$hash = (string) $hash;
		if ( '' === $hash ) {
			return false;
		}

		// WordPress 6.8+: prefijo $wp$ sobre bcrypt.
		if ( str_starts_with( $hash, '$wp$' ) ) {
			$hash = substr( $hash, 4 );
		}

		// WordPress clásico (phpass $P$ / $H$).
		if ( str_starts_with( $hash, '$P$' ) || str_starts_with( $hash, '$H$' ) ) {
			return self::verify_phpass( $password, $hash );
		}

		return password_verify( $password, $hash );
	}

	/**
	 * @param string $password Contraseña en texto plano.
	 * @return string
	 */
	public static function hash( $password ) {
		return password_hash( $password, PASSWORD_DEFAULT );
	}

	/**
	 * @param string $password Contraseña en texto plano.
	 * @param string $stored   Hash phpass.
	 * @return bool
	 */
	private static function verify_phpass( $password, $stored ) {
		if ( strlen( $stored ) !== 34 ) {
			return false;
		}
		$itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
		$count  = 1 << strpos( $itoa64, $stored[3] );
		$salt   = substr( $stored, 4, 8 );
		$hash   = md5( $salt . $password, true );
		do {
			$hash = md5( $hash . $password, true );
		} while ( --$count );
		$output = substr( $stored, 0, 12 );
		$i      = 0;
		while ( $i < 16 ) {
			$value = ord( $hash[ $i++ ] );
			$output .= $itoa64[ $value & 0x3f ];
			if ( $i < 16 ) {
				$value |= ord( $hash[ $i ] ) << 8;
				$output .= $itoa64[ ( $value >> 6 ) & 0x3f ];
				if ( $i++ >= 16 ) {
					break;
				}
				$value |= ord( $hash[ $i ] ) << 16;
				$output .= $itoa64[ ( $value >> 12 ) & 0x3f ];
				if ( $i++ >= 16 ) {
					break;
				}
				$output .= $itoa64[ ( $value >> 18 ) & 0x3f ];
			}
		}
		return hash_equals( $stored, $output );
	}
}

function wp_check_password( $password, $hash, $user_id = '' ) {
	return JB_Password::verify( $password, $hash );
}

function wp_hash_password( $password ) {
	return JB_Password::hash( $password );
}
