import numpy as np
from scipy.signal import butter, sosfilt
from .base import BaseProcessorModule

try:
    from ..pipeline.saturation import oversampled
except ImportError:
    from automaster_app.pipeline.saturation import oversampled


class HarmonicsModule(BaseProcessorModule):
    """Harmonic Enhancement - Fixed for DC Offset and Phase Safety."""
    
    def process(self, audio: np.ndarray, warmth: float = 0.0, edge: float = 0.0, blend: float = 1.0) -> np.ndarray:
        if warmth <= 0 and edge <= 0: return audio
        
        sr = self.sample_rate
        original = audio.copy()
        
        # 1. Generate Harmonics only
        # We process a copy to avoid contaminating the original before blend
        h_gen = audio.copy()
        generated = np.zeros_like(h_gen)
        
        # Warmth: Even harmonics (x^2)
        if warmth > 0:
            # We use absolute to generate harmonics but we must filter DC later
            generated += oversampled(lambda u: u ** 2, h_gen) * (warmth * 0.05)
            
        # Edge: Odd harmonics (x^3)
        if edge > 0:
            generated += oversampled(lambda u: u ** 3, h_gen) * (edge * 0.02)
            
        # 2. CRITICAL: DC Blocker / High-Pass
        # This removes the 'offset' created by squaring the signal
        # prevents the 'cracking' and 'choking' of the limiter
        sos = butter(4, 30, 'hp', fs=sr, output='sos')
        if generated.ndim == 1:
            generated = sosfilt(sos, generated)
        else:
            generated[:, 0] = sosfilt(sos, generated[:, 0])
            generated[:, 1] = sosfilt(sos, generated[:, 1])
            
        # 3. Parallel Blend
        out = (generated * blend) + original
        
        return np.clip(out, -1.0, 1.0)
