from __future__ import annotations

from datetime import datetime, timezone
from typing import Dict, Tuple

import hmac
import hashlib

from .config import AroFloSettings


def build_authorization_value(settings: AroFloSettings) -> str:
    """
    Construye el header Authorization igual que en Postman:

    uencoded=...&pencoded=...&orgEncoded=...
    (ya vienen encoded desde la consola de AroFlo)
    """
    return (
        f"uencoded={settings.u_encoded}"
        f"&pencoded={settings.p_encoded}"
        f"&orgEncoded={settings.org_encoded}"
    )


def build_timestamp() -> str:
    """
    Genera timestamp ISO 8601 UTC como usa AroFlo.
    Ejemplo: 2018-07-25T01:39:57.135Z
    """
    now = datetime.now(timezone.utc)
    iso = now.isoformat(timespec="milliseconds")
    return iso.replace("+00:00", "Z")


def build_hmac_signature(
    request_type: str,
    var_string: str,
    authorization: str,
    iso_timestamp: str,
    settings: AroFloSettings,
) -> Tuple[str, Dict[str, str]]:
    """
    Replica la lógica del pre-request script de Postman.

    payload = [
        requestType,
        HostIP (si existe),
        urlPath (= ''),
        accept,
        Authorization,
        isoTimestamp,
        VarString,
    ]
    """

    url_path = ""  # La doc indica que por ahora siempre es vacío

    payload_parts = [request_type.upper()]

    if settings.host_ip:
        payload_parts.append(settings.host_ip)

    payload_parts.extend(
        [
            url_path,
            settings.accept,
            authorization,
            iso_timestamp,
            var_string,
        ]
    )

    payload_str = "+".join(payload_parts)

    signature_hex = hmac.new(
        key=settings.api_secret.encode("utf-8"),
        msg=payload_str.encode("utf-8"),
        digestmod=hashlib.sha512,
    ).hexdigest()

    headers: Dict[str, str] = {
        "Authentication": f"HMAC {signature_hex}",
        "Accept": settings.accept,
        "Authorization": authorization,
        "afdatetimeutc": iso_timestamp,
    }

    if settings.host_ip:
        headers["HostIP"] = settings.host_ip

    return signature_hex, headers
