"""Command-line interface for WideBible.

Requires the ``cli`` extra: ``pip install widebible[cli]``

Usage::

    widebible verse john.3.16
    widebible search "love"
    widebible book genesis
    widebible person moses
    widebible place jerusalem
"""

from __future__ import annotations

import json
import sys

import typer
from rich.console import Console

from widebible.client import WideBible

app = typer.Typer(
    name="widebible",
    help="WideBible CLI — Bible verses, people, places, and study tools.",
    no_args_is_help=True,
)
console = Console()


def _print_json(data: dict) -> None:  # type: ignore[type-arg]
    """Pretty-print JSON response."""
    console.print_json(json.dumps(data, ensure_ascii=False, indent=2))


def _parse_verse_ref(ref: str) -> tuple[str, int, int]:
    """Parse a verse reference like 'john.3.16' into (book, chapter, verse)."""
    parts = ref.split(".")
    if len(parts) != 3:
        console.print(
            f"[red]Invalid verse reference: {ref}[/red]\n"
            "Expected format: book.chapter.verse (e.g. john.3.16)",
            err=True,
        )
        raise typer.Exit(1)
    book = parts[0]
    try:
        chapter = int(parts[1])
        verse_num = int(parts[2])
    except ValueError:
        console.print(f"[red]Chapter and verse must be numbers: {ref}[/red]", err=True)
        raise typer.Exit(1)
    return book, chapter, verse_num


@app.command()
def verse(
    ref: str = typer.Argument(help="Verse reference (e.g. john.3.16)"),
    translation: str = typer.Option("kjv", "--translation", "-t", help="Translation code"),
) -> None:
    """Get a Bible verse by reference."""
    book, chapter, verse_num = _parse_verse_ref(ref)
    with WideBible() as client:
        try:
            result = client.get_verse(book, chapter, verse_num, translation)
        except Exception as e:
            console.print(f"[red]Error: {e}[/red]", err=True)
            raise typer.Exit(1)
    # Display verse results
    results = result.get("results", [result])
    if isinstance(results, list) and results:
        for v in results:
            ref_str = v.get("reference", f"{book} {chapter}:{verse_num}")
            text = v.get("text", "")
            console.print(f"[bold]{ref_str}[/bold] ({translation.upper()})")
            console.print(text)
    else:
        _print_json(result)


@app.command()
def search(
    query: str = typer.Argument(help="Search query"),
    limit: int = typer.Option(10, "--limit", "-n", help="Max results"),
) -> None:
    """Search Bible verses by keyword."""
    with WideBible() as client:
        result = client.search(query, limit=limit)
    results = result.get("results", [])
    if results:
        for v in results:
            ref_str = v.get("reference", "")
            text = v.get("text", "")
            console.print(f"[bold]{ref_str}[/bold]")
            console.print(f"  {text[:120]}{'...' if len(text) > 120 else ''}")
            console.print()
    else:
        console.print("[yellow]No results found.[/yellow]")


@app.command()
def book(
    slug: str = typer.Argument(help="Book slug (e.g. genesis, john)"),
) -> None:
    """Get book information."""
    with WideBible() as client:
        try:
            result = client.get_book(slug)
        except Exception as e:
            console.print(f"[red]Error: {e}[/red]", err=True)
            raise typer.Exit(1)
    name = result.get("name", slug)
    testament = result.get("testament", "")
    chapters = result.get("chapter_count", 0)
    verses = result.get("verse_count", 0)
    description = result.get("description", "")
    console.print(f"[bold]{name}[/bold] ({testament})")
    console.print(f"Chapters: {chapters} | Verses: {verses}")
    if description:
        console.print(f"\n{description}")


@app.command()
def person(
    slug: str = typer.Argument(help="Person slug (e.g. moses, david)"),
) -> None:
    """Get information about a biblical person."""
    with WideBible() as client:
        try:
            result = client.get_person(slug)
        except Exception as e:
            console.print(f"[red]Error: {e}[/red]", err=True)
            raise typer.Exit(1)
    name = result.get("name", slug)
    bio = result.get("bio", "")
    testament = result.get("testament", "")
    verse_count = result.get("verse_count", 0)
    console.print(f"[bold]{name}[/bold] ({testament})")
    console.print(f"Mentioned in {verse_count} verses")
    if bio:
        console.print(f"\n{bio}")


@app.command()
def place(
    slug: str = typer.Argument(help="Place slug (e.g. jerusalem, bethlehem)"),
) -> None:
    """Get information about a biblical place."""
    with WideBible() as client:
        try:
            result = client.get_place(slug)
        except Exception as e:
            console.print(f"[red]Error: {e}[/red]", err=True)
            raise typer.Exit(1)
    name = result.get("name", slug)
    description = result.get("description", "")
    lat = result.get("latitude")
    lon = result.get("longitude")
    verse_count = result.get("verse_count", 0)
    console.print(f"[bold]{name}[/bold]")
    if lat and lon:
        console.print(f"Coordinates: {lat}, {lon}")
    console.print(f"Mentioned in {verse_count} verses")
    if description:
        console.print(f"\n{description}")


if __name__ == "__main__":
    app()
