# NOVA_CLI\nova_cli\nova_core\auth\client.py

import os
import time
import webbrowser
import requests
from typing import Optional, Dict, Any


class NovaAuthClient:
    def __init__(self, base_url: Optional[str] = None):
        # Priority:
        # 1) passed base_url
        # 2) env NOVA_AUTH_BASE_URL
        # 3) default production
        resolved = base_url or os.getenv("NOVA_AUTH_BASE_URL") or "https://nova.bridgeye.com"
        self.base_url = resolved.rstrip("/")

        # Basic client identity (helps audit logs + debugging)
        self.user_agent = os.getenv("NOVA_USER_AGENT", "NovaCLI/1.0")

    def _headers(self) -> Dict[str, str]:
        return {"User-Agent": self.user_agent}

    def create_session(self) -> str:
        # Render can cold-start, keep this lenient
        r = requests.post(
            f"{self.base_url}/auth/session",
            timeout=30,
            headers=self._headers(),
        )
        r.raise_for_status()
        data = r.json()
        return data["session_id"]

    def open_browser(self, session_id: str) -> None:
        url = f"{self.base_url}/login?session_id={session_id}"
        webbrowser.open(url)

    def poll_session(self, session_id: str, timeout: int = 300) -> Optional[str]:
        start = time.time()

        while time.time() - start < timeout:
            try:
                r = requests.get(
                    f"{self.base_url}/auth/session/{session_id}",
                    timeout=10,
                    headers=self._headers(),
                )

                if r.status_code == 200:
                    data = r.json()
                    if data.get("status") == "approved":
                        return data.get("auth_code")

            except Exception:
                pass

            time.sleep(2)

        return None

    def exchange_auth_code(self, auth_code: str) -> Dict[str, Any]:
        try:
            r = requests.post(
                f"{self.base_url}/auth/token",
                json={"auth_code": auth_code},
                timeout=20,
                headers=self._headers(),
            )

            if r.status_code != 200:
                return {
                    "error": "token_exchange_failed",
                    "status": r.status_code,
                    "body": r.text,
                }

            return r.json()

        except Exception as e:
            return {"error": "request_failed", "body": str(e)}

    def refresh_access(self, refresh_token: str) -> Dict[str, Any]:
        try:
            r = requests.post(
                f"{self.base_url}/auth/refresh",
                json={"refresh_token": refresh_token},
                timeout=20,
                headers=self._headers(),
            )

            if r.status_code != 200:
                return {
                    "error": "refresh_failed",
                    "status": r.status_code,
                    "body": r.text,
                }

            return r.json()

        except Exception as e:
            return {"error": "request_failed", "body": str(e)}
