"""Voice transcription — OpenAI Whisper when key exists, else local placeholder."""

from __future__ import annotations

import base64
import io

import httpx

from app.config import get_settings
from app.schemas.common import JobStatus
from app.schemas.transcription import (
    TranscriptionProvider,
    TranscriptionRequest,
    TranscriptionResponse,
    TranscriptSegment,
)


class TranscriptionService:
    async def transcribe(self, payload: TranscriptionRequest) -> TranscriptionResponse:
        settings = get_settings()
        provider = payload.provider
        if provider == TranscriptionProvider.STUB:
            provider = TranscriptionProvider.WHISPER

        audio_bytes: bytes | None = None
        if payload.audio_base64:
            try:
                audio_bytes = base64.b64decode(payload.audio_base64)
            except Exception:
                audio_bytes = None

        # Live OpenAI Whisper
        if (
            provider == TranscriptionProvider.WHISPER
            and settings.openai_api_key.strip()
            and (audio_bytes or payload.source_url)
        ):
            try:
                async with httpx.AsyncClient(timeout=120.0) as client:
                    if not audio_bytes and payload.source_url:
                        dl = await client.get(payload.source_url)
                        dl.raise_for_status()
                        audio_bytes = dl.content

                    assert audio_bytes is not None
                    files = {
                        "file": ("audio.wav", io.BytesIO(audio_bytes), "audio/wav"),
                    }
                    data = {
                        "model": settings.whisper_model,
                        "language": payload.language,
                        "response_format": "verbose_json",
                    }
                    res = await client.post(
                        "https://api.openai.com/v1/audio/transcriptions",
                        headers={"Authorization": f"Bearer {settings.openai_api_key}"},
                        files=files,
                        data=data,
                    )
                    res.raise_for_status()
                    body = res.json()
                    text = body.get("text")
                    segments = [
                        TranscriptSegment(
                            start_ms=int(float(seg.get("start", 0)) * 1000),
                            end_ms=int(float(seg.get("end", 0)) * 1000),
                            speaker=None,
                            text=str(seg.get("text", "")).strip(),
                            confidence=None,
                        )
                        for seg in (body.get("segments") or [])[:200]
                    ]
                    return TranscriptionResponse(
                        correlation_id=payload.correlation_id,
                        interview_id=payload.interview_id,
                        provider=TranscriptionProvider.WHISPER,
                        status=JobStatus.SUCCEEDED,
                        stub=False,
                        message="Transcribed via OpenAI Whisper",
                        text=text,
                        segments=segments,
                    )
            except Exception as exc:  # noqa: BLE001
                return TranscriptionResponse(
                    correlation_id=payload.correlation_id,
                    interview_id=payload.interview_id,
                    provider=TranscriptionProvider.WHISPER,
                    status=JobStatus.FAILED,
                    stub=True,
                    message=f"Whisper failed: {exc}",
                    text=None,
                    segments=[],
                )

        # Local / no-key fallback
        return TranscriptionResponse(
            correlation_id=payload.correlation_id,
            interview_id=payload.interview_id,
            provider=TranscriptionProvider.STUB
            if payload.provider == TranscriptionProvider.STUB
            else provider,
            status=JobStatus.SUCCEEDED,
            stub=True,
            message=(
                "Local transcription placeholder — set OPENAI_API_KEY "
                "for live Whisper speech-to-text"
            ),
            text="[transcription pending — add OPENAI_API_KEY]",
            segments=[],
        )
