"""Command-line interface for res_sum."""

from __future__ import annotations

import argparse
import logging
import sys
import warnings

warnings.filterwarnings("ignore", category=UserWarning, module="pydantic")
warnings.filterwarnings("ignore", category=DeprecationWarning, module="importlib")

from res_sum import __version__
from res_sum.models.providers import list_providers, list_models
from res_sum.domains.config import list_domains


def main() -> None:
    parser = argparse.ArgumentParser(
        prog="res-sum",
        description="res_sum — A Python package leveraging LLMs for research evidence synthesis",
    )
    parser.add_argument("--version", "-V", action="version", version=f"res-sum {__version__}")
    subparsers = parser.add_subparsers(dest="command", help="Command to run")

    # ---- summarize command ----
    sp_sum = subparsers.add_parser(
        "summarize",
        help="Batch-summarize PDF papers in a directory",
    )
    sp_sum.add_argument(
        "--pdf_directory", required=True,
        help="Directory containing PDF files",
    )
    sp_sum.add_argument(
        "--output_directory", required=True,
        help="Directory for output summaries",
    )
    sp_sum.add_argument(
        "--prompt", default=None,
        help="Custom prompt for summarization (overrides domain CoT)",
    )
    sp_sum.add_argument(
        "--provider", default="ollama",
        choices=list_providers(),
        help="LLM provider (default: ollama). Use 'ollama_cloud' for hosted Ollama API.",
    )
    sp_sum.add_argument(
        "--model", default=None,
        help="Model name (default: provider's default)",
    )
    sp_sum.add_argument(
        "--api_key", default=None,
        help="API key (falls back to environment variables)",
    )
    sp_sum.add_argument(
        "--domain", default="ecology",
        help="Domain config: 'ecology', 'general', or path to YAML file",
    )
    sp_sum.add_argument(
        "--output_format", default="docx",
        choices=["docx", "json", "csv"],
        help="Output format (default: docx)",
    )
    sp_sum.add_argument(
        "--section", default="methodology",
        choices=["introduction", "methodology"],
        help="Section to start extraction from (default: methodology)",
    )
    sp_sum.add_argument(
        "--chunk_size", type=int, default=4000,
        help="Chunk size in characters (default: 4000)",
    )
    sp_sum.add_argument(
        "--chunk_overlap", type=int, default=200,
        help="Chunk overlap in characters (default: 200)",
    )
    sp_sum.add_argument(
        "--n_chunks", type=int, default=10,
        help="Number of chunks to retrieve per paper (default: 10)",
    )
    sp_sum.add_argument(
        "--data_dir", default="./knowledge_base",
        help="Directory for persistent data (ChromaDB, etc.)",
    )
    sp_sum.add_argument(
        "--no_cot", action="store_true",
        help="Disable Chain-of-Thought prompting",
    )
    sp_sum.add_argument(
        "--use_grobid", action="store_true",
        help="Use GROBID server for PDF parsing (falls back to PyMuPDF if unavailable)",
    )
    sp_sum.add_argument(
        "--grobid_url", default="http://localhost:8070",
        help="GROBID server URL (default: http://localhost:8070)",
    )
    sp_sum.add_argument(
        "--mode", default="hybrid",
        choices=["local", "graph", "global", "hybrid"],
        help="Retrieval mode (default: hybrid). 'local'=vector only, 'graph'=graph+vector, 'global'=community, 'hybrid'=all combined.",
    )
    sp_sum.add_argument(
        "--no_graph", action="store_true",
        help="Disable knowledge graph construction (faster, but no GraphRAG)",
    )
    sp_sum.add_argument(
        "--rebuild", action="store_true",
        help="Wipe existing knowledge base and rebuild from scratch",
    )
    sp_sum.add_argument(
        "--verbose", "-v", action="store_true",
        help="Enable verbose logging",
    )

    # ---- explore command ----
    sp_explore = subparsers.add_parser(
        "explore",
        help="Open interactive dashboard to explore the knowledge base",
    )
    sp_explore.add_argument(
        "--data_dir", default="./knowledge_base",
        help="Directory containing the knowledge base data",
    )
    sp_explore.add_argument(
        "--output", default="./explore_dashboard.html",
        help="Output path for the HTML dashboard",
    )
    sp_explore.add_argument(
        "--no_open", action="store_true",
        help="Don't auto-open the browser",
    )

    # ---- info command ----
    sp_info = subparsers.add_parser(
        "info",
        help="Show available providers, models, and domains",
    )

    args = parser.parse_args()

    if args.command is None:
        parser.print_help()
        sys.exit(0)

    if args.command == "info":
        _run_info()
    elif args.command == "explore":
        _run_explore(args)
    elif args.command == "summarize":
        _run_summarize(args)


def _run_explore(args: argparse.Namespace) -> None:
    """Launch the interactive explore dashboard."""
    from pathlib import Path
    from res_sum.retrieval.vector_store import VectorStore
    from res_sum.graph.knowledge_graph import KnowledgeGraph
    from res_sum.graph.community import load_communities
    from res_sum.explore.dashboard import generate_dashboard

    data_dir = Path(args.data_dir)
    if not data_dir.exists():
        print(f"Error: data directory not found: {data_dir}")
        print("Run 'res-sum summarize' first to ingest papers and build the knowledge base.")
        sys.exit(1)

    # Load existing data
    vs = VectorStore(data_dir=data_dir)
    kg = KnowledgeGraph()
    graph_path = data_dir / "knowledge_graph.graphml"
    if graph_path.exists():
        kg.load(graph_path)

    communities, summaries = {}, {}
    comm_path = data_dir / "communities.json"
    if comm_path.exists():
        communities, summaries = load_communities(comm_path)

    print(f"Loaded: {vs.count()} chunks, {kg.num_nodes()} entities, {kg.num_edges()} relationships")

    path = generate_dashboard(
        knowledge_graph=kg,
        vector_store=vs,
        communities=communities,
        community_summaries=summaries,
        output_path=args.output,
        open_browser=not args.no_open,
    )
    print(f"Dashboard saved to: {path}")


def _run_info() -> None:
    """Print available providers, models, and domains."""
    print("=== res_sum v2.0 ===\n")

    print("Available LLM providers:")
    for provider in list_providers():
        models = list_models(provider)
        print(f"  {provider}: {', '.join(models[:3])}{'...' if len(models) > 3 else ''}")

    print(f"\nAvailable domains: {', '.join(list_domains())}")
    print("\nCustom domains: provide a path to a YAML file (--domain ./my_domain.yaml)")


def _run_summarize(args: argparse.Namespace) -> None:
    """Run batch summarization."""
    # Set up logging
    level = logging.DEBUG if args.verbose else logging.INFO
    logging.basicConfig(
        level=level,
        format="%(asctime)s [%(levelname)s] %(message)s",
        datefmt="%H:%M:%S",
    )

    from res_sum.core import ResSum

    rs = ResSum(
        llm_provider=args.provider,
        model=args.model,
        api_key=args.api_key,
        domain=args.domain,
        data_dir=args.data_dir,
        chunk_size=args.chunk_size,
        chunk_overlap=args.chunk_overlap,
        start_section=args.section,
        prompt=args.prompt,
        use_grobid=args.use_grobid,
        grobid_url=args.grobid_url,
        build_graph=not args.no_graph,
    )

    # Rebuild knowledge base if requested
    if args.rebuild:
        rs._rebuild_knowledge_base()

    results = rs.summarize_papers(
        pdf_directory=args.pdf_directory,
        output_directory=args.output_directory,
        prompt=args.prompt,
        mode=args.mode,
        use_cot=not args.no_cot,
        output_format=args.output_format,
        n_chunks=args.n_chunks,
    )

    # Print summary
    success = sum(1 for r in results if r["status"] == "success")
    skipped = sum(1 for r in results if r["status"] == "skipped")
    errors = sum(1 for r in results if r["status"].startswith("error"))
    print(f"\nDone: {success} summarized, {skipped} skipped, {errors} errors")


if __name__ == "__main__":
    main()
