from __future__ import annotations

from datetime import datetime, timezone
from typing import Any, Dict, Optional

import httpx

from .time import parse_iso_z
from ..exceptions import AuthError
from ..types import TokenResult


def extract_request_id(resp: httpx.Response) -> Optional[str]:
    return resp.headers.get("X-Request-Id") or resp.headers.get("X-Request-ID")


def build_default_headers(
    *,
    headers: Optional[Dict[str, str]],
    accept: str,
    content_type: Optional[str] = None,
) -> Dict[str, str]:
    final_headers: Dict[str, str] = {"Accept": accept}
    if content_type:
        final_headers["Content-Type"] = content_type
    if headers:
        final_headers.update(headers)
    return final_headers


def is_expiring_soon(expires_at: datetime, refresh_skew_seconds: int) -> bool:
    now = datetime.now(timezone.utc)
    return (expires_at - now).total_seconds() <= refresh_skew_seconds


def build_auth_payload(*, access_key_id: str, access_key_secret: str) -> Dict[str, str]:
    return {
        "access_key_id": access_key_id,
        "access_key_secret": access_key_secret,
    }


def parse_token_result(data: Any) -> TokenResult:
    if not isinstance(data, dict) or data.get("status") != "SUCCESS":
        raise AuthError(f"token API returned non-success: {data}")

    result = data.get("result") or {}
    token = result.get("token")
    expiration = result.get("expiration")
    if not token or not expiration:
        raise AuthError(f"token API response missing fields: {data}")

    return TokenResult(token=token, expiration=parse_iso_z(expiration))
