"""Market operations: long, short, close positions."""

from typing import Annotated, Any

import typer

from ..config import OutputFormat
from ..context import AppContext
from ..utils import complete_coin_symbol
from .base import console, parse_leverage, parse_order_response, parse_percentage, trading_command, with_progress

app = typer.Typer(help="Market operations", rich_markup_mode="rich")


@app.command("long")
@trading_command
def long_position(
    ctx: typer.Context,
    coin: Annotated[
        str,
        typer.Argument(help="Coin symbol (e.g., [bold green]BTC[/bold green])", autocompletion=complete_coin_symbol),
    ],
    leverage: Annotated[str, typer.Argument(help="Leverage (e.g., [cyan]5x[/cyan], [cyan]10[/cyan])")],
    margin: Annotated[float, typer.Argument(help="Margin in USD (e.g., [yellow]1000[/yellow])", min=10)],
    slippage: Annotated[
        float,
        typer.Option("--slippage", "-s", help="[yellow]Max slippage %[/yellow] (default: 1%)", min=0.01, max=10.0),
    ] = 1.0,
) -> None:
    """Open a long position with specified leverage and margin."""
    app_ctx: AppContext = ctx.obj

    coin = coin.upper()
    leverage_int = parse_leverage(leverage)

    if ctx.meta.get("verbose"):
        console.print("\n[bold]Long Position Details:[/bold]")
        console.print(f"  Coin: [cyan]{coin}[/cyan]")
        console.print(f"  Leverage: [yellow]{leverage_int}x[/yellow]")
        console.print(f"  Margin: [yellow]${margin:,.2f}[/yellow]")
        console.print(f"  Slippage: [yellow]{slippage}%[/yellow]")
        console.print()

    @with_progress(f"Opening long position for {coin}...")
    def execute() -> Any:
        return app_ctx.client.open_position(
            coin=coin,
            is_long=True,
            leverage=leverage_int,
            margin_usd=margin,
            slippage=slippage,
        )

    result = execute()

    if app_ctx.formatter.format == OutputFormat.JSON:
        app_ctx.formatter.print(result)
    else:
        success, message = parse_order_response(result)
        if success:
            console.print(f"[green]✓[/green] Long position opened: {message}")
        else:
            console.print(f"[red]✗[/red] Failed to open long position: {message}")
            raise typer.Exit(code=1) from None


@app.command("short")
@trading_command
def short_position(
    ctx: typer.Context,
    coin: Annotated[
        str,
        typer.Argument(help="Coin symbol (e.g., [bold green]BTC[/bold green])", autocompletion=complete_coin_symbol),
    ],
    leverage: Annotated[str, typer.Argument(help="Leverage (e.g., [cyan]5x[/cyan], [cyan]10[/cyan])")],
    margin: Annotated[float, typer.Argument(help="Margin in USD (e.g., [yellow]1000[/yellow])", min=10)],
    slippage: Annotated[
        float,
        typer.Option("--slippage", "-s", help="[yellow]Max slippage %[/yellow] (default: 1%)", min=0.01, max=10.0),
    ] = 1.0,
) -> None:
    """Open a short position with specified leverage and margin."""
    app_ctx: AppContext = ctx.obj

    coin = coin.upper()
    leverage_int = parse_leverage(leverage)

    if ctx.meta.get("verbose"):
        console.print("\n[bold]Short Position Details:[/bold]")
        console.print(f"  Coin: [cyan]{coin}[/cyan]")
        console.print(f"  Leverage: [yellow]{leverage_int}x[/yellow]")
        console.print(f"  Margin: [yellow]${margin:,.2f}[/yellow]")
        console.print(f"  Slippage: [yellow]{slippage}%[/yellow]")
        console.print()

    @with_progress(f"Opening short position for {coin}...")
    def execute() -> Any:
        return app_ctx.client.open_position(
            coin=coin,
            is_long=False,
            leverage=leverage_int,
            margin_usd=margin,
            slippage=slippage,
        )

    result = execute()

    if app_ctx.formatter.format == OutputFormat.JSON:
        app_ctx.formatter.print(result)
    else:
        success, message = parse_order_response(result)
        if success:
            console.print(f"[green]✓[/green] Short position opened: {message}")
        else:
            console.print(f"[red]✗[/red] Failed to open short position: {message}")
            raise typer.Exit(code=1) from None


@app.command("close")
@trading_command
def close_position(
    ctx: typer.Context,
    target: Annotated[str, typer.Argument(help="Coin symbol or [yellow]'all'[/yellow] for all positions")],
    percentage: Annotated[str, typer.Argument(help="Percentage to close (e.g., [cyan]100%[/cyan], [cyan]50[/cyan])")],
    slippage: Annotated[
        float,
        typer.Option("--slippage", "-s", help="[yellow]Max slippage %[/yellow] (default: 1%)", min=0.01, max=10.0),
    ] = 1.0,
) -> None:
    """Close a position or percentage of all positions."""
    app_ctx: AppContext = ctx.obj

    percentage_float = parse_percentage(percentage)
    target_address = app_ctx.config.account_address or ""

    if target.lower() == "all":
        if ctx.meta.get("verbose"):
            console.print(f"[yellow]Warning:[/yellow] This will close {percentage_float}% of ALL open positions")

        @with_progress(f"Closing {percentage_float}% of all positions...")
        def execute() -> Any:
            return app_ctx.client.close_all_positions(percentage_float, target_address, slippage)

        results = execute()

        if app_ctx.formatter.format == OutputFormat.JSON:
            app_ctx.formatter.print(results)
        else:
            if not results:
                console.print("[yellow]No open positions found[/yellow]")
            else:
                success_count = 0
                for result in results:
                    coin = result.get("coin", "Unknown")
                    if "error" in result:
                        console.print(f"[red]✗[/red] {coin}: {result['error']}")
                    else:
                        success, message = parse_order_response(result["result"])
                        if success:
                            console.print(f"[green]✓[/green] {coin}: {message}")
                            success_count += 1
                        else:
                            console.print(f"[red]✗[/red] {coin}: {message}")

                console.print(f"\n[cyan]Successfully closed {success_count}/{len(results)} positions[/cyan]")
    else:
        coin = target.upper()

        if ctx.meta.get("verbose"):
            console.print("\n[bold]Close Position Details:[/bold]")
            console.print(f"  Coin: [cyan]{coin}[/cyan]")
            console.print(f"  Percentage: [yellow]{percentage_float}%[/yellow]")
            console.print(f"  Slippage: [yellow]{slippage}%[/yellow]")
            console.print()

        @with_progress(f"Closing {percentage_float}% of {coin} position...")
        def execute() -> Any:
            return app_ctx.client.close_position(coin, percentage_float, target_address, slippage)

        result = execute()

        if app_ctx.formatter.format == OutputFormat.JSON:
            app_ctx.formatter.print(result)
        else:
            success, message = parse_order_response(result)
            if success:
                console.print(f"[green]✓[/green] Position closed: {message}")
            else:
                console.print(f"[red]✗[/red] Failed to close position: {message}")
                raise typer.Exit(code=1) from None
