"""
signals command — display this week's market intelligence signals.

Entry point: `skilark signals` or `skilark signals --all`

Fetches market signals from the API and renders them as a numbered list.
By default shows up to 5 signals; --all requests the full set for the week.

The rendering logic is extracted into `run_signals()` so tests can call it
directly with a mock client without touching ConfigStore or performing
network I/O.
"""

import sys

from rich.console import Console

from skilark_cli.client import SkilarkClient
from skilark_cli.config_store import ConfigStore

console = Console()

_DEFAULT_LIMIT = 5


def dispatch(signals_args: list[str]) -> None:
    """Entry point called from main.py for `skilark signals`.

    Handles config loading, client setup, and flag parsing, then delegates
    to ``run_signals()``.  Exits early with a friendly message if the user
    has not yet completed onboarding.

    Args:
        signals_args: Remaining argv after the ``signals`` token.
                      Recognises the ``--all`` flag.
    """
    config_store = ConfigStore()

    if config_store.is_first_run():
        console.print("[dim]Run 'skilark today' first to get started.[/dim]")
        return

    show_all = "--all" in signals_args

    config = config_store.load()
    client = SkilarkClient(base_url=config["api_url"], user_id=config.get("user_id"))

    limit = 0 if show_all else _DEFAULT_LIMIT
    run_signals(client, limit=limit, show_all=show_all)


def run_signals(
    client: SkilarkClient,
    limit: int,
    show_all: bool,
) -> None:
    """Fetch and render market signals.

    Separated from ``dispatch()`` so tests can inject a mock client and
    verify output without touching the filesystem or network.

    Args:
        client:   SkilarkClient instance (or mock in tests).
        limit:    Number of signals to request from the API, or None for all.
        show_all: When False, a hint telling the user about ``--all`` is
                  appended after the signal list.
    """
    data = client.get_signals(limit=limit)

    signals = data.get("signals", [])
    week_of = data.get("week_of", "")

    if not signals:
        console.print("[dim]No signals available this week.[/dim]")
        return

    # Format "2026-02-23" → "Feb 23"
    week_label = _format_week(week_of)
    console.print(f"\n[bold]Market Signals[/bold] — Week of {week_label}\n")

    for i, signal in enumerate(signals, start=1):
        title = signal.get("title", "")
        body = signal.get("body", "")
        console.print(f"[bold]{i}. {title}[/bold]")
        if body:
            console.print(f"   [dim]{body}[/dim]")
        console.print()

    if not show_all:
        console.print(
            "[dim]Type 'skilark signals --all' to see all signals this week.[/dim]\n"
        )


def _format_week(week_of: str) -> str:
    """Convert an ISO date string to a short human-readable label.

    Args:
        week_of: Date string in ``YYYY-MM-DD`` format.

    Returns a label like ``"Feb 23"``, or the original string if parsing fails.
    """
    try:
        from datetime import date

        d = date.fromisoformat(week_of)
        return f"{d.strftime('%b')} {d.day}"
    except (ValueError, TypeError):
        return week_of
