package academy

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)

// ElevenLabsClient handles text-to-speech via the ElevenLabs API
type ElevenLabsClient struct {
	apiKey  string
	voiceID string
	client  *http.Client
}

// NewElevenLabsClient creates a new ElevenLabs client
func NewElevenLabsClient() *ElevenLabsClient {
	apiKey := os.Getenv("ELEVENLABS_API_KEY")
	voiceID := os.Getenv("ELEVENLABS_VOICE_ID")
	if voiceID == "" {
		voiceID = "EXAVITQu4vr4xnSDxMaL" // Default: "Sarah" voice
	}

	return &ElevenLabsClient{
		apiKey:  apiKey,
		voiceID: voiceID,
		client: &http.Client{
			Timeout: 120 * time.Second,
		},
	}
}

// IsConfigured returns true if API key is set
func (c *ElevenLabsClient) IsConfigured() bool {
	return c.apiKey != ""
}

// TextToSpeechRequest represents the API request
type TextToSpeechRequest struct {
	Text          string        `json:"text"`
	ModelID       string        `json:"model_id"`
	VoiceSettings VoiceSettings `json:"voice_settings"`
}

// VoiceSettings controls voice parameters
type VoiceSettings struct {
	Stability       float64 `json:"stability"`
	SimilarityBoost float64 `json:"similarity_boost"`
	Style           float64 `json:"style"`
}

// TextToSpeech converts text to speech audio (MP3)
func (c *ElevenLabsClient) TextToSpeech(text string) ([]byte, error) {
	if !c.IsConfigured() {
		return nil, fmt.Errorf("ElevenLabs API key not configured")
	}

	url := fmt.Sprintf("https://api.elevenlabs.io/v1/text-to-speech/%s", c.voiceID)

	reqBody := TextToSpeechRequest{
		Text:    text,
		ModelID: "eleven_multilingual_v2",
		VoiceSettings: VoiceSettings{
			Stability:       0.5,
			SimilarityBoost: 0.75,
			Style:           0.5,
		},
	}

	jsonBody, err := json.Marshal(reqBody)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal request: %w", err)
	}

	req, err := http.NewRequest("POST", url, bytes.NewReader(jsonBody))
	if err != nil {
		return nil, fmt.Errorf("failed to create request: %w", err)
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("xi-api-key", c.apiKey)
	req.Header.Set("Accept", "audio/mpeg")

	resp, err := c.client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("ElevenLabs API request failed: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		return nil, fmt.Errorf("ElevenLabs API error %d: %s", resp.StatusCode, string(body))
	}

	audioData, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("failed to read audio response: %w", err)
	}

	return audioData, nil
}
