#!/usr/bin/env python3
"""
Standalone CLI for LinkedIn Recruiter bridge. Zero dependencies (stdlib only).

Install:
    pip install linkedin-bridge

First login (saves token to ~/.linkedin-bridge-token):
    linkedin-bridge login --email user@example.com --password secret

Usage:
    linkedin-bridge parseCandidateList
    linkedin-bridge changeStage --stageName "Grade 5"
    linkedin-bridge navigateToUrl --url "https://www.linkedin.com/talent/hire/123/discover/pipeline"
    linkedin-bridge clickCandidateByIndex --index 3

Override API URL:
    LINKEDIN_BRIDGE_URL=http://localhost:8321 linkedin-bridge ping
"""

import json
import os
import sys
import urllib.error
import urllib.request
from pathlib import Path

API_BASE = os.environ.get("LINKEDIN_BRIDGE_URL", "https://sourcer.8d1.ai")
TOKEN_FILE = Path.home() / ".linkedin-bridge-token"


def _load_token():
    """Load saved JWT access token."""
    if TOKEN_FILE.exists():
        return TOKEN_FILE.read_text().strip()
    return None


def _save_token(token):
    """Save JWT access token to file."""
    TOKEN_FILE.write_text(token)
    TOKEN_FILE.chmod(0o600)


def _auth_headers():
    """Return Authorization header if token exists."""
    token = _load_token()
    if token:
        return {"Authorization": f"Bearer {token}"}
    return {}


def http_get(url):
    headers = _auth_headers()
    req = urllib.request.Request(url, headers=headers)
    try:
        with urllib.request.urlopen(req, timeout=5) as resp:
            return json.loads(resp.read())
    except urllib.error.HTTPError as e:
        if e.code == 401:
            print("ERROR: Not authenticated. Run: linkedin-bridge login --email EMAIL --password PASS", file=sys.stderr)
            sys.exit(1)
        raise
    except urllib.error.URLError:
        print("ERROR: API not reachable at " + API_BASE, file=sys.stderr)
        sys.exit(1)


def http_post(url, body):
    data = json.dumps(body).encode()
    headers = {"Content-Type": "application/json"}
    headers.update(_auth_headers())
    req = urllib.request.Request(url, data=data, headers=headers)
    try:
        with urllib.request.urlopen(req, timeout=35) as resp:
            return resp.status, json.loads(resp.read())
    except urllib.error.HTTPError as e:
        if e.code == 401:
            print("ERROR: Not authenticated. Run: linkedin-bridge login --email EMAIL --password PASS", file=sys.stderr)
            sys.exit(1)
        try:
            detail = json.loads(e.read()).get("detail", str(e))
        except Exception:
            detail = str(e)
        return e.code, {"detail": detail}
    except urllib.error.URLError:
        print("ERROR: Connection lost", file=sys.stderr)
        sys.exit(1)


def cmd_login(args):
    """Authenticate with email/password and save token."""
    params = _parse_params(args)
    email = params.get("email")
    password = params.get("password")

    if not email or not password:
        print("Usage: linkedin-bridge login --email EMAIL --password PASSWORD", file=sys.stderr)
        sys.exit(1)

    code, data = http_post(
        f"{API_BASE}/api/login",
        {"email": email, "password": password},
    )

    if code != 200:
        print(f"ERROR: Login failed — {data.get('detail', data)}", file=sys.stderr)
        sys.exit(1)

    token = data.get("access_token")
    if not token:
        print("ERROR: No access_token in response", file=sys.stderr)
        sys.exit(1)

    _save_token(token)
    print(f"Logged in. Token saved to {TOKEN_FILE}")


def _parse_params(args):
    """Parse --key value pairs from args list."""
    params = {}
    i = 0
    while i < len(args):
        if args[i].startswith("--"):
            key = args[i][2:]
            if i + 1 < len(args) and not args[i + 1].startswith("--"):
                val = args[i + 1]
                if val.isdigit():
                    val = int(val)
                elif val.lower() in ("true", "false"):
                    val = val.lower() == "true"
                params[key] = val
                i += 2
            else:
                params[key] = True
                i += 1
        else:
            i += 1
    return params


def main():
    if len(sys.argv) < 2:
        print("Usage: linkedin-bridge <action> [--param value ...]", file=sys.stderr)
        print("       linkedin-bridge login --email EMAIL --password PASSWORD", file=sys.stderr)
        sys.exit(1)

    action = sys.argv[1]

    # Login is handled separately
    if action == "login":
        return cmd_login(sys.argv[2:])

    params = _parse_params(sys.argv[2:])

    # Get session
    status = http_get(f"{API_BASE}/api/bridge/status")
    if not status.get("connected") or not status.get("session_id"):
        print("ERROR: Bridge not connected", file=sys.stderr)
        sys.exit(1)

    session_id = status["session_id"]

    # Execute
    code, data = http_post(
        f"{API_BASE}/api/bridge/{session_id}/execute",
        {"action": action, "params": params, "timeout": 30},
    )

    if code != 200:
        print(f"ERROR: {data.get('detail', data)}", file=sys.stderr)
        sys.exit(1)

    print(json.dumps(data.get("result", data), indent=2, ensure_ascii=False))


if __name__ == "__main__":
    sys.exit(main())
