// Package stt konuşmayı metne çevirir (Phase 6, "STT").
//
// TASARIM: motor seçimi kullanıcının kararıdır; bu paket yalnızca ARAYÜZÜ tanımlar.
// Sağlanan uygulama whisper.cpp'nin HTTP sunucusuyla konuşur (yerel, gizlilik korumalı).
// Bulut STT istenirse aynı Recognizer arayüzünün başka bir uygulaması eklenir —
// oturum/WS/ayar katmanı DEĞİŞMEZ.
package stt

import (
	"context"
	"errors"
	"strings"
	"time"
)

// Recognizer ses verisini metne çevirir.
// audio ham ses baytlarıdır (WAV/PCM); mime içeriğini belirtir.
type Recognizer interface {
	Transcribe(ctx context.Context, audio []byte, mime string) (string, error)
}

// Hatalar: WS katmanı bunları kullanıcıya anlaşılır mesajla çevirir.
var (
	// ErrNoRecognizer STT motoru yapılandırılmamış (sunucu ses kabul etmiyor).
	ErrNoRecognizer = errors.New("stt: konuşma tanıma motoru yapılandırılmamış")
	// ErrNotStarted audio gelmeden stop geldi.
	ErrNotStarted = errors.New("stt: kayıt başlatılmamış")
	// ErrEmptyAudio stop anında veri yok (kullanıcı sessizce konuşmadı).
	ErrEmptyAudio = errors.New("stt: ses verisi yok")
	// ErrTooLong kayıt sınırı aştı; veri kesilerek işlenir (sessizce yutmak yerine hata).
	ErrTooLong = errors.New("stt: kayıt süresi sınırı aştı")
	// ErrUnavailable motor yanıt vermedi (kapalı, zaman aşımı, hatalı yanıt). GEÇİCİDİR.
	ErrUnavailable = errors.New("stt: konuşma tanıma motoru yanıt vermedi")
)

// Options motor ayarlarıdır.
type Options struct {
	// URL motorun tam adresi.
	//   whisper.cpp : http://127.0.0.1:9000/inference
	//   OpenAI-uyumlu: https://api.openai.com/v1/audio/transcriptions
	// Boşsa motor yapılandırılmamış.
	URL string
	// APIKey yalnızca OpenAI-uyumlu motorlarda kullanılır (taşıyıcı belirteç).
	// whisper.cpp bunu yok sayar.
	APIKey string
	// Model yalnızca OpenAI-uyumlu motorlarda kullanılır (örn. "whisper-1", "large-v3").
	Model string
	// Language tanıma dili (boşsa motor varsayılanı).
	Language string
	// Timeout tek tanıma çağrısının üst sınırı.
	Timeout time.Duration
}

// Sanitize metni tek satıra indirger ve boş sonucu nil yapar.
// Kullanıcının konuştuğunu sandığı ama motorun boş döndüğü durumda "boş mesaj" göndermemeliyiz.
func Sanitize(s string) string {
	s = strings.TrimSpace(strings.ReplaceAll(s, "\r", " "))
	s = strings.ReplaceAll(s, "\n", " ")
	return strings.Join(strings.Fields(s), " ")
}
