import os, json, time, requests
from datetime import datetime, timezone
from typing import Optional, Dict, Any

DEFAULT_EVENT_MANAGER_URL = "https://f2fgmuihpg.execute-api.us-west-2.amazonaws.com/prod/events"
EVENT_MANAGER_URL = os.getenv("EVENT_MANAGER_URL", DEFAULT_EVENT_MANAGER_URL)
HTTP_TIMEOUT_S = float(os.getenv("CBX_HTTP_TIMEOUT_S", "10"))
RETRIES = int(os.getenv("CBX_RETRIES", "2"))

def _now_iso() -> str:
    return datetime.now(timezone.utc).isoformat()

def _post_event_manager(message: Dict[str, Any]) -> int:
    payload = {"message": message}
    last_exc = None
    for attempt in range(RETRIES + 1):
        try:
            print(f"[CBX SDK] → {EVENT_MANAGER_URL}: {json.dumps(payload)}")
            resp = requests.post(EVENT_MANAGER_URL, json=payload, timeout=HTTP_TIMEOUT_S)
            print(f"[CBX SDK] ← {resp.status_code} {resp.text if resp.status_code>=400 else ''}")
            return resp.status_code
        except Exception as e:
            last_exc = e
            time.sleep(min(0.25 * (2**attempt), 2.0))
    print(f"[CBX SDK] POST failed: {last_exc}")
    return 599

def post_start(agent_id: str, session_id: str, initiated_by: str, authtoken: str) -> int:
    return _post_event_manager({
        "event": "start",
        "agent_id": agent_id,
        "subject": session_id,
        "initiatedBy": initiated_by,
        "authtoken": authtoken
    })

def post_status_change(agent_id: str, session_id: str, initiated_by: str, authtoken: str,
                       new_status: str = "Completed", status_message: Optional[str] = None) -> int:
    return _post_event_manager({
        "event": "statuschange",
        "agent_id": agent_id,
        "subject": session_id,
        "initiatedBy": initiated_by,
        "authtoken": authtoken,
        "statusMessage": status_message or f"Run {new_status.lower()}."
    })

def post_health(agent_id: str, session_id: str, initiated_by: str, authtoken: str,
                health_score: int, condition: str, unhealth_endpoints: Optional[list] = None,
                timestamp: Optional[str] = None) -> int:
    return _post_event_manager({
        "event": "health",
        "agent_id": agent_id,
        "subject": session_id,
        "initiatedBy": initiated_by,
        "authtoken": authtoken,
        "healthScore": int(health_score),
        "condition": condition,
        "unhealth_endpoints": unhealth_endpoints or [],
        "timestamp": timestamp or _now_iso()
    })

def post_error(agent_id: str, session_id: str, initiated_by: str, authtoken: str,
               error_code: str, error_message: str, severity: str = "ERROR",
               stack_trace: Optional[str] = None, timestamp: Optional[str] = None) -> int:
    return _post_event_manager({
        "event": "error",
        "agent_id": agent_id,
        "subject": session_id,
        "initiatedBy": initiated_by,
        "authtoken": authtoken,
        "errorCode": error_code,
        "errorMessage": error_message,
        "severity": severity,
        "stackTrace": stack_trace,
        "timestamp": timestamp or _now_iso()
    })

def post_heartbeat(agent_id: str, session_id: str, initiated_by: str, authtoken: str,
                   status: str, active_task: str, previous_task: str, nexttaskdelay: Optional[int] = None) -> int:
    return _post_event_manager({
        "event": "heartbeat",
        "agent_id": agent_id,
        "subject": session_id,
        "initiatedBy": initiated_by,
        "authtoken": authtoken,
        "status": status,
        "active_task": active_task,
        "previous_task": previous_task,
        "nexttaskdelay": int(nexttaskdelay) if nexttaskdelay is not None else None
    })

