"""One-time Google Health API authorisation — run on your laptop.

Walks the OAuth consent flow once and prints the refresh token to store as a Fly
secret. After this, the backend refreshes access tokens silently forever (or,
in OAuth "testing" mode, until the 7-day refresh-token expiry — see SETUP doc).

Prereqs (done once in Google Cloud Console, see HEALTH_SETUP.md):
  1. Create a project, enable the Google Health API.
  2. Configure the OAuth consent screen, add yourself as a Test user, add the
     Restricted googlehealth.*.read scopes.
  3. Create an OAuth client of type "Web application" and add this redirect URI:
       http://localhost:8765/callback
  4. Export the client id/secret, then run:
       GOOGLE_HEALTH_CLIENT_ID=... GOOGLE_HEALTH_CLIENT_SECRET=... \
         uv run python -m src.oauth_setup
"""

import json
import os
import urllib.parse
import urllib.request
import webbrowser
from http.server import BaseHTTPRequestHandler, HTTPServer

from health import SCOPES, TOKEN_URL  # reuse the same scope/endpoint config

AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth"
REDIRECT = "http://localhost:8765/callback"

CLIENT_ID = os.getenv("GOOGLE_HEALTH_CLIENT_ID", "")
CLIENT_SECRET = os.getenv("GOOGLE_HEALTH_CLIENT_SECRET", "")

_code: dict[str, str] = {}


class _Handler(BaseHTTPRequestHandler):
    def do_GET(self):  # noqa: N802
        qs = urllib.parse.urlparse(self.path).query
        params = urllib.parse.parse_qs(qs)
        self.send_response(200)
        self.send_header("Content-Type", "text/html")
        self.end_headers()
        if "code" in params:
            _code["code"] = params["code"][0]
            self.wfile.write(b"<h2>Authorised. You can close this tab.</h2>")
        else:
            self.wfile.write(b"<h2>No code received.</h2>")

    def log_message(self, *_):  # silence
        pass


def main() -> None:
    if not (CLIENT_ID and CLIENT_SECRET):
        raise SystemExit("Set GOOGLE_HEALTH_CLIENT_ID and GOOGLE_HEALTH_CLIENT_SECRET first.")

    auth = f"{AUTH_URL}?" + urllib.parse.urlencode(
        {
            "client_id": CLIENT_ID,
            "redirect_uri": REDIRECT,
            "response_type": "code",
            "scope": SCOPES,
            "access_type": "offline",   # ask for a refresh token
            "prompt": "consent",         # force it to be returned every time
        }
    )
    print("Opening browser to authorise. If it doesn't open, visit:\n" + auth + "\n")
    webbrowser.open(auth)

    server = HTTPServer(("localhost", 8765), _Handler)
    while "code" not in _code:
        server.handle_request()

    data = urllib.parse.urlencode(
        {
            "client_id": CLIENT_ID,
            "client_secret": CLIENT_SECRET,
            "code": _code["code"],
            "redirect_uri": REDIRECT,
            "grant_type": "authorization_code",
        }
    ).encode()
    req = urllib.request.Request(TOKEN_URL, data=data)
    with urllib.request.urlopen(req, timeout=15) as resp:
        tokens = json.loads(resp.read().decode())

    refresh = tokens.get("refresh_token")
    if not refresh:
        print("No refresh token returned. Revoke prior access at "
              "https://myaccount.google.com/permissions and retry.")
        print(json.dumps(tokens, indent=2))
        return

    print("\n✅  Success. Store these as Fly secrets:\n")
    print(f'  flyctl secrets set \\\n'
          f'    GOOGLE_HEALTH_CLIENT_ID="{CLIENT_ID}" \\\n'
          f'    GOOGLE_HEALTH_CLIENT_SECRET="{CLIENT_SECRET}" \\\n'
          f'    GOOGLE_HEALTH_REFRESH_TOKEN="{refresh}"\n')
    print("Then verify locally with:  uv run python -m src.health --probe")


if __name__ == "__main__":
    main()
