"""Typer CLI for FOMO Guard."""

import asyncio
import sys
from typing import Optional

import typer
from rich.console import Console

from .config import get_config, reload_config
from .core.analyzer import FOMOAnalyzer, AnalysisError
from .utils.cooldown import CooldownTracker
from .utils.display import DisplayFormatter

app = typer.Typer(
    name="fomo-guard",
    help="CLI tool to help crypto newcomers avoid FOMO-driven decisions",
    add_completion=False,
)
config_app = typer.Typer(help="Configuration management")
app.add_typer(config_app, name="config")

console = Console()
display = DisplayFormatter()


def run_async(coro):
    """Run an async coroutine safely across Python versions."""
    if sys.version_info >= (3, 10):
        return asyncio.run(coro)
    else:
        loop = asyncio.get_event_loop()
        return loop.run_until_complete(coro)


@app.command()
def check(
    symbol: str = typer.Argument(..., help="Cryptocurrency symbol (e.g., BTC, ETH)"),
    detailed: bool = typer.Option(
        False, "--detailed", "-d", help="Show detailed indicator breakdown"
    ),
):
    """Check FOMO score for a cryptocurrency."""

    async def _check():
        with display.create_progress() as progress:
            task = progress.add_task(f"Analyzing {symbol.upper()}...", total=None)

            async with FOMOAnalyzer() as analyzer:
                fomo_score = await analyzer.analyze(symbol)

            progress.remove_task(task)

        display.display_score(fomo_score, detailed=detailed)

    try:
        run_async(_check())
    except AnalysisError as e:
        display.display_error(f"Analysis failed: {e}")
        raise typer.Exit(1)
    except KeyboardInterrupt:
        console.print("\n[dim]Cancelled[/dim]")
        raise typer.Exit(0)
    except Exception as e:
        display.display_error(f"Unexpected error: {e}")
        raise typer.Exit(1)


@app.command()
def cool(
    symbol: Optional[str] = typer.Argument(
        None, help="Cryptocurrency symbol to set cooldown for"
    ),
    status: bool = typer.Option(
        False, "--status", "-s", help="Show active cooldowns"
    ),
    hours: int = typer.Option(
        None, "--hours", "-h", help="Custom cooldown duration in hours"
    ),
):
    """Manage cooling periods for purchase intentions."""
    tracker = CooldownTracker()
    config = get_config()

    if status or symbol is None:
        # Show cooldown status
        cooldowns = tracker.get_active_cooldowns()
        display.display_cooldown_status(cooldowns)
        return

    # Set a new cooldown
    duration = hours or config.settings.default_cooldown_hours
    tracker.add_cooldown(symbol.upper(), duration)
    display.display_success(
        f"Cooldown set for {symbol.upper()} - wait {duration} hours before buying"
    )
    console.print(
        f"\n[dim]Run 'fomo-guard cool --status' to check your cooldowns[/dim]"
    )


@app.command()
def history(
    symbol: str = typer.Argument(..., help="Cryptocurrency symbol"),
    days: int = typer.Option(90, "--days", "-d", help="Historical lookback in days"),
):
    """View historical FOMO events for a cryptocurrency."""
    from .core.history import HistoryTracker

    async def _history():
        tracker = HistoryTracker()
        events = await tracker.get_fomo_events(symbol, days)

        if not events:
            console.print(f"[dim]No significant FOMO events found for {symbol.upper()} in the last {days} days[/dim]")
            return

        tracker.display_events(symbol, events)

    try:
        run_async(_history())
    except Exception as e:
        display.display_error(str(e))
        raise typer.Exit(1)


@app.command()
def serve(
    host: str = typer.Option("0.0.0.0", "--host", help="API host"),
    port: int = typer.Option(8000, "--port", "-p", help="API port"),
    reload: bool = typer.Option(False, "--reload", help="Enable auto-reload"),
):
    """Start the FOMO Guard API server."""
    import uvicorn

    console.print(f"[bold]Starting FOMO Guard API server...[/bold]")
    console.print(f"  Host: {host}")
    console.print(f"  Port: {port}")
    console.print(f"  Docs: http://{host}:{port}/docs\n")

    uvicorn.run(
        "fomo_guard.api:app",
        host=host,
        port=port,
        reload=reload,
    )


# Config subcommands
@config_app.command("set")
def config_set(
    key: str = typer.Argument(..., help="Config key (e.g., coingecko, twitter)"),
    value: str = typer.Argument(..., help="Config value"),
):
    """Set a configuration value (API key or setting)."""
    config = get_config()

    # Check if it's an API key or setting
    api_key_names = [
        "coingecko",
        "coinmarketcap",
        "twitter",
        "reddit_client_id",
        "reddit_client_secret",
        "lunarcrush",
        "glassnode",
        "etherscan",
    ]

    setting_names = [
        "default_cooldown_hours",
        "cache_ttl_minutes",
        "api_host",
        "api_port",
    ]

    try:
        if key in api_key_names:
            config.set_api_key(key, value)
            display.display_success(f"API key '{key}' has been set")
        elif key in setting_names:
            config.set_setting(key, value)
            display.display_success(f"Setting '{key}' has been set to '{value}'")
        else:
            display.display_error(
                f"Unknown config key: {key}\n"
                f"Valid API keys: {', '.join(api_key_names)}\n"
                f"Valid settings: {', '.join(setting_names)}"
            )
            raise typer.Exit(1)
    except Exception as e:
        display.display_error(str(e))
        raise typer.Exit(1)


@config_app.command("list")
def config_list():
    """List all configured API keys."""
    config = get_config()
    display.display_config_list(config.list_api_keys())


@config_app.command("path")
def config_path():
    """Show configuration file path."""
    from .config import Config

    console.print(f"Config file: {Config.get_config_path()}")
    console.print(f"Data directory: {Config.get_data_dir()}")


@app.callback()
def main():
    """
    FOMO Guard - Don't buy the top!

    A CLI tool to help crypto newcomers avoid FOMO-driven decisions
    by analyzing price, social, and on-chain signals.
    """
    pass


if __name__ == "__main__":
    app()
