#!/usr/bin/env python3
"""
anthropic-balance-check.py
Scrapes the Remaining Balance from platform.claude.com/settings/billing
via the OpenClaw browser CLI (CDP, openclaw profile).
Updates memory/vital-balance-anchor.json preserving all other fields.
"""

import json
import re
import subprocess
import sys
import datetime

BILLING_URL = "https://platform.claude.com/settings/billing"
ANCHOR_FILE = "/Users/aicomputer/.openclaw/workspace/memory/vital-balance-anchor.json"
OPENCLAW_BIN = "/opt/homebrew/bin/openclaw"
BROWSER_PROFILE = "openclaw"


def get_billing_tab_id():
    """Return the CDP target ID of the billing tab, or None if not found."""
    result = subprocess.run(
        [OPENCLAW_BIN, "browser", "--browser-profile", BROWSER_PROFILE, "tabs", "--json"],
        capture_output=True, text=True, timeout=15
    )
    if result.returncode != 0:
        return None
    try:
        data = json.loads(result.stdout)
        tabs = data.get("tabs", data) if isinstance(data, dict) else data
    except json.JSONDecodeError:
        return None
    for tab in tabs:
        url = tab.get("url", "")
        if "claude.com/settings/billing" in url and tab.get("type", "page") == "page":
            return tab.get("targetId") or tab.get("id")
    # return first page tab as fallback
    for tab in tabs:
        if tab.get("type", "page") == "page":
            return tab.get("targetId") or tab.get("id")
    return None


def navigate_to_billing(tab_id):
    """Navigate a tab to the billing page."""
    cmd = [
        OPENCLAW_BIN, "browser", "--browser-profile", BROWSER_PROFILE,
        "navigate", "--url", BILLING_URL,
    ]
    if tab_id:
        cmd += ["--target-id", tab_id]
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
    return result.returncode == 0


def evaluate_body_text(tab_id):
    """Run document.body.innerText on the given tab and return the text."""
    cmd = [
        OPENCLAW_BIN, "browser", "--browser-profile", BROWSER_PROFILE,
        "evaluate",
        "--fn", "() => document.body.innerText",
    ]
    if tab_id:
        cmd += ["--target-id", tab_id]
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=20)
    if result.returncode != 0:
        print(f"[evaluate stderr] {result.stderr[:200]}", file=sys.stderr)
        return ""
    # The CLI returns a JSON-encoded string; parse it to get the real text
    raw = result.stdout.strip()
    try:
        return json.loads(raw)
    except json.JSONDecodeError:
        return raw


def parse_balance(text):
    """Extract dollar amount from billing page text."""
    # Handles both inline and newline-separated formats:
    # "$163.17 Remaining Balance" or "$163.17\nRemaining Balance"
    m = re.search(r'\$([0-9,]+\.[0-9]{2})\s*\n?\s*Remaining\s+Balance', text)
    if m:
        return float(m.group(1).replace(",", ""))
    # Fallback: "Remaining Balance" then nearby dollar amount
    m = re.search(r'Remaining\s+Balance[^\$]*\$([0-9,]+\.[0-9]{2})', text)
    if m:
        return float(m.group(1).replace(",", ""))
    return None


def get_today_spend():
    """Get today's cumulative spend from openclaw usage-cost. Returns float or 0.0."""
    try:
        result = subprocess.run(
            ["openclaw", "gateway", "usage-cost", "--json", "--days", "1"],
            capture_output=True, text=True, timeout=15
        )
        if result.returncode != 0:
            return 0.0
        data = json.loads(result.stdout)
        today = datetime.date.today().strftime("%Y-%m-%d")
        for d in data.get("daily", []):
            if d.get("date") == today:
                return float(d.get("totalCost", 0.0))
        return 0.0
    except Exception:
        return 0.0


def update_anchor(balance):
    """
    Write anchor_balance + anchor_date + anchor_spend_at_set + last_checked.
    Resets anchor to today so delta math starts clean from this scrape.
    """
    try:
        with open(ANCHOR_FILE) as f:
            anchor = json.load(f)
    except (FileNotFoundError, json.JSONDecodeError):
        anchor = {}

    today_spend = get_today_spend()
    today_date  = datetime.date.today().strftime("%Y-%m-%d")

    anchor["anchor_balance"]      = balance
    anchor["anchor_date"]         = today_date
    anchor["anchor_spend_at_set"] = today_spend
    anchor["last_checked"]        = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
    anchor["source"]              = "direct — scraped from console.anthropic.com/settings/billing"

    with open(ANCHOR_FILE, "w") as f:
        json.dump(anchor, f, indent=2)
        f.write("\n")


def main():
    print("Finding billing tab…")
    tab_id = get_billing_tab_id()
    if tab_id:
        print(f"Using tab {tab_id}")
    else:
        print("No tab found, will open new one.")

    # Try to get text; navigate first if needed
    text = evaluate_body_text(tab_id)
    balance = parse_balance(text)

    if balance is None:
        print("Balance not found on current page — navigating to billing…")
        navigate_to_billing(tab_id)
        import time; time.sleep(5)
        text = evaluate_body_text(tab_id)
        balance = parse_balance(text)

    if balance is None:
        print("ERROR: Could not find 'Remaining Balance' on page.", file=sys.stderr)
        snippet = text[:600] if text else "(empty)"
        print(f"Page snippet:\n{snippet}", file=sys.stderr)
        sys.exit(1)

    print(f"Balance: ${balance:.2f}")
    update_anchor(balance)
    print(f"Updated {ANCHOR_FILE}")


if __name__ == "__main__":
    main()
