import asyncio
import json
import sys
from pathlib import Path
import typer

from krrkt.engine.pipeline import proofread
from krrkt.engine.scorer import score_color

app = typer.Typer(name="krrkt", help="Russian text quality checker")


def _get_text(text_or_path: str) -> str:
    """If text_or_path is a file path, read the file. Otherwise return as-is."""
    path = Path(text_or_path)
    if path.exists() and path.is_file():
        return path.read_text(encoding="utf-8")
    return text_or_path


def _format_human(result) -> str:
    """Format result for human-readable terminal output."""
    lines = []

    # Score bar
    filled = int(result.score)
    empty = 10 - filled
    bar = "\u2588" * filled + "\u2591" * empty
    color_map = {"green": typer.colors.GREEN, "orange": typer.colors.YELLOW, "red": typer.colors.RED}

    lines.append(f"  {result.score} / 10  {bar}")
    lines.append(f"  {result.words} words, {result.sentences} sentences")
    lines.append("")

    if result.stopwords > 0:
        lines.append(f"  {result.stopwords} stop-words:")

        # Group by severity
        serious = [f for f in result.findings if f.weight >= 80]
        medium = [f for f in result.findings if 0 < f.weight < 80]
        info = [f for f in result.findings if f.weight == 0]

        for f in serious:
            line = f"  \u25a0 \u00ab{f.word}\u00bb {f.rule}"
            if f.description:
                line += f" \u2014 {f.description}"
            lines.append(line)
        for f in medium:
            line = f"  \u25b2 \u00ab{f.word}\u00bb {f.rule}"
            if f.description:
                line += f" \u2014 {f.description}"
            lines.append(line)
        for f in info:
            lines.append(f"  \u25cb \u00ab{f.word}\u00bb {f.rule}")
    else:
        lines.append("  No issues found!")

    return "\n".join(lines)


@app.command()
def check(
    text: str = typer.Argument(help="Text to check or path to file"),
    no_llm: bool = typer.Option(False, "--no-llm", help="Skip LLM analysis (fast layer only)"),
    format: str = typer.Option("human", "--format", "-f", help="Output format: human or json"),
    model: str = typer.Option(None, "--model", "-m", help="LLM model to use"),
):
    """Check text for style issues."""
    content = _get_text(text)
    result = asyncio.run(proofread(content, skip_llm=no_llm, model=model))

    if format == "json":
        import dataclasses
        data = dataclasses.asdict(result)
        del data["text"]  # Don't echo back the full text
        typer.echo(json.dumps(data, ensure_ascii=False, indent=2))
    else:
        typer.echo(_format_human(result))


@app.command()
def score(
    text: str = typer.Argument(help="Text to score"),
    no_llm: bool = typer.Option(False, "--no-llm", help="Skip LLM analysis"),
):
    """Get score only."""
    content = _get_text(text)
    result = asyncio.run(proofread(content, skip_llm=no_llm))
    typer.echo(f"{result.score}/10")


@app.command()
def serve(
    host: str = typer.Option("127.0.0.1", "--host", help="Host to bind"),
    port: int = typer.Option(8080, "--port", "-p", help="Port to bind"),
):
    """Start API server."""
    import uvicorn
    uvicorn.run("krrkt.api.app:app", host=host, port=port, reload=False)


if __name__ == "__main__":
    app()
