"""Test performance comparison: deepcopy vs PredictedTarget for prediction."""

import sys
import time
import copy
import math
from dataclasses import dataclass, field
from typing import List, Tuple


# Mock minimal Target class for testing
@dataclass
class Target:
    target_id: int
    active: bool = True
    traceable: bool = True
    restart: bool = False
    current_velocity_fps: float = field(default=0.0)
    current_vertical_velocity_fps: float = field(default=0.0)
    current_heading_deg: float = field(default=0.0)
    current_pitch_deg: float = field(default=0.0)
    current_range_nm: float = field(default=0.0)
    current_azimuth_deg: float = field(default=0.0)
    current_altitude_ft: float = field(default=0.0)
    _pos_x_ft: float = field(default=0.0)
    _pos_y_ft: float = field(default=0.0)
    _pos_z_ft: float = field(default=0.0)
    trajectory: List = field(default_factory=list)
    _path: List[Tuple] = field(default_factory=list)

    def update_state(self, dt: float):
        """Simple kinematic update."""
        heading_rad = math.radians(self.current_heading_deg)
        vx = self.current_velocity_fps * math.sin(heading_rad)
        vy = self.current_velocity_fps * math.cos(heading_rad)
        self._pos_x_ft += vx * dt
        self._pos_y_ft += vy * dt
        self._pos_z_ft += self.current_vertical_velocity_fps * dt


class PredictedTarget:
    """Lightweight wrapper for predicted target state."""

    __slots__ = (
        "target_id",
        "active",
        "traceable",
        "restart",
        "_pos_x_ft",
        "_pos_y_ft",
        "_pos_z_ft",
        "current_velocity_fps",
        "current_vertical_velocity_fps",
        "current_heading_deg",
        "current_pitch_deg",
        "current_range_nm",
        "current_azimuth_deg",
        "current_altitude_ft",
    )

    def __init__(self, target: Target, horizon_s: float):
        self.target_id = target.target_id
        self.active = target.active
        self.traceable = target.traceable
        self.restart = target.restart

        self.current_velocity_fps = target.current_velocity_fps
        self.current_vertical_velocity_fps = target.current_vertical_velocity_fps
        self.current_heading_deg = target.current_heading_deg
        self.current_pitch_deg = target.current_pitch_deg

        heading_rad = math.radians(target.current_heading_deg)
        vx = target.current_velocity_fps * math.sin(heading_rad)
        vy = target.current_velocity_fps * math.cos(heading_rad)
        vz = target.current_vertical_velocity_fps

        self._pos_x_ft = target._pos_x_ft + vx * horizon_s
        self._pos_y_ft = target._pos_y_ft + vy * horizon_s
        self._pos_z_ft = target._pos_z_ft + vz * horizon_s

        dist_2d = math.sqrt(self._pos_x_ft**2 + self._pos_y_ft**2)
        self.current_range_nm = dist_2d / 6076.12
        self.current_azimuth_deg = (
            math.degrees(math.atan2(self._pos_x_ft, self._pos_y_ft)) % 360
        )
        self.current_altitude_ft = self._pos_z_ft


def benchmark_deepcopy(targets: List[Target], horizon_s: float, iterations: int):
    """OLD approach: deepcopy + update_state."""
    start = time.perf_counter()

    for _ in range(iterations):
        predicted = []
        for target in targets:
            pred = copy.deepcopy(target)
            pred.update_state(horizon_s)
            predicted.append(pred)

    elapsed = time.perf_counter() - start
    return elapsed


def benchmark_lightweight(targets: List[Target], horizon_s: float, iterations: int):
    """NEW approach: PredictedTarget lightweight wrapper."""
    start = time.perf_counter()

    for _ in range(iterations):
        predicted = [PredictedTarget(t, horizon_s) for t in targets]

    elapsed = time.perf_counter() - start
    return elapsed


def main():
    print("=" * 70)
    print("Prediction Performance Comparison: deepcopy vs PredictedTarget")
    print("=" * 70)

    # Create test targets
    num_targets = 32
    targets = []
    for i in range(num_targets):
        t = Target(
            target_id=i,
            current_velocity_fps=300.0,
            current_heading_deg=45.0,
            current_vertical_velocity_fps=10.0,
            _pos_x_ft=10000.0 + i * 1000,
            _pos_y_ft=20000.0 + i * 500,
            _pos_z_ft=5000.0 + i * 100,
        )
        # Add some complex data to make deepcopy slower
        t.trajectory = [f"waypoint_{j}" for j in range(10)]
        t._path = [
            (i, j, k, l)
            for i, j, k, l in zip(range(100), range(100), range(100), range(100))
        ]
        targets.append(t)

    horizon_s = 0.2  # 200ms prediction horizon
    iterations = 1000  # Simulate 1000 prediction cycles

    print(f"\nTest configuration:")
    print(f"  Targets: {num_targets}")
    print(f"  Prediction horizon: {horizon_s}s")
    print(f"  Iterations: {iterations}")
    print(f"  Total predictions: {num_targets * iterations}")

    # Warm-up
    benchmark_deepcopy(targets[:2], horizon_s, 10)
    benchmark_lightweight(targets[:2], horizon_s, 10)

    # Benchmark OLD approach
    print(f"\n{'OLD (deepcopy + update_state)':<40}", end="")
    old_time = benchmark_deepcopy(targets, horizon_s, iterations)
    print(f"{old_time*1000:>8.2f} ms")

    # Benchmark NEW approach
    print(f"{'NEW (PredictedTarget lightweight)':<40}", end="")
    new_time = benchmark_lightweight(targets, horizon_s, iterations)
    print(f"{new_time*1000:>8.2f} ms")

    # Results
    speedup = old_time / new_time
    reduction_pct = ((old_time - new_time) / old_time) * 100

    print(f"\n{'='*70}")
    print(f"Speedup: {speedup:.1f}x faster")
    print(f"Time reduction: {reduction_pct:.1f}%")
    print(f"Time saved per cycle: {(old_time - new_time) / iterations * 1000:.3f} ms")
    print(f"\nAt 20Hz simulation rate:")
    print(f"  OLD overhead: {old_time / iterations * 1000:.2f} ms/frame")
    print(f"  NEW overhead: {new_time / iterations * 1000:.2f} ms/frame")
    print(
        f"  Saved per second: {(old_time - new_time) / iterations * 20 * 1000:.2f} ms"
    )
    print(f"{'='*70}")


if __name__ == "__main__":
    main()
