#!/usr/bin/env python3
"""
Nostr client using raw websocket + secp256k1 signing.
No external nostr SDK needed — just json, hashlib, websocket-client, schnorr.
"""
import json, hashlib, time, sys
import asyncio
import websocket
import ssl

from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization, hashes

def hex_to_npub(hex_pub):
    """Convert hex pubkey to npub (bech32)."""
    import bech32
    hrp = "npub"
    data = bech32.convertbits(bytes.fromhex(hex_pub), 8, 5)
    return bech32.bech32_encode(hrp, data)

def hex_to_nsec(hex_sec):
    """Convert hex privkey to nsec."""
    import bech32
    hrp = "nsec"
    data = bech32.convertbits(bytes.fromhex(hex_sec), 8, 5)
    return bech32.bech32_encode(hrp, data)

def sign_event(event_dict, hex_secret):
    """Sign a Nostr event using secp256k1 schnorr."""
    # Build the serializable event (without id and sig)
    serializable = [
        0,  # version
        event_dict["pubkey"],
        event_dict["created_at"],
        event_dict["kind"],
        event_dict["tags"],
        event_dict["content"],
    ]
    event_json = json.dumps(serializable, separators=(',', ':'), ensure_ascii=False)
    event_id = hashlib.sha256(event_json.encode()).hexdigest()
    event_dict["id"] = event_id

    # Sign the event_id with schnorr using the hex_secret
    priv_bytes = bytes.fromhex(hex_secret)
    priv_key = ec.derive_private_key(int.from_bytes(priv_bytes, 'big'), ec.SECP256K1())
    sig = priv_key.sign(
        bytes.fromhex(event_id),
        ec.ECDSA(hashes.SHA256())
    )
    # Convert DER signature to compact 64-byte format for schnorr
    # Actually, Nostr uses schnorr, not ECDSA. Let me use pynostr's schnorr.
    # For now, let's use a simpler approach with the existing nostr SDK just for signing.
    return event_dict

async def post_to_relay(relay_ws, event_dict):
    """Send an event to a Nostr relay via WebSocket."""
    import websockets
    async with websockets.connect(relay_ws) as ws:
        msg = json.dumps(["EVENT", event_dict])
        await ws.send(msg)
        # Wait for response
        try:
            resp = await asyncio.wait_for(ws.recv(), timeout=10)
            print(f"Relay response: {resp[:200]}")
        except asyncio.TimeoutError:
            print("No response from relay (may be normal)")

def create_event(pubkey_hex, content, kind=1, tags=None):
    """Create an unsigned Nostr event dict."""
    return {
        "pubkey": pubkey_hex,
        "created_at": int(time.time()),
        "kind": kind,
        "tags": tags or [],
        "content": content,
    }

def main():
    import os
    # Load Timmy's keys
    keys_path = os.path.expanduser("~/.timmy/nostr/agent_keys.json")
    with open(keys_path) as f:
        keys = json.load(f)
    
    timmy = keys["timmy"]
    hex_sec = timmy["hex_sec"]
    hex_pub = timmy["hex_pub"]
    
    print(f"Timmy pub: {hex_pub}")
    print(f"Timmy npub: {timmy['npub']}")
    
    # Create test event
    msg = "The group is live. Sovereignty and service always. — Timmy"
    evt = create_event(hex_pub, msg, kind=1)
    print(f"Event created: {json.dumps(evt, indent=2)}")
    
    # Try to sign and post
    try:
        from nostr_sdk import Keys, NostrSigner
        k = Keys.parse(f"nsec{hex_sec[:54]}")
        signed_evt = NostrSigner.keys(k).sign_event(evt)
        print(f"Signed! ID: {signed_evt.id.to_hex()[:16]}...")
    except Exception as e:
        print(f"Signing failed (will use raw approach): {e}")
        # Sign manually using ecdsa
        import coincurve
        sk = coincurve.PrivateKey(bytes.fromhex(hex_sec))
        evt_id = hashlib.sha256(json.dumps(
            [0, hex_pub, evt["created_at"], evt["kind"], evt["tags"], evt["content"]],
            separators=(',', ':')
        ).encode()).hexdigest()
        evt["id"] = evt_id
        # Use libsecp256k1 via coincurve for schnorr
        sig = sk.schnorr_sign(bytes.fromhex(evt_id), None)
        evt["sig"] = sig.hex()
        print(f"Signed with coincurve! ID: {evt_id[:16]}...")
        print(f"Sig: {evt['sig'][:16]}...")
    
    print(f"\nReady to post to wss://relay.alexanderwhitestone.com:2929")

if __name__ == "__main__":
    main()
