#!/usr/bin/env python3
"""
TK — Manual keyboard-controlled trader for Turbo.

Hotkeys:
  [7] SELL YES  (hit best YES bid)
  [8] BUY YES   (lift best YES ask)
  [9] BUY NO    (lift best NO ask)
  [0] SELL NO   (hit best NO bid)

  [B] Place resting BUY YES at custom price
  [S] Place resting SELL YES at custom price

  [G] Start auto-join mode (follow best bid/ask)
  [N] Cancel all orders
  [P] Show position
  [Q] Quit

Usage:
  python3 mm/tk.py --wallet 0xYOUR_WALLET
  python3 mm/tk.py --wallet 0xYOUR_WALLET --size 2
"""

import argparse
import sys
import threading
import time

sys.path.insert(0, sys.path[0])
from turbo_client import TurboClient

PRICE_SCALE = 1_000_000

# Cross-platform key reading
try:
    import tty
    import termios

    def get_key():
        fd = sys.stdin.fileno()
        old = termios.tcgetattr(fd)
        try:
            tty.setraw(fd)
            return sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old)
except ImportError:
    import msvcrt
    def get_key():
        return msvcrt.getch().decode("utf-8", errors="ignore")


def main():
    parser = argparse.ArgumentParser(description="TK — Manual trader for Turbo")
    parser.add_argument("--wallet", required=True, help="Trader wallet address")
    parser.add_argument("--size", type=float, default=1.0, help="Order size in USDC (default: 1)")
    parser.add_argument("--url", default="http://localhost:8080", help="Backend URL")
    args = parser.parse_args()

    client = TurboClient(args.wallet, args.url)
    size_raw = int(args.size * PRICE_SCALE)

    # State
    join_mode = False
    join_bid_id = None
    join_ask_id = None
    running = True

    def show_status():
        """Print current market + orderbook status."""
        try:
            mkt = client.get_market()
            market_id = mkt.get("marketId", "")
            btc = mkt.get("btcPrice", 0)
            strike = mkt.get("strikePrice", 0)
            secs = mkt.get("secondsRemaining", 0)

            yes_book = mkt.get("yesBook", {})
            best_bid = yes_book.get("bids", [{}])[0] if yes_book.get("bids") else {}
            best_ask = yes_book.get("asks", [{}])[0] if yes_book.get("asks") else {}

            bid_c = f"{int(best_bid['price'] / PRICE_SCALE * 100)}c" if best_bid.get("price") else "--"
            ask_c = f"{int(best_ask['price'] / PRICE_SCALE * 100)}c" if best_ask.get("price") else "--"
            spread = ""
            if best_bid.get("price") and best_ask.get("price"):
                sp = (best_ask["price"] - best_bid["price"]) / (PRICE_SCALE / 100)
                spread = f" ({sp:.0f}c spread)"

            print(
                f"\r[TK] BTC ${btc:,.0f} | Strike ${strike:,.0f} | "
                f"Bid {bid_c} / Ask {ask_c}{spread} | "
                f"{secs}s left | {'JOIN' if join_mode else 'MANUAL'}",
                end="", flush=True
            )
        except Exception as e:
            print(f"\r[TK] Error: {e}", end="", flush=True)

    def join_loop():
        """Background loop for auto-join mode."""
        nonlocal join_bid_id, join_ask_id, join_mode
        last_bid_price = 0
        last_ask_price = 0

        while running and join_mode:
            try:
                mkt = client.get_market()
                yes_book = mkt.get("yesBook", {})
                bids = yes_book.get("bids", [])
                asks = yes_book.get("asks", [])

                # Find best bid/ask that isn't ours
                my_orders = {o["id"] for o in client.get_my_orders()}

                target_bid = 0
                for b in bids:
                    target_bid = b["price"]
                    break

                target_ask = 0
                for a in asks:
                    target_ask = a["price"]
                    break

                # Join best bid + 0.5c
                join_bid = target_bid + 5000 if target_bid else 450000
                join_ask = target_ask - 5000 if target_ask else 550000

                # Only update if price changed > 1c
                if abs(join_bid - last_bid_price) >= 10000:
                    if join_bid_id:
                        try:
                            client.cancel_order(join_bid_id)
                        except Exception:
                            pass
                    result = client.place_order(side=0, outcome=0, price=join_bid, size=size_raw)
                    join_bid_id = result.get("orderId")
                    last_bid_price = join_bid

                if abs(join_ask - last_ask_price) >= 10000:
                    if join_ask_id:
                        try:
                            client.cancel_order(join_ask_id)
                        except Exception:
                            pass
                    result = client.place_order(side=1, outcome=0, price=join_ask, size=size_raw)
                    join_ask_id = result.get("orderId")
                    last_ask_price = join_ask

            except Exception as e:
                print(f"\n[JOIN] Error: {e}")

            time.sleep(2)

    print(f"[TK] Keyboard Trader started")
    print(f"[TK] Wallet: {args.wallet}")
    print(f"[TK] Size:   ${args.size}")
    print()
    print("[TK] Keys: [7]SellY [8]BuyY [9]BuyN [0]SellN [G]Join [N]Cancel [P]Pos [Q]Quit")
    print()

    # Status display loop
    def status_loop():
        while running:
            show_status()
            time.sleep(3)

    t = threading.Thread(target=status_loop, daemon=True)
    t.start()

    while running:
        try:
            key = get_key().lower()

            if key == "q":
                print("\n[TK] Quitting — cancelling all orders...")
                client.cancel_all()
                running = False
                break

            elif key == "8":
                # BUY YES — lift best ask
                mkt = client.get_market()
                asks = mkt.get("yesBook", {}).get("asks", [])
                if asks:
                    price = asks[0]["price"]
                    result = client.place_order(side=0, outcome=0, price=price, size=size_raw)
                    c = int(price / PRICE_SCALE * 100)
                    print(f"\n[TK] BUY YES @ {c}c → {result.get('status', '?')}")
                else:
                    print("\n[TK] No YES asks")

            elif key == "7":
                # SELL YES — hit best bid
                mkt = client.get_market()
                bids = mkt.get("yesBook", {}).get("bids", [])
                if bids:
                    price = bids[0]["price"]
                    result = client.place_order(side=1, outcome=0, price=price, size=size_raw)
                    c = int(price / PRICE_SCALE * 100)
                    print(f"\n[TK] SELL YES @ {c}c → {result.get('status', '?')}")
                else:
                    print("\n[TK] No YES bids")

            elif key == "9":
                # BUY NO — lift best NO ask
                mkt = client.get_market()
                asks = mkt.get("noBook", {}).get("asks", [])
                if asks:
                    price = asks[0]["price"]
                    result = client.place_order(side=0, outcome=1, price=price, size=size_raw)
                    c = int(price / PRICE_SCALE * 100)
                    print(f"\n[TK] BUY NO @ {c}c → {result.get('status', '?')}")
                else:
                    print("\n[TK] No NO asks")

            elif key == "0":
                # SELL NO — hit best NO bid
                mkt = client.get_market()
                bids = mkt.get("noBook", {}).get("bids", [])
                if bids:
                    price = bids[0]["price"]
                    result = client.place_order(side=1, outcome=1, price=price, size=size_raw)
                    c = int(price / PRICE_SCALE * 100)
                    print(f"\n[TK] SELL NO @ {c}c → {result.get('status', '?')}")
                else:
                    print("\n[TK] No NO bids")

            elif key == "g":
                join_mode = not join_mode
                if join_mode:
                    print("\n[TK] JOIN mode ON — auto-following best bid/ask")
                    jt = threading.Thread(target=join_loop, daemon=True)
                    jt.start()
                else:
                    print("\n[TK] JOIN mode OFF")
                    if join_bid_id:
                        try:
                            client.cancel_order(join_bid_id)
                        except Exception:
                            pass
                        join_bid_id = None
                    if join_ask_id:
                        try:
                            client.cancel_order(join_ask_id)
                        except Exception:
                            pass
                        join_ask_id = None

            elif key == "n":
                n = client.cancel_all()
                join_bid_id = None
                join_ask_id = None
                print(f"\n[TK] Cancelled {n} orders")

            elif key == "p":
                pos = client.get_position()
                yes_s = pos.get("yesShares", 0) / PRICE_SCALE
                no_s = pos.get("noShares", 0) / PRICE_SCALE
                inv = pos.get("totalInvested", 0) / PRICE_SCALE
                print(f"\n[TK] Position: YES {yes_s:.2f} | NO {no_s:.2f} | Invested ${inv:.2f}")

            elif key == "b":
                # Place resting BUY YES at custom price
                print("\n[TK] Enter BUY YES price in cents (e.g. 45): ", end="", flush=True)
                # Read digits until enter
                price_str = ""
                while True:
                    ch = get_key()
                    if ch in ("\r", "\n"):
                        break
                    if ch.isdigit():
                        price_str += ch
                        print(ch, end="", flush=True)
                if price_str:
                    price = int(price_str) * (PRICE_SCALE // 100)
                    result = client.place_order(side=0, outcome=0, price=price, size=size_raw)
                    print(f" → {result.get('status', '?')} (id: {result.get('orderId', '?')})")

            elif key == "s":
                # Place resting SELL YES at custom price
                print("\n[TK] Enter SELL YES price in cents (e.g. 55): ", end="", flush=True)
                price_str = ""
                while True:
                    ch = get_key()
                    if ch in ("\r", "\n"):
                        break
                    if ch.isdigit():
                        price_str += ch
                        print(ch, end="", flush=True)
                if price_str:
                    price = int(price_str) * (PRICE_SCALE // 100)
                    result = client.place_order(side=1, outcome=0, price=price, size=size_raw)
                    print(f" → {result.get('status', '?')} (id: {result.get('orderId', '?')})")

        except KeyboardInterrupt:
            print("\n[TK] Quitting...")
            client.cancel_all()
            running = False
            break

    print("[TK] Done.")


if __name__ == "__main__":
    main()
