"""
Acoustic Model Module - Mackenzie equation for sound velocity
"""

import numpy as np


class AcousticModel:
    """
    Mackenzie equation for sound velocity in seawater
    
    c(T,S,D) = 1448.96 + 4.591T - 5.304e-2 T² + 2.374e-4 T³
               + 1.340(S - 35) + 1.630e-2 D + 1.675e-7 D²
    
    Validated to 11,000m depth
    """
    
    def __init__(self,
                 temperature: float = 2.0,
                 salinity: float = 34.7,
                 depth: float = 0):
        """
        Initialize acoustic model
        """
        self.temperature = temperature
        self.salinity = salinity
        self.depth = depth
    
    def sound_speed(self) -> float:
        """
        Calculate sound speed using Mackenzie equation
        """
        T = self.temperature
        S = self.salinity
        D = self.depth
        
        c = (1448.96 + 
             4.591 * T - 
             5.304e-2 * T**2 + 
             2.374e-4 * T**3 +
             1.340 * (S - 35) + 
             1.630e-2 * D + 
             1.675e-7 * D**2)
        
        return c
    
    def travel_time(self, distance: float) -> float:
        """Calculate acoustic travel time"""
        c = self.sound_speed()
        return distance / c
    
    def range_from_time(self, time: float) -> float:
        """Calculate range from travel time"""
        c = self.sound_speed()
        return c * time
    
    def refraction_index(self) -> float:
        """Calculate refraction index relative to surface"""
        # Surface sound speed (depth = 0)
        surface_speed = (1448.96 + 
                        4.591 * self.temperature - 
                        5.304e-2 * self.temperature**2 + 
                        2.374e-4 * self.temperature**3 +
                        1.340 * (self.salinity - 35))
        
        return self.sound_speed() / surface_speed
    
    def acoustic_impedance(self, density: float) -> float:
        """Calculate acoustic impedance Z = ρ * c"""
        return density * self.sound_speed()
    
    def reflection_coefficient(self, density1: float, density2: float) -> float:
        """
        Calculate reflection coefficient at interface
        Simplified for normal incidence
        """
        c1 = self.sound_speed()
        # Assume slightly different sound speed in second medium
        c2 = c1 * 1.01
        
        Z1 = density1 * c1
        Z2 = density2 * c2
        
        return (Z2 - Z1) / (Z2 + Z1)
    
    def sofar_channel_depth(self) -> float:
        """Estimate SOFAR channel depth"""
        # SOFAR channel typically around 1000-1200m
        return 1000.0
    
    def validate_challenger_deep(self) -> dict:
        """
        Validate against Challenger Deep conditions
        
        Expected: c = 1663.8 m/s at 10,911m, 1.9°C, 34.68 PSU
        """
        # Save current state
        orig_temp = self.temperature
        orig_sal = self.salinity
        orig_depth = self.depth
        
        # Set Challenger Deep conditions
        self.temperature = 1.9
        self.salinity = 34.68
        self.depth = 10911
        
        c = self.sound_speed()
        expected = 1663.8
        error_percent = abs(c - expected) / expected * 100
        
        # Restore original state
        self.temperature = orig_temp
        self.salinity = orig_sal
        self.depth = orig_depth
        
        return {
            'sound_speed': c,
            'expected': expected,
            'error_percent': error_percent,
            'valid': error_percent < 1.0
        }
    
    def __repr__(self) -> str:
        return (f"AcousticModel(T={self.temperature}°C, "
                f"S={self.salinity}PSU, depth={self.depth:.0f}m)")
