"""Engine commands: status, submit, cancel, positions, orders, fills, kill-switch."""

from __future__ import annotations

import click


@click.command()
@click.pass_context
def status(ctx):
    """Show engine status: PnL, positions, orders, uptime."""
    from horizon.tools import engine_status
    from horizon.cli._fmt import output

    output(engine_status(), json_mode=ctx.obj.get("json", False))


@click.command()
@click.option("--market-id", required=True, help="Market identifier")
@click.option("--side", required=True, type=click.Choice(["buy", "sell"]), help="Order side (buy or sell)")
@click.option("--market-side", default="yes", type=click.Choice(["yes", "no"]), help="Market side (yes or no)")
@click.option("--price", required=True, type=float, help="Limit price (0-1 for prediction markets)")
@click.option("--size", required=True, type=float, help="Order size")
@click.pass_context
def submit(ctx, market_id, side, market_side, price, size):
    """Submit a limit order.

    \b
    Examples:
      horizon submit --market-id will-btc-hit-100k --side buy --price 0.55 --size 10
      horizon submit --market-id will-btc-hit-100k --side sell --market-side no --price 0.45 --size 5
    """
    from horizon.tools import submit_order
    from horizon.cli._fmt import output

    result = submit_order(
        market_id=market_id,
        side=side,
        price=price,
        size=size,
        market_side=market_side,
    )
    output(result, json_mode=ctx.obj.get("json", False))


@click.command()
@click.argument("order_id")
@click.pass_context
def cancel(ctx, order_id):
    """Cancel an order by ID."""
    from horizon.tools import cancel_order
    from horizon.cli._fmt import output

    output(cancel_order(order_id), json_mode=ctx.obj.get("json", False))


@click.command("cancel-all")
@click.pass_context
def cancel_all(ctx):
    """Cancel all open orders."""
    from horizon.tools import cancel_all_orders
    from horizon.cli._fmt import output

    output(cancel_all_orders(), json_mode=ctx.obj.get("json", False))


@click.command("kill-switch")
@click.argument("action", type=click.Choice(["on", "off"]))
@click.option("--reason", default="CLI kill switch", help="Reason for activation")
@click.pass_context
def kill_switch(ctx, action, reason):
    """Activate or deactivate the kill switch."""
    from horizon.tools import activate_kill_switch, deactivate_kill_switch
    from horizon.cli._fmt import output

    if action == "on":
        result = activate_kill_switch(reason)
    else:
        result = deactivate_kill_switch()
    output(result, json_mode=ctx.obj.get("json", False))


@click.command()
@click.option("--market-id", default=None, help="Filter by market ID")
@click.pass_context
def positions(ctx, market_id):
    """Show open positions from the engine."""
    from horizon.tools import list_positions
    from horizon.cli._fmt import output

    output(list_positions(), json_mode=ctx.obj.get("json", False))


@click.command()
@click.option("--market-id", default=None, help="Filter by market ID")
@click.pass_context
def orders(ctx, market_id):
    """Show open orders from the engine."""
    from horizon.tools import list_open_orders
    from horizon.cli._fmt import output

    output(list_open_orders(market_id=market_id), json_mode=ctx.obj.get("json", False))


@click.command()
@click.option("--limit", default=20, help="Number of fills to show")
@click.pass_context
def fills(ctx, limit):
    """Show recent fills from the engine."""
    from horizon.tools import list_recent_fills
    from horizon.cli._fmt import output

    output(list_recent_fills(limit=limit), json_mode=ctx.obj.get("json", False))


@click.command("cancel-market")
@click.argument("market_id")
@click.pass_context
def cancel_market(ctx, market_id):
    """Cancel all orders for a specific market."""
    from horizon.tools import cancel_market_orders
    from horizon.cli._fmt import output

    output(cancel_market_orders(market_id), json_mode=ctx.obj.get("json", False))


@click.command("stop-loss")
@click.option("--market-id", required=True, help="Market identifier")
@click.option("--side", required=True, type=click.Choice(["yes", "no"]), help="Position side")
@click.option("--trigger", required=True, type=float, help="Trigger price")
@click.option("--size", required=True, type=float, help="Order size")
@click.pass_context
def stop_loss(ctx, market_id, side, trigger, size):
    """Add a stop-loss contingent order."""
    from horizon.tools import add_stop_loss
    from horizon.cli._fmt import output

    output(add_stop_loss(market_id=market_id, side=side, trigger_price=trigger, size=size), json_mode=ctx.obj.get("json", False))


@click.command("take-profit")
@click.option("--market-id", required=True, help="Market identifier")
@click.option("--side", required=True, type=click.Choice(["yes", "no"]), help="Position side")
@click.option("--trigger", required=True, type=float, help="Trigger price")
@click.option("--size", required=True, type=float, help="Order size")
@click.pass_context
def take_profit(ctx, market_id, side, trigger, size):
    """Add a take-profit contingent order."""
    from horizon.tools import add_take_profit
    from horizon.cli._fmt import output

    output(add_take_profit(market_id=market_id, side=side, trigger_price=trigger, size=size), json_mode=ctx.obj.get("json", False))


@click.command("contingent-orders")
@click.pass_context
def contingent_orders(ctx):
    """List pending stop-loss and take-profit orders."""
    from horizon.tools import list_contingent_orders
    from horizon.cli._fmt import output

    output(list_contingent_orders(), json_mode=ctx.obj.get("json", False))


@click.command()
@click.option("--market-id", required=True, help="Market identifier")
@click.option("--buy-exchange", required=True, help="Exchange to buy on")
@click.option("--sell-exchange", required=True, help="Exchange to sell on")
@click.option("--buy-price", required=True, type=float, help="Buy price")
@click.option("--sell-price", required=True, type=float, help="Sell price")
@click.option("--size", required=True, type=float, help="Trade size")
@click.pass_context
def arb(ctx, market_id, buy_exchange, sell_exchange, buy_price, sell_price, size):
    """Execute a cross-exchange arbitrage trade."""
    from horizon.tools import execute_arb
    from horizon.cli._fmt import output

    output(execute_arb(market_id=market_id, buy_exchange=buy_exchange, sell_exchange=sell_exchange, buy_price=buy_price, sell_price=sell_price, size=size), json_mode=ctx.obj.get("json", False))


@click.command("copy-trades")
@click.argument("address")
@click.option("--markets", required=True, multiple=True, help="Market IDs to copy on")
@click.option("--scale", default=1.0, type=float, help="Size multiplier")
@click.pass_context
def copy_trades(ctx, address, markets, scale):
    """Start copy-trading a wallet."""
    from horizon.tools import start_copy_trades
    from horizon.cli._fmt import output

    output(start_copy_trades(address=address, market_ids=list(markets), scale=scale), json_mode=ctx.obj.get("json", False))


@click.command("stealth-estimate")
@click.option("--market-id", required=True, help="Market identifier")
@click.option("--size", required=True, type=float, help="Order size")
@click.pass_context
def stealth_estimate(ctx, market_id, size):
    """Estimate market impact for a stealth order."""
    from horizon.tools import stealth_estimate_impact
    from horizon.cli._fmt import output

    output(stealth_estimate_impact(market_id=market_id, size=size), json_mode=ctx.obj.get("json", False))


@click.command("stealth-execute")
@click.option("--market-id", required=True, help="Market identifier")
@click.option("--side", required=True, type=click.Choice(["buy", "sell"]), help="Order side")
@click.option("--size", required=True, type=float, help="Total size")
@click.option("--slices", default=5, type=int, help="Number of slices")
@click.pass_context
def stealth_execute(ctx, market_id, side, size, slices):
    """Execute a large order stealthily in slices."""
    from horizon.tools import stealth_execute_order
    from horizon.cli._fmt import output

    output(stealth_execute_order(market_id=market_id, side=side, size=size, n_slices=slices), json_mode=ctx.obj.get("json", False))


@click.command("portfolio-metrics")
@click.pass_context
def portfolio_metrics(ctx):
    """Show portfolio-level metrics (Sharpe, Sortino, drawdown)."""
    from horizon.tools import get_portfolio_metrics
    from horizon.cli._fmt import output

    output(get_portfolio_metrics(), json_mode=ctx.obj.get("json", False))


@click.command("portfolio-weights")
@click.option("--method", default="equal", help="Weighting method (equal, kelly, risk_parity)")
@click.pass_context
def portfolio_weights(ctx, method):
    """Compute portfolio weights."""
    from horizon.tools import get_portfolio_weights
    from horizon.cli._fmt import output

    output(get_portfolio_weights(method=method), json_mode=ctx.obj.get("json", False))


@click.command("runtime-params")
@click.pass_context
def runtime_params(ctx):
    """Show current runtime parameters."""
    from horizon.tools import get_runtime_params
    from horizon.cli._fmt import output

    output(get_runtime_params(), json_mode=ctx.obj.get("json", False))


@click.command("set-params")
@click.argument("params", nargs=-1, required=True)
@click.pass_context
def set_params(ctx, params):
    """Update runtime parameters (KEY=VALUE pairs).

    Example: horizon set-params spread=0.05 size=10
    """
    from horizon.tools import update_runtime_params
    from horizon.cli._fmt import output

    parsed = {}
    for p in params:
        k, v = p.split("=", 1)
        try:
            parsed[k] = float(v)
        except ValueError:
            click.echo(f"Error: '{v}' is not a valid number for param '{k}'", err=True)
            return
    output(update_runtime_params(parsed), json_mode=ctx.obj.get("json", False))
