#!/usr/bin/env python3
"""One-time Whoop OAuth handshake. Run this once; it stores refresh tokens for the daily pull."""
import json, secrets, string, sys, urllib.parse
from pathlib import Path

import requests

LIFE = Path("/data/cameron/life")
CREDS = LIFE / ".whoop_creds.json"
TOKENS = LIFE / ".whoop_tokens.json"

AUTH_URL = "https://api.prod.whoop.com/oauth/oauth2/auth"
TOKEN_URL = "https://api.prod.whoop.com/oauth/oauth2/token"
SCOPES = "read:cycles read:recovery read:profile read:sleep read:workout offline"


def main():
    creds = json.loads(CREDS.read_text())
    state = "".join(secrets.choice(string.ascii_letters + string.digits) for _ in range(8))

    params = {
        "client_id": creds["client_id"],
        "redirect_uri": creds["redirect_uri"],
        "response_type": "code",
        "scope": SCOPES,
        "state": state,
    }
    auth_url = f"{AUTH_URL}?{urllib.parse.urlencode(params)}"

    print("\n=== Whoop OAuth — Step 1 ===")
    print("Open this URL in your browser:\n")
    print(auth_url)
    print("\nAuthorize the app. Your browser will try to redirect to a localhost URL")
    print("that won't load — that's expected. Copy the FULL URL from the address bar")
    print("(it contains '?code=...&state=...') and paste it below.\n")

    pasted = input("Paste the redirected URL (or just the code): ").strip()

    if pasted.startswith("http"):
        qs = urllib.parse.urlparse(pasted).query
        params = urllib.parse.parse_qs(qs)
        code = params.get("code", [None])[0]
        returned_state = params.get("state", [None])[0]
        if not code:
            print("ERROR: no 'code' parameter found in URL.")
            sys.exit(1)
        if returned_state != state:
            print(f"WARNING: state mismatch. Expected {state}, got {returned_state}.")
    else:
        code = pasted

    print("\n=== Step 2: exchanging code for tokens ===")
    r = requests.post(
        TOKEN_URL,
        data={
            "grant_type": "authorization_code",
            "code": code,
            "client_id": creds["client_id"],
            "client_secret": creds["client_secret"],
            "redirect_uri": creds["redirect_uri"],
        },
        headers={"Content-Type": "application/x-www-form-urlencoded"},
        timeout=30,
    )

    if r.status_code != 200:
        print(f"ERROR {r.status_code}: {r.text}")
        sys.exit(1)

    tokens = r.json()
    TOKENS.write_text(json.dumps(tokens, indent=2))
    TOKENS.chmod(0o600)

    print(f"\nSuccess. Tokens saved to {TOKENS}")
    print(f"  access_token expires in: {tokens.get('expires_in')}s")
    print(f"  refresh_token present: {'refresh_token' in tokens}")
    print(f"  scope: {tokens.get('scope')}")


if __name__ == "__main__":
    main()
