"""send command — extract a message and deliver it."""

import typer

from cli_framework import get_context
from message_delivery import DeliveryOptions, DeliveryPipeline, GitError
from send_message.cli import app
from send_message.commands._helpers import resolve_tool_and_session, show_available_sessions
from send_message.context import SendMessageContext
from session_store import MessageSelector
from session_store.errors import MessageNotFoundError, SessionNotFoundError


@app.command()
def send(
    ctx: typer.Context,
    target: str = typer.Argument(
        ...,
        help="Message target: latest, HEAD, HEAD~N, <number>, first, search:<text>",
    ),
    subject: str = typer.Option(None, "--subject", "-s", help="Email subject"),
    name: str = typer.Option(None, "--name", "-n", help="Override note filename"),
    no_push: bool = typer.Option(False, "--no-push", help="Skip git push"),
    no_email: bool = typer.Option(False, "--no-email", help="Skip email"),
    no_commit: bool = typer.Option(False, "--no-commit", help="Skip git commit"),
    dry_run: bool = typer.Option(False, "--dry-run", help="Skip all side-effects"),
    to: str = typer.Option(None, "--to", help="Override recipient email"),
) -> None:
    """Extract a message and deliver it as a note + email."""
    app_ctx = get_context(ctx)
    assert isinstance(app_ctx, SendMessageContext)
    console = app_ctx.console

    tool, session_id, store = resolve_tool_and_session(ctx)

    try:
        session = store.get_session(session_id, tool=tool)
    except SessionNotFoundError:
        console.print(f"[red]Error:[/red] Session not found: {session_id}")
        show_available_sessions(console, store, tool=tool)
        raise typer.Exit(1) from None

    try:
        message = store.select_message(target, session_id=session_id, tool=tool)
    except MessageNotFoundError:
        console.print(f"[red]Error:[/red] Message not found for target: {target}")
        selector = MessageSelector()
        candidates = selector.filter_assistant(session.messages)
        if candidates:
            console.print(f"[dim]Available assistant messages ({len(candidates)}):[/dim]")
            for i, msg in enumerate(candidates[:10], 1):
                preview = msg.content[:60].replace("\n", " ")
                console.print(f"  {i}. {preview}")
        else:
            console.print("[dim]No assistant messages in this session.[/dim]")
        raise typer.Exit(1) from None

    options = DeliveryOptions(
        subject=subject,
        filename=name,
        no_push=no_push,
        no_email=no_email,
        no_commit=no_commit,
        dry_run=dry_run,
        to_email=to,
    )

    pipeline = DeliveryPipeline()
    try:
        result = pipeline.deliver(message, session.title, options)
    except GitError as exc:
        console.print(f"[red]Error:[/red] {exc}")
        raise typer.Exit(1) from None

    console.print(f"[green]Saved:[/green] {result.note_path}")
    if dry_run:
        console.print("[yellow]Dry run:[/yellow] skipped commit, email, push")
    else:
        if result.committed:
            console.print("[green]Committed:[/green] yes")
        else:
            console.print("[dim]Committed:[/dim] no (nothing to commit)")
        if result.emailed:
            console.print("[green]Emailed:[/green] yes")
        elif not no_email:
            console.print("[dim]Emailed:[/dim] no")
        if result.pushed:
            console.print("[green]Pushed:[/green] yes")
        elif not no_push:
            console.print("[dim]Pushed:[/dim] no")
