import base64
import hashlib
import hmac
import os

PBKDF2_PREFIX = "pbkdf2_sha256"
PBKDF2_ITERATIONS = 260_000
SALT_BYTES = 16


def hash_password(raw_password: str) -> str:
    raw_password = str(raw_password or "")
    salt = os.urandom(SALT_BYTES)
    digest = hashlib.pbkdf2_hmac(
        "sha256",
        raw_password.encode("utf-8"),
        salt,
        PBKDF2_ITERATIONS,
    )
    salt_b64 = base64.b64encode(salt).decode("ascii")
    digest_b64 = base64.b64encode(digest).decode("ascii")
    return f"{PBKDF2_PREFIX}${PBKDF2_ITERATIONS}${salt_b64}${digest_b64}"


def is_password_hash(value: str) -> bool:
    return str(value or "").startswith(f"{PBKDF2_PREFIX}$")


def verify_password(raw_password: str, stored_password: str) -> bool:
    raw_password = str(raw_password or "")
    stored_password = str(stored_password or "")

    # Hỗ trợ password cũ đang lưu plaintext để user/staff cũ vẫn login được.
    # Sau khi login đúng, controller sẽ tự đổi password đó sang hash.
    if not is_password_hash(stored_password):
        return hmac.compare_digest(raw_password, stored_password)

    try:
        _, iterations_str, salt_b64, digest_b64 = stored_password.split("$", 3)
        iterations = int(iterations_str)
        salt = base64.b64decode(salt_b64.encode("ascii"))
        expected_digest = base64.b64decode(digest_b64.encode("ascii"))
        actual_digest = hashlib.pbkdf2_hmac(
            "sha256",
            raw_password.encode("utf-8"),
            salt,
            iterations,
        )
        return hmac.compare_digest(actual_digest, expected_digest)
    except Exception:
        return False