"""Channel Extract audio filter — select mono/left/right from stereo AudioAnalysis."""

from dataclasses import replace
from typing import Any, Dict, List

import numpy as np

from wled_controller.core.audio.analysis import AudioAnalysis
from wled_controller.core.audio.filters.base import AudioFilter, AudioFilterOptionDef
from wled_controller.core.audio.filters.registry import AudioFilterRegistry


@AudioFilterRegistry.register
class ChannelExtractFilter(AudioFilter):
    """Select a single channel (mono mix, left, or right) from stereo AudioAnalysis.

    When 'mono' is selected, left and right are averaged into the main fields.
    When 'left' or 'right' is selected, that channel's data replaces the main fields.
    """

    filter_id = "channel_extract"
    filter_name = "Channel Extract"

    def __init__(self, options: Dict[str, Any]):
        super().__init__(options)
        self._channel = self.options["channel"]

    @classmethod
    def get_options_schema(cls) -> List[AudioFilterOptionDef]:
        return [
            AudioFilterOptionDef(
                key="channel",
                label="Channel",
                option_type="select",
                default="mono",
                min_value=None,
                max_value=None,
                step=None,
                choices=[
                    {"value": "mono", "label": "Mono (L+R average)"},
                    {"value": "left", "label": "Left"},
                    {"value": "right", "label": "Right"},
                ],
            ),
        ]

    def process(self, analysis: AudioAnalysis) -> AudioAnalysis:
        channel = self._channel

        if channel == "left":
            return replace(
                analysis,
                rms=analysis.left_rms,
                spectrum=np.copy(analysis.left_spectrum),
            )
        elif channel == "right":
            return replace(
                analysis,
                rms=analysis.right_rms,
                spectrum=np.copy(analysis.right_spectrum),
            )
        else:
            # mono: average left and right
            avg_rms = (analysis.left_rms + analysis.right_rms) / 2.0
            avg_spectrum = (analysis.left_spectrum + analysis.right_spectrum) / 2.0
            return replace(
                analysis,
                rms=avg_rms,
                spectrum=avg_spectrum.astype(np.float32),
            )
