from __future__ import annotations

import hashlib
import hmac
from typing import Any

from app.config import settings
from app.core.crypto import decrypt_secret, encrypt_secret


def decrypt_optional(value: Any) -> str | None:
    if value in (None, ""):
        return None
    text = str(value)
    try:
        return decrypt_secret(text)
    except Exception:
        # Legacy rows may still contain plaintext. Treat them as readable and
        # rewrite them on the next successful update.
        return text


def encrypt_optional(value: Any) -> str | None:
    if value in (None, ""):
        return None
    text = str(value).strip()
    if not text:
        return None
    try:
        decrypt_secret(text)
        return text
    except Exception:
        return encrypt_secret(text)


def deterministic_hash(value: Any) -> str | None:
    if value in (None, ""):
        return None
    text = str(value).strip().upper()
    if not text:
        return None
    return hmac.new(
        settings.JWT_SECRET_KEY.encode("utf-8"),
        text.encode("utf-8"),
        hashlib.sha256,
    ).hexdigest()


def mask_id_card(value: Any) -> str | None:
    plain = decrypt_optional(value)
    if not plain:
        return None
    text = plain.strip().upper()
    if len(text) == 18:
        return text[:6] + "********" + text[14:]
    return text[:4] + "****" + text[-4:] if len(text) > 8 else "****"


def mask_name(value: Any) -> str | None:
    plain = decrypt_optional(value)
    if not plain:
        return None
    text = plain.strip()
    if len(text) == 2:
        return text[0] + "*"
    if len(text) >= 3:
        return text[0] + "*" * (len(text) - 1)
    return "*"


def is_masked(value: Any) -> bool:
    return isinstance(value, str) and "*" in value
