package dev.adriankuta.visualizer.domain.processors

import androidx.compose.ui.graphics.Color
import dev.adriankuta.visualizer.HSL
import dev.adriankuta.visualizer.MovingAverage
import dev.adriankuta.visualizer.calculateRms
import dev.adriankuta.visualizer.data.FftFrame
import dev.adriankuta.visualizer.data.VisualizerFrame
import dev.adriankuta.visualizer.data.WaveformFrame
import timber.log.Timber
import kotlin.reflect.KClass

/**
 * Default implementation of SoundToColorMapper that uses HSL color space
 * and moving average for smooth color transitions.
 *
 * Follows Single Responsibility Principle by focusing on sound-to-color mapping.
 * Follows Dependency Inversion Principle by depending on abstractions.
 */
class HSLSoundToColorMapper(
    private val baseHue: Float = 0f, // Blue hue as default
    private val saturation: Float = 1f,
    private val movingAverageWindowSize: Int = 2
) : VisualizerProcessor {

    private val movingAverage = MovingAverage(movingAverageWindowSize)
    private var rmsMax = 0.0

    override suspend fun invoke(frame: VisualizerFrame): Color {
        val waveform = frame.data
        // Calculate RMS value for current frame
        val currentRms = calculateRms(waveform)

        rmsMax -= 0.01
        // Update maximum RMS value for normalization
        if (currentRms > rmsMax) {
            rmsMax = currentRms
        }

        Timber.d("Max RMS: %s, current %s", rmsMax, currentRms)

        // Calculate energy ratio (0-1)
        val energyRatio = if (rmsMax > 0) currentRms / rmsMax else 0.0

        // Apply moving average for smooth transitions
        val adjustedLightness = movingAverage.process(energyRatio)

        // Create HSL color and convert to Compose Color
        val hslColor = HSL(
            hue = baseHue,
            saturation = saturation,
            lightness = adjustedLightness.toFloat().coerceIn(0f, 1f)
        )

        return hslColor.toComposeColor()
    }
}
