"""AWS Polly text-to-speech service."""

import logging
import time

_logger = logging.getLogger(__name__)

try:
    import boto3 as _boto3
except ImportError:
    _boto3 = None

VOICE_MAP = {
    "en-GB": {"female": "Amy", "male": "Brian"},
    "en-US": {"female": "Joanna", "male": "Matthew"},
    "en-AU": {"female": "Nicole", "male": "Russell"},
    "en-IN": {"female": "Aditi", "male": "Aditi"},
}


class PollyService:
    """AWS Polly TTS for generating listening exam audio."""

    def __init__(self, env):
        self.env = env
        self._get_param = env["ir.config_parameter"].sudo().get_param
        self._client = None

    def _get_client(self):
        if self._client:
            return self._client
        if not _boto3:
            raise RuntimeError("boto3 not installed — run: pip install boto3")
        access_key = self._get_param("encoach_ai.aws_access_key", "")
        secret_key = self._get_param("encoach_ai.aws_secret_key", "")
        region = self._get_param("encoach_ai.aws_region", "eu-west-1")
        if not access_key or not secret_key:
            import os
            access_key = access_key or os.environ.get("AWS_ACCESS_KEY_ID", "")
            secret_key = secret_key or os.environ.get("AWS_SECRET_ACCESS_KEY", "")
        if not access_key:
            raise RuntimeError("AWS credentials not configured — set in AI Settings")
        self._client = _boto3.client(
            "polly",
            aws_access_key_id=access_key,
            aws_secret_access_key=secret_key,
            region_name=region,
        )
        return self._client

    def _log(self, action, latency, status="success", error=None):
        try:
            self.env["encoach.ai.log"].sudo().create({
                "service": "polly",
                "action": action,
                "latency_ms": latency,
                "status": status,
                "error_message": error,
            })
        except Exception:
            pass

    def synthesize(self, text, *, voice=None, language="en-GB", gender="female",
                   engine="neural", output_format="mp3"):
        """Convert text to speech audio bytes.

        Returns:
            dict with 'audio' (bytes), 'content_type', 'voice', 'characters'
        """
        client = self._get_client()
        if not voice:
            voice = VOICE_MAP.get(language, VOICE_MAP["en-GB"]).get(gender, "Amy")
        t0 = time.time()
        try:
            resp = client.synthesize_speech(
                Text=text,
                OutputFormat=output_format,
                VoiceId=voice,
                Engine=engine,
                LanguageCode=language,
            )
            audio = resp["AudioStream"].read()
            latency = int((time.time() - t0) * 1000)
            self._log("synthesize", latency)
            return {
                "audio": audio,
                "content_type": resp["ContentType"],
                "voice": voice,
                "characters": len(text),
            }
        except Exception as exc:
            self._log("synthesize", int((time.time() - t0) * 1000), "error", str(exc))
            raise

    def list_voices(self, language="en-GB"):
        """List available voices for a language."""
        client = self._get_client()
        resp = client.describe_voices(LanguageCode=language)
        return [
            {"id": v["Id"], "name": v["Name"], "gender": v["Gender"], "engine": v.get("SupportedEngines", [])}
            for v in resp.get("Voices", [])
        ]
