"""Surface charge analysis tool for the Amina CLI."""

import typer
from pathlib import Path
from typing import Optional
from rich.console import Console

METADATA = {
    "name": "surface-charge",
    "display_name": "Surface Charge Analysis",
    "category": "analysis",
    "description": "Analyze protein surface electrostatics using APBS calculations",
    "modal_function_name": "surface_charge_worker",
    "modal_app_name": "surface-charge-api",
    "status": "available",
    "outputs": {
        "csv_filepath": "Surface charge analysis results CSV",
        "plot_filepath": "Surface charge visualization plot",
        "pdb_filepath": "Processed PDB structure",
    },
}

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("surface-charge")
    def run_surface_charge(
        pdb: Path = typer.Option(
            ...,
            "--pdb",
            "-p",
            help="Path to PDB file for analysis",
            exists=True,
        ),
        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 output files (default: random 4-letter code)",
        ),
        # Output preferences
        savecsv: bool = typer.Option(
            True,
            "--savecsv/--no-csv",
            help="Save results to CSV file",
        ),
        saveplot: bool = typer.Option(
            True,
            "--plot/--no-plot",
            help="Save visualization plots",
        ),
        # APBS parameters
        forcefield: str = typer.Option(
            "AMBER",
            "--forcefield",
            "-f",
            help="Force field for charge assignment (AMBER or CHARMM)",
        ),
        ionic_strength: float = typer.Option(
            0.15,
            "--ionic-strength",
            "-i",
            help="Ionic strength of solution in mol/L (0.0-5.0)",
        ),
        ph: float = typer.Option(
            7.4,
            "--ph",
            help="pH value for charge assignment (0.0-14.0)",
        ),
        # Multipole analysis
        multipole: bool = typer.Option(
            True,
            "--multipole/--no-multipole",
            help="Perform multipole moment analysis",
        ),
        multipole_l_max: int = typer.Option(
            2,
            "--multipole-l-max",
            help="Maximum order of multipole expansion",
        ),
        # Surface analysis parameters
        sasa_threshold: float = typer.Option(
            0.1,
            "--sasa-threshold",
            help="SASA threshold for surface atoms in nm^2",
        ),
        patch_distance: float = typer.Option(
            8.0,
            "--patch-distance",
            help="Distance threshold for patch clustering in Angstrom",
        ),
        patch_size: int = typer.Option(
            3,
            "--patch-size",
            help="Minimum number of atoms for patch identification",
        ),
    ):
        """
        Analyze protein surface electrostatics using APBS calculations.

        Performs comprehensive surface charge analysis including:
        - Electrostatic potential calculations using APBS
        - Multipole moment analysis
        - Charge patch identification
        - Surface charge autocorrelation analysis

        Examples:
            amina run surface-charge --pdb ./protein.pdb -o ./results/
            amina run surface-charge --pdb ./protein.pdb -j myjob -o ./results/
            amina run surface-charge --pdb ./protein.pdb --ph 6.5 --ionic-strength 0.1 -o ./results/
            amina run surface-charge --pdb ./protein.pdb --forcefield CHARMM -o ./results/
        """
        # Validate required options
        if output is None:
            console.print("[red]Error:[/red] --output / -o is required")
            raise typer.Exit(1)

        # Validate forcefield
        if forcefield.upper() not in ["AMBER", "CHARMM"]:
            console.print(f"[red]Error:[/red] Invalid forcefield '{forcefield}'. Must be AMBER or CHARMM")
            raise typer.Exit(1)

        # Validate pH range
        if ph < 0.0 or ph > 14.0:
            console.print(f"[red]Error:[/red] pH must be between 0.0 and 14.0, got {ph}")
            raise typer.Exit(1)

        # Validate ionic strength
        if ionic_strength < 0.0 or ionic_strength > 5.0:
            console.print(f"[red]Error:[/red] Ionic strength must be between 0.0 and 5.0, got {ionic_strength}")
            raise typer.Exit(1)

        # Read PDB file content
        pdb_content = pdb.read_text()
        console.print(f"Read PDB from {pdb}")

        # Build params matching worker's expected fields
        params = {
            "pdb_content": pdb_content,
            "pdb_filename": pdb.stem,  # Use filename for naming outputs
            # Output preferences
            "savecsv": savecsv,
            "saveplot": saveplot,
            # APBS parameters
            "apbs_forcefield": forcefield.upper(),
            "apbs_ionic_strength": ionic_strength,
            "apbs_ph": ph,
            # Multipole analysis
            "do_multipole_analysis": multipole,
            "multipole_l_max": multipole_l_max,
            # Surface analysis parameters
            "surface_sasa_threshold": sasa_threshold,
            "surface_patch_distance": patch_distance,
            "surface_patch_size_threshold": patch_size,
        }

        if job_name:
            params["job_name"] = job_name

        # Execute
        run_tool_with_progress("surface-charge", params, output)
