"""pulse-tv CLI — start the TradingView webhook server."""

import argparse
import json
import logging
import os
import sys
import time

from pulse_tradingview.converter import AlertConverter
from pulse_tradingview.router import SignalRouter
from pulse_tradingview.webhook import WebhookReceiver


def setup_logging(verbose: bool) -> None:
    level = logging.DEBUG if verbose else logging.INFO
    logging.basicConfig(
        level=level,
        format="%(asctime)s [%(levelname)s] %(message)s",
        datefmt="%H:%M:%S",
    )


def load_config(path: str) -> dict:
    if not os.path.exists(path):
        return {}
    with open(path) as f:
        return json.load(f)


def build_router(config: dict) -> SignalRouter:
    router = SignalRouter()

    if "binance" in config:
        from pulse_binance import BinanceAdapter
        c = config["binance"]
        adapter = BinanceAdapter(
            api_key=c["api_key"],
            api_secret=c["api_secret"],
            testnet=c.get("testnet", False),
        )
        router.add_adapter(adapter, "Binance")

    if "bybit" in config:
        from pulse_bybit import BybitAdapter
        c = config["bybit"]
        adapter = BybitAdapter(
            api_key=c["api_key"],
            api_secret=c["api_secret"],
            testnet=c.get("testnet", False),
        )
        router.add_adapter(adapter, "Bybit")

    if "kraken" in config:
        from pulse_kraken import KrakenAdapter
        c = config["kraken"]
        adapter = KrakenAdapter(api_key=c["api_key"], api_secret=c["api_secret"])
        router.add_adapter(adapter, "Kraken")

    if "okx" in config:
        from pulse_okx import OKXAdapter
        c = config["okx"]
        adapter = OKXAdapter(
            api_key=c["api_key"],
            api_secret=c["api_secret"],
            passphrase=c["passphrase"],
        )
        router.add_adapter(adapter, "OKX")

    if "freqtrade" in config:
        from pulse_freqtrade import FreqtradeAdapter
        c = config["freqtrade"]
        adapter = FreqtradeAdapter(
            url=c.get("url", "http://localhost:8080"),
            username=c.get("username", "freqtrader"),
            password=c["password"],
        )
        router.add_adapter(adapter, "Freqtrade")

    # Confidence filter
    min_confidence = config.get("min_confidence", 0.0)
    if min_confidence > 0:
        router.add_filter(lambda p: p.get("confidence", 1.0) >= min_confidence)

    # Pair whitelist
    pairs = config.get("pairs", [])
    if pairs:
        router.add_filter(lambda p: p.get("pair") in pairs)

    return router


def cmd_start(args):
    """Start the webhook server."""
    config = load_config(args.config)
    setup_logging(args.verbose)

    router = build_router(config)

    if not router._adapters:
        print("Warning: No exchanges configured. Signals will be logged but not executed.")
        print(f"Create a config file: pulse-tv init --output {args.config}")

    def on_signal(params):
        print(
            f"  Signal: {params.get('pair')} | {params.get('direction').upper()} | "
            f"confidence={params.get('confidence', 1.0):.0%} | "
            f"price={params.get('price', 'market')}"
        )
        return router.route(params)

    receiver = WebhookReceiver(
        port=args.port,
        on_signal=on_signal,
        secret=args.secret or config.get("secret"),
    )

    print(f"\npulse-tradingview v0.1.1")
    print(f"Webhook server: http://0.0.0.0:{args.port}/")
    print(f"Health check:   http://localhost:{args.port}/")
    if router._adapters:
        print(f"Exchanges:      {', '.join(name for name, _ in router._adapters)}")
    print(f"\nIn TradingView → Alert → Webhook URL:")
    print(f"  http://YOUR_PUBLIC_IP:{args.port}/\n")
    print("Waiting for signals... (Ctrl+C to stop)\n")

    receiver.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("\nStopping...")
        receiver.stop()


def cmd_init(args):
    """Create a sample config file."""
    sample = {
        "binance": {
            "api_key": "YOUR_BINANCE_API_KEY",
            "api_secret": "YOUR_BINANCE_API_SECRET",
            "testnet": False
        },
        "min_confidence": 0.7,
        "pairs": ["BTC/USDT", "ETH/USDT", "SOL/USDT"],
        "secret": "optional-shared-secret-for-security"
    }
    output = args.output or "pulse_tv_config.json"
    with open(output, "w") as f:
        json.dump(sample, f, indent=2)
    print(f"Created: {output}")
    print("Edit it to add your exchange API keys and remove exchanges you don't use.")


def cmd_test(args):
    """Send a test signal to a running webhook server."""
    import urllib.request

    payload = json.dumps({
        "action": args.action,
        "symbol": args.symbol.replace("/", ""),
        "price": str(args.price) if args.price else "0",
        "interval": "1h",
        "confidence": str(args.confidence),
    }).encode()

    url = f"http://localhost:{args.port}/"
    req = urllib.request.Request(
        url, data=payload,
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=5) as r:
            result = json.loads(r.read())
            print(f"Response: {json.dumps(result, indent=2)}")
    except Exception as e:
        print(f"Error: {e}")
        print(f"Is the server running? Start it with: pulse-tv start")


def main():
    parser = argparse.ArgumentParser(
        prog="pulse-tv",
        description="TradingView webhook server for PULSE Protocol.",
    )
    subparsers = parser.add_subparsers(dest="command")

    # start
    start_p = subparsers.add_parser("start", help="Start webhook server")
    start_p.add_argument("--port", type=int, default=8888, help="Port (default: 8888)")
    start_p.add_argument("--config", default="pulse_tv_config.json", help="Config file")
    start_p.add_argument("--secret", help="Shared secret for webhook validation")
    start_p.add_argument("--verbose", "-v", action="store_true")

    # init
    init_p = subparsers.add_parser("init", help="Create sample config")
    init_p.add_argument("--output", help="Output file path")

    # test
    test_p = subparsers.add_parser("test", help="Send test signal to running server")
    test_p.add_argument("--port", type=int, default=8888)
    test_p.add_argument("--action", default="buy", choices=["buy", "sell", "close"])
    test_p.add_argument("--symbol", default="BTC/USDT")
    test_p.add_argument("--price", type=float)
    test_p.add_argument("--confidence", type=float, default=0.9)

    args = parser.parse_args()

    if args.command == "start":
        cmd_start(args)
    elif args.command == "init":
        cmd_init(args)
    elif args.command == "test":
        cmd_test(args)
    else:
        parser.print_help()


if __name__ == "__main__":
    main()
