"""Definitions for speech recognition service actions, events and state."""

from __future__ import annotations

from dataclasses import field
from enum import StrEnum
from typing import TYPE_CHECKING

from immutable import Immutable
from redux import BaseAction, BaseEvent

if TYPE_CHECKING:
    from collections.abc import Sequence

    from ubo_app.store.main import UboAction

from ubo_app.utils.persistent_store import read_from_persistent_store


class SpeechRecognitionAction(BaseAction):
    """Base class for speech recognition actions."""


class SpeechRecognitionSetSelectedEngineAction(SpeechRecognitionAction):
    """Action to set the selected speech recognition engine."""

    engine_name: SpeechRecognitionEngineName | None


class SpeechRecognitionSetIsIntentsActiveAction(SpeechRecognitionAction):
    """Action to set the active state of the voice intents listener."""

    is_active: bool


class SpeechRecognitionSetIsAssistantActiveAction(SpeechRecognitionAction):
    """Action to set the active state of the voice assistant listener."""

    is_active: bool


class SpeechRecognitionIntent(Immutable):
    """Intent for speech recognition service."""

    phrase: str | Sequence[str]
    action: UboAction | Sequence[UboAction]


class SpeechRecognitionReportWakeWordDetectionAction(SpeechRecognitionAction):
    """Action to report wake word detection."""

    wake_word: str


class SpeechRecognitionReportIntentDetectionAction(SpeechRecognitionAction):
    """Action to report intent detection."""

    intent: SpeechRecognitionIntent


class SpeechRecognitionReportSpeechAction(SpeechRecognitionAction):
    """Action to report speech raw audio and recognized text."""

    engine_name: SpeechRecognitionEngineName
    text: str
    audio: bytes


class SpeechRecognitionEvent(BaseEvent):
    """Base class for speech recognition events."""


class SpeechRecognitionReportTextEvent(SpeechRecognitionEvent):
    """Event to report stream of recognized text."""

    timestamp: float
    text: str


class SpeechRecognitionStatus(StrEnum):
    """State for speech recognition service."""

    IDLE = 'idle'
    INTENTS_WAITING = 'intents_waiting'
    ASSISTANT_WAITING = 'assistant_waiting'


class SpeechRecognitionEngineName(StrEnum):
    """Available speech recognition engines."""

    VOSK = 'vosk'
    GOOGLE = 'google_cloud'


class SpeechRecognitionState(Immutable):
    """State for speech recognition service."""

    selected_engine: SpeechRecognitionEngineName | None = field(
        default=read_from_persistent_store(
            'speech_recognition:selected_engine',
            mapper=lambda value: SpeechRecognitionEngineName(value)
            if value in SpeechRecognitionEngineName.__members__.values()
            else SpeechRecognitionEngineName.VOSK,
            default=SpeechRecognitionEngineName.VOSK,
        ),
    )
    intents: list[SpeechRecognitionIntent]
    is_intents_active: bool = field(
        default=read_from_persistent_store(
            'speech_recognition:is_intents_active',
            default=True,
        ),
    )
    is_assistant_active: bool = field(
        default=read_from_persistent_store(
            'speech_recognition:is_assistant_active',
            default=False,
        ),
    )
    status: SpeechRecognitionStatus = SpeechRecognitionStatus.IDLE
