import numpy as np
import pandas as pd
import math

def generate_radar_csv(filename="pulse_compression_output.csv"):
    """
    Generate realistic radar CSV data for testing the Python GUI
    """
    
    # Radar parameters matching your testbench
    num_long_chirps = 16
    num_short_chirps = 16
    samples_per_chirp = 512  # Reduced for manageable file size
    fs_adc = 400e6  # 400 MHz ADC
    timestamp_ns = 0
    
    # Target parameters
    targets = [
        {
            'range': 3000, 'velocity': 25, 'snr': 30, 'azimuth': 10, 'elevation': 5
        },  # Fast moving target
        {
            'range': 5000, 'velocity': -15, 'snr': 25, 'azimuth': 20, 'elevation': 2
        },  # Approaching target
        {
            'range': 8000, 'velocity': 5, 'snr': 20, 'azimuth': 30, 'elevation': 8
        },  # Slow moving target
        {
            'range': 12000, 'velocity': -8, 'snr': 18, 'azimuth': 45, 'elevation': 3
        },  # Distant target
    ]
    
    # Noise parameters
    noise_std = 5
    clutter_std = 10
    
    data = []
    chirp_number = 0
    
    # Generate Long Chirps (30µs duration equivalent)
    for chirp in range(num_long_chirps):
        for sample in range(samples_per_chirp):
            # Base noise
            i_val = np.random.normal(0, noise_std)
            q_val = np.random.normal(0, noise_std)
            
            # Add clutter (stationary targets)
            _clutter_range = 2000  # Fixed clutter at 2km
            if sample < 100:  # Simulate clutter in first 100 samples
                i_val += np.random.normal(0, clutter_std)
                q_val += np.random.normal(0, clutter_std)
            
            # Add moving targets with Doppler shift
            for target in targets:
                # Calculate range bin (simplified)
                range_bin = int(target['range'] / 20)  # ~20m per bin
                doppler_phase = (
                    2 * math.pi * target['velocity'] * chirp / 100
                )  # Doppler phase shift
                
                # Target appears around its range bin with some spread
                if abs(sample - range_bin) < 10:
                    # Signal amplitude decreases with range
                    amplitude = target['snr'] * (10000 / target['range'])
                    phase = 2 * math.pi * sample / 50 + doppler_phase
                    
                    i_val += amplitude * math.cos(phase)
                    q_val += amplitude * math.sin(phase)
            
            # Calculate derived values
            magnitude_squared = i_val**2 + q_val**2
            
            data.append({
                'timestamp_ns': timestamp_ns,
                'chirp_number': chirp_number,
                'chirp_type': 'LONG',
                'sample_index': sample,
                'I_value': int(i_val),
                'Q_value': int(q_val),
                'magnitude_squared': int(magnitude_squared)
            })
            
            timestamp_ns += int(1e9 / fs_adc)  # 2.5ns per sample at 400MHz
        
        chirp_number += 1
        timestamp_ns += 137000  # Add listening period (137µs)
    
    # Guard time between long and short chirps
    timestamp_ns += 175400  # 175.4µs guard time
    
    # Generate Short Chirps (0.5µs duration equivalent)
    for chirp in range(num_short_chirps):
        for sample in range(samples_per_chirp):
            # Base noise
            i_val = np.random.normal(0, noise_std)
            q_val = np.random.normal(0, noise_std)
            
            # Add clutter (different characteristics for short chirps)
            if sample < 50:  # Less clutter for short chirps
                i_val += np.random.normal(0, clutter_std/2)
                q_val += np.random.normal(0, clutter_std/2)
            
            # Add moving targets with different Doppler for short chirps
            for target in targets:
                # Range bin calculation (different for short chirps)
                range_bin = int(target['range'] / 40)  # Different range resolution
                doppler_phase = (
                    2 * math.pi * target['velocity'] * (chirp + 5) / 80
                )  # Different Doppler
                
                # Target appears around its range bin
                if abs(sample - range_bin) < 8:
                    # Different amplitude characteristics for short chirps
                    amplitude = target['snr'] * 0.7 * (8000 / target['range'])  # 70% amplitude
                    phase = 2 * math.pi * sample / 30 + doppler_phase
                    
                    i_val += amplitude * math.cos(phase)
                    q_val += amplitude * math.sin(phase)
            
            # Calculate derived values
            magnitude_squared = i_val**2 + q_val**2
            
            data.append({
                'timestamp_ns': timestamp_ns,
                'chirp_number': chirp_number,
                'chirp_type': 'SHORT',
                'sample_index': sample,
                'I_value': int(i_val),
                'Q_value': int(q_val),
                'magnitude_squared': int(magnitude_squared)
            })
            
            timestamp_ns += int(1e9 / fs_adc)  # 2.5ns per sample
        
        chirp_number += 1
        timestamp_ns += 174500  # Add listening period (174.5µs)
    
    # Create DataFrame
    df = pd.DataFrame(data)
    
    # Save to CSV
    df.to_csv(filename, index=False)
    
    return df

def analyze_generated_data(df):
    """
    Analyze the generated data to verify target detection
    """
    
    # Basic statistics
    df[df['chirp_type'] == 'LONG']
    df[df['chirp_type'] == 'SHORT']
    
    
    # Calculate actual magnitude and phase for analysis
    df['magnitude'] = np.sqrt(df['I_value']**2 + df['Q_value']**2)
    df['phase_rad'] = np.arctan2(df['Q_value'], df['I_value'])
    
    # Find high-magnitude samples (potential targets)
    high_mag_threshold = df['magnitude'].quantile(0.95)  # Top 5%
    targets_detected = df[df['magnitude'] > high_mag_threshold]
    
    
    # Group by chirp type
    targets_detected[targets_detected['chirp_type'] == 'LONG']
    targets_detected[targets_detected['chirp_type'] == 'SHORT']
    
    
    return df

if __name__ == "__main__":
    # Generate the CSV file
    df = generate_radar_csv("test_radar_data.csv")
    
    # Analyze the generated data
    analyze_generated_data(df)
    
