from __future__ import annotations

from mcp.server.fastmcp import FastMCP

from .service import AssettoCoachService


service = AssettoCoachService()
mcp = FastMCP("Assetto Corsa Coach")


@mcp.tool()
def health() -> dict:
    """Report environment discovery, AC telemetry liveness, and optional MOZA presence."""
    return service.health()


@mcp.tool()
def snapshot() -> dict:
    """Read one live telemetry snapshot from Assetto Corsa shared memory."""
    return service.snapshot()


@mcp.tool()
def library() -> dict:
    """Summarize installed cars, track layouts, and setup-seed availability from the local AC install."""
    return service.library_summary()


@mcp.tool()
def verify_moza_plugin() -> dict:
    """Check whether the official MOZA Assetto Corsa Python app is installed and enabled."""
    return service.verify_moza_plugin()


@mcp.tool()
def install_moza_plugin(enable: bool = True) -> dict:
    """Install the official MOZA Assetto Corsa Python app from the local Pit House install and enable it in python.ini."""
    return service.install_moza_plugin(enable=enable)


@mcp.tool()
def install_ac_app(enable: bool = True) -> dict:
    """Install a minimal in-sim AC Python app that shows coach state and latest feedback from disk."""
    return service.install_ac_app(enable=enable)


@mcp.tool()
def install_bridge_app(enable: bool = True) -> dict:
    """Install a minimal in-sim AC Python telemetry bridge app that publishes custom shared memory."""
    return service.install_bridge_app(enable=enable)


@mcp.tool()
def capture_run(duration_s: float = 120.0, sample_hz: float = 50.0, label: str = "") -> dict:
    """Record a fixed-duration telemetry capture from the running sim."""
    return service.capture_run(duration_s=duration_s, sample_hz=sample_hz, label=label or None)


@mcp.tool()
def capture_laps(
    lap_count: int = 3,
    sample_hz: float = 50.0,
    max_duration_s: float = 1800.0,
    label: str = "",
) -> dict:
    """Record telemetry until the requested number of complete laps is captured."""
    return service.capture_laps(
        lap_count=lap_count,
        sample_hz=sample_hz,
        max_duration_s=max_duration_s,
        label=label or None,
    )


@mcp.tool()
def list_sessions(limit: int = 10) -> list[dict]:
    """List the most recent captured telemetry sessions."""
    return service.list_sessions(limit=limit)


@mcp.tool()
def analyze_session(session_id: str = "") -> dict:
    """Analyze the latest captured session, or a specific session id."""
    return service.analyze_session(session_id=session_id or None)


@mcp.tool()
def compare_laps(
    session_id: str = "",
    slower_lap_number: int | None = None,
    reference_lap_number: int | None = None,
) -> dict:
    """Compare one slower lap against a reference lap inside a captured session."""
    return service.compare_laps(
        session_id=session_id or None,
        slower_lap_number=slower_lap_number,
        reference_lap_number=reference_lap_number,
    )


@mcp.tool()
def recommend_training(materialize_setups: bool = True) -> dict:
    """Recommend a locally grounded training curriculum and optionally materialize setup files for the recommended combos."""
    return service.recommend_training(materialize_setups=materialize_setups)


@mcp.tool()
def write_training_setup(
    car_model: str,
    profile_id: str,
    track: str = "",
    track_layout: str = "",
    setup_name: str = "",
) -> dict:
    """Create a training setup from an existing local setup seed for a specific car and optional track layout."""
    return service.materialize_training_setup(
        car_model=car_model,
        track=track or None,
        track_layout=track_layout or None,
        profile_id=profile_id,
        setup_name=setup_name or None,
    )


@mcp.tool()
def prepare_training_launch(
    stage: str = "smooth_inputs",
    apply_setup_as_last: bool = True,
    launch_surface: str = "content_manager",
    dry_run: bool = True,
) -> dict:
    """Prepare an offline training launch for one curriculum stage and optionally start the chosen launch surface."""
    return service.prepare_training_launch(
        stage=stage,
        apply_setup_as_last=apply_setup_as_last,
        launch_surface=launch_surface,
        dry_run=dry_run,
    )


@mcp.tool()
def prepare_direct_training_launch(
    car_model: str,
    track: str,
    profile_id: str,
    track_layout: str = "",
    live_mode: str = "consistency",
    title: str = "Custom Training Run",
    apply_setup_as_last: bool = True,
    launch_surface: str = "content_manager",
    dry_run: bool = True,
) -> dict:
    """Prepare a direct car/track/profile training launch and optionally start the chosen launch surface."""
    return service.prepare_direct_training_launch(
        car_model=car_model,
        track=track,
        track_layout=track_layout or None,
        profile_id=profile_id,
        live_mode=live_mode,
        title=title,
        apply_setup_as_last=apply_setup_as_last,
        launch_surface=launch_surface,
        dry_run=dry_run,
    )


@mcp.tool()
def start_live_coach(
    mode: str = "consistency",
    reference_session_id: str = "",
    car_model: str = "",
    track: str = "",
    track_layout: str = "",
    tts_enabled: bool = True,
    muted: bool = False,
    max_callouts_per_lap: int = 3,
    sample_hz: float = 20.0,
    zone_count: int = 4,
    setup_profile: str = "",
    plan_label: str = "",
) -> dict:
    """Start the live coaching runtime in the background for the current or specified combo."""
    return service.start_live_coach(
        mode=mode,
        reference_session_id=reference_session_id or None,
        car_model=car_model or None,
        track=track or None,
        track_layout=track_layout or None,
        tts_enabled=tts_enabled,
        muted=muted,
        max_callouts_per_lap=max_callouts_per_lap,
        sample_hz=sample_hz,
        zone_count=zone_count,
        setup_profile=setup_profile or None,
        plan_label=plan_label or None,
    )


@mcp.tool()
def live_coach_status() -> dict:
    """Read status for the detached live coaching runtime."""
    return service.live_coach_status()


@mcp.tool()
def stop_live_coach() -> dict:
    """Stop the detached live coaching runtime."""
    return service.stop_live_coach()


def main() -> None:
    mcp.run()


if __name__ == "__main__":  # pragma: no cover
    main()
