from uuid import uuid4
from pathlib import Path
from typing import Any
import json
import os
import webbrowser
from termcolor import colored

SESSION_PATH = Path.home() / ".envis" / "session.json"

def _get_env_url(var_name: str, default: str) -> str:
    """
    Read a URL override from environment variables with a safe fallback.
    Trailing slashes are stripped so joins don't produce double slashes.
    """
    value = os.getenv(var_name)
    if not value:
        return default
    return value.rstrip("/")

BASE_URL = _get_env_url("ENVIS_API_URL", "https://envis.onrender.com")
FRONTEND_URL = _get_env_url("ENVIS_DASH_URL", "https://envisible.netlify.app")
WAIT_TIME = 120
POLL_DELAY_SECONDS = 5

def load_session() -> dict:
    """
    Load the cached session tokens that the CLI stored after login.
    """

    if not SESSION_PATH.exists():
        device_code = uuid4()
        raise RuntimeError(
            f"Not authenticated. Visit {FRONTEND_URL}/auth?device_code={device_code} to link this device."
        )

    try:
        session = json.loads(SESSION_PATH.read_text(encoding="utf-8"))
    except json.JSONDecodeError as exc:
        raise RuntimeError("Session file is corrupt. Re-run `envis login`.") from exc

    access_token = session.get("access_token")
    if not access_token:
        raise RuntimeError("Session missing access_token. Re-run `envis login`.")

    return session


def write_session(session_info: dict[str, Any]) -> None:
    """
    Persist the Supabase session locally so future calls can reuse it.
    """
    if not isinstance(session_info, dict):
        raise RuntimeError("Session payload must be a dictionary.")

    try:
        payload = json.dumps(session_info, indent=2)
    except (TypeError, ValueError) as exc:
        raise RuntimeError("Session payload is not JSON serializable.") from exc

    try:
        SESSION_PATH.parent.mkdir(parents=True, exist_ok=True)
        SESSION_PATH.write_text(payload, encoding="utf-8")
        os.chmod(SESSION_PATH, 0o600)
    except OSError as exc:
        raise RuntimeError(f"Failed to write session cache: {exc}") from exc

def ensure_session() -> None:

    from .auth import wait_for_auth

    if SESSION_PATH.exists():
        return

    device_code = str(uuid4())
    auth_url = f"{FRONTEND_URL}/auth?device_code={device_code}"

    print(colored("No cached session detected.", "red"))

    try:
        webbrowser.open(auth_url, new=2)
        print(f"\nTrying to open:")
        print(colored(f"        {auth_url}", "blue"))
    except Exception:
        print(colored("Could not open browser automatically – open \n {auth_url}", "red"))

    print("\nWaiting for the session to be approved...")
    wait_for_auth(device_code)
    print(colored("\nDevice approved and session saved locally.", "green"))
