# apps/aroflo_connector_app/core/auth.py

from __future__ import annotations

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

import hmac
import hashlib

from .config import settings


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

    uencoded=...&pencoded=...&orgEncoded=...
    (todo URI-encoded en Postman, pero ya viene encoded desde AroFlo)
    """
    # Estas variables ya deberían venir codificadas 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)
    # incluimos milisegundos
    iso = now.isoformat(timespec="milliseconds")
    # Convertimos '+00:00' a 'Z'
    return iso.replace("+00:00", "Z")


def build_hmac_signature(
    request_type: str,
    var_string: str,
    authorization: str,
    iso_timestamp: str,
) -> 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 = ""  # En la doc dice 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_bytes = hmac.new(
        key=settings.secret_key.encode("utf-8"),
        msg=payload_str.encode("utf-8"),
        digestmod=hashlib.sha512,
    ).hexdigest()

    headers = {
        "Authentication": f"HMAC {signature_bytes}",
        "Accept": settings.accept,
        "Authorization": authorization,
        "afdatetimeutc": iso_timestamp,
    }

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

    return signature_bytes, headers


