import base64
import hashlib
import hmac
import secrets
from datetime import datetime, timezone
from typing import Iterable

from cryptography.fernet import Fernet
from flask import current_app, request


def utcnow_naive() -> datetime:
    return datetime.now(timezone.utc).replace(tzinfo=None)


def _derived_fernet_key() -> str:
    digest = hashlib.sha256(current_app.config["SECRET_KEY"].encode("utf-8")).digest()
    return base64.urlsafe_b64encode(digest).decode("utf-8")


def get_fernet() -> Fernet:
    key = current_app.config.get("APP_ENCRYPTION_KEY") or _derived_fernet_key()
    return Fernet(key.encode("utf-8"))


def get_key_hash_pepper() -> bytes:
    pepper = current_app.config.get("KEY_HASH_PEPPER") or current_app.config["SECRET_KEY"]
    return pepper.encode("utf-8")


def encrypt_text(value: str) -> str:
    return get_fernet().encrypt(value.encode("utf-8")).decode("utf-8")


def decrypt_text(value: str) -> str:
    return get_fernet().decrypt(value.encode("utf-8")).decode("utf-8")


def generate_access_key() -> str:
    token = secrets.token_urlsafe(24)
    return f"DLV-{token}"


def normalize_access_key(raw_key: str) -> str:
    return raw_key.strip()


def hash_access_key(raw_key: str) -> str:
    normalized = normalize_access_key(raw_key).encode("utf-8")
    return hmac.new(get_key_hash_pepper(), normalized, hashlib.sha256).hexdigest()


def mask_access_key(raw_key: str) -> str:
    compact = normalize_access_key(raw_key)
    if len(compact) <= 10:
        return compact
    return f"{compact[:8]}...{compact[-4:]}"


def split_nonempty_lines(value: str) -> list[str]:
    return [line.strip() for line in value.splitlines() if line.strip()]


def chunk_join(values: Iterable[str]) -> str:
    return "\n".join(values)


def client_ip() -> str:
    forwarded_for = request.headers.get("X-Forwarded-For", "")
    if forwarded_for:
        return forwarded_for.split(",")[0].strip()[:64]
    return (request.remote_addr or "unknown")[:64]
