import re
import secrets
import string
from datetime import datetime, timezone
from decimal import ROUND_DOWN, ROUND_HALF_UP, Decimal

_ALPHABET = string.ascii_uppercase + string.digits
_SLUG_RE = re.compile(r"[^a-z0-9]+")


def utcnow() -> datetime:
    return datetime.now(timezone.utc)


def random_code(length: int = 8) -> str:
    return "".join(secrets.choice(_ALPHABET) for _ in range(length))


def order_number() -> str:
    return f"{utcnow().strftime('%y%m%d')}{random_code(6)}"


def slugify(value: str) -> str:
    slug = _SLUG_RE.sub("-", (value or "").strip().lower()).strip("-")
    return slug or random_code(6).lower()


def money(value: Decimal | float | int | str) -> Decimal:
    """Round to 2 decimals; used for all fiat/wallet amounts."""
    return Decimal(str(value)).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)


def crypto(value: Decimal | float | int | str, places: int = 6) -> Decimal:
    exp = Decimal(1).scaleb(-places)
    return Decimal(str(value)).quantize(exp, rounding=ROUND_DOWN)


def as_bool(value: object, default: bool = False) -> bool:
    if isinstance(value, bool):
        return value
    if value is None:
        return default
    return str(value).strip().lower() in {"1", "true", "yes", "on"}
