"""DockQ complex quality assessment tool for the Amina CLI."""

import typer
import json
from pathlib import Path
from typing import Optional, List
from rich.console import Console

METADATA = {
    "name": "dockq",
    "display_name": "DockQ",
    "category": "interactions",
    "description": "Assess quality of predicted protein complex structures against reference structures",
    "modal_function_name": "dockq_worker",
    "modal_app_name": "dockq-api",
    "status": "available",
    "outputs": {},  # DockQ returns metrics, not files
    "output_display": {
        "sections": [
            {
                "title": "Interface Metrics",
                "table": {
                    "data_key": "interfaces",
                    "columns": [
                        {"key": "chain_pair", "header": "Chain Pair"},
                        {"key": "DockQ", "header": "DockQ", "justify": "right", "format": "{:.3f}"},
                        {"key": "iRMSD", "header": "iRMSD (\u00c5)", "justify": "right", "format": "{:.3f}"},
                        {"key": "LRMSD", "header": "LRMSD (\u00c5)", "justify": "right", "format": "{:.3f}"},
                        {"key": "fnat", "header": "fnat", "justify": "right", "format": "{:.3f}"},
                        {"key": "quality_class", "header": "Quality"},
                    ],
                },
            },
            {
                "title": "Global Summary",
                "fields": [
                    {"key": "global_summary.total_interfaces", "label": "Total interfaces"},
                    {"key": "global_summary.avg_DockQ", "label": "Average DockQ", "format": "{:.3f}"},
                    {"key": "global_summary.avg_fnat", "label": "Average fnat", "format": "{:.3f}"},
                    {"key": "global_summary.avg_iRMSD", "label": "Average iRMSD", "format": "{:.3f} \u00c5"},
                    {"key": "global_summary.best_interface", "label": "Best interface"},
                    {"key": "global_summary.worst_interface", "label": "Worst interface"},
                ],
            },
        ],
    },
}

console = Console()


def register(app: typer.Typer):
    """Register this tool's command with the app."""
    from amina_cli.commands.tools import run_tool_with_progress

    @app.command("dockq")
    def run_dockq(
        model: Path = typer.Option(
            ...,
            "--model",
            "-m",
            help="Path to model/predicted complex structure (PDB file)",
            exists=True,
        ),
        reference: Path = typer.Option(
            ...,
            "--reference",
            "-r",
            help="Path to native/reference complex structure (PDB file)",
            exists=True,
        ),
        interface_pairs: Optional[str] = typer.Option(
            None,
            "--interfaces",
            "-i",
            help="Specific chain pairs to evaluate (e.g., 'A:B,A:C' for interfaces A-B and A-C)",
        ),
        chain_mapping: Optional[str] = typer.Option(
            None,
            "--chain-mapping",
            "-c",
            help="Chain mapping from native to model (e.g., 'A:A,B:X' maps native A to model A, native B to model X)",
        ),
        output: Path = typer.Option(
            ...,
            "--output",
            "-o",
            help="Output directory for results",
        ),
        job_name: Optional[str] = typer.Option(
            None,
            "--job-name",
            "-j",
            help="Custom job name for tracking (default: random 4-letter code)",
        ),
    ):
        """
        Assess quality of predicted protein complex structures using DockQ.

        DockQ evaluates how well a predicted protein complex structure matches
        a native/reference structure. It provides per-interface metrics including:

        - DockQ score (0-1, higher is better)
        - iRMSD (interface RMSD)
        - LRMSD (ligand RMSD)
        - fnat (fraction of native contacts)
        - Quality classification (Incorrect/Acceptable/Medium/High)

        Examples:
            amina run dockq -m predicted.pdb -r native.pdb -o ./results/
            amina run dockq -m model.pdb -r reference.pdb --interfaces A:B,A:C -o ./results/
            amina run dockq -m model.pdb -r native.pdb --chain-mapping A:A,B:X -o ./results/
        """
        # Validate required options
        if output is None:
            console.print("[red]Error:[/red] --output / -o is required")
            raise typer.Exit(1)

        # Read file contents
        model_content = model.read_text()
        reference_content = reference.read_text()
        console.print(f"Read model structure from {model}")
        console.print(f"Read reference structure from {reference}")

        # Build params
        params = {
            "model_pdb_content": model_content,
            "model_pdb_filename": model.stem,
            "reference_pdb_content": reference_content,
            "reference_pdb_filename": reference.stem,
        }

        # Parse interface pairs: "A:B,A:C" -> [["A","B"], ["A","C"]]
        if interface_pairs:
            parsed_pairs = []
            for pair in interface_pairs.split(","):
                pair = pair.strip()
                if ":" not in pair:
                    console.print(
                        f"[red]Error:[/red] Invalid interface pair format '{pair}'. Use 'CHAIN1:CHAIN2' (e.g., 'A:B')"
                    )
                    raise typer.Exit(1)
                chains = pair.split(":")
                if len(chains) != 2:
                    console.print(
                        f"[red]Error:[/red] Invalid interface pair '{pair}'. Expected 'CHAIN1:CHAIN2' format."
                    )
                    raise typer.Exit(1)
                parsed_pairs.append([chains[0].strip().upper(), chains[1].strip().upper()])
            params["interface_pairs"] = parsed_pairs
            console.print(f"Evaluating interfaces: {parsed_pairs}")

        # Parse chain mapping: "A:A,B:X" -> {"A": "A", "B": "X"}
        if chain_mapping:
            mapping = {}
            for pair in chain_mapping.split(","):
                pair = pair.strip()
                if ":" not in pair:
                    console.print(
                        f"[red]Error:[/red] Invalid chain mapping '{pair}'. Use 'NATIVE:MODEL' (e.g., 'A:A' or 'B:X')"
                    )
                    raise typer.Exit(1)
                chains = pair.split(":")
                if len(chains) != 2:
                    console.print(f"[red]Error:[/red] Invalid chain mapping '{pair}'. Expected 'NATIVE:MODEL' format.")
                    raise typer.Exit(1)
                mapping[chains[0].strip().upper()] = chains[1].strip().upper()
            params["chain_mapping"] = mapping
            console.print(f"Using chain mapping: {mapping}")

        if job_name:
            params["job_name"] = job_name

        run_tool_with_progress("dockq", params, output)
