package services

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
)

var whisperHTTPClient = &http.Client{Timeout: 90 * time.Second}

// TranscribirAudio envía un archivo de audio a un endpoint de transcripción
// compatible con la API de OpenAI (POST /audio/transcriptions, multipart) y
// devuelve el texto. Funciona tanto con OpenAI (modelo whisper-1) como con Groq
// (modelo whisper-large-v3), reutilizando la config que ya se administra en
// /app/ai-config con el módulo "whisper".
func TranscribirAudio(ai *models.AiConfig, audioPath string) (string, error) {
	if ai == nil {
		return "", fmt.Errorf("no hay una configuración de Whisper activa: ve a /app/ai-config, crea o edita una y márcale el módulo 'Transcripción de audio (Whisper)'")
	}
	if ai.ClaveEnClaro() == "" {
		return "", fmt.Errorf("la configuración de Whisper '%s' no tiene API key", ai.Nombre)
	}

	baseURL := ai.BaseURL
	if baseURL == "" {
		baseURL = ProviderDefaultURL(ai.Provider)
	}
	baseURL = strings.TrimRight(baseURL, "/")

	model := ai.ModelName
	if model == "" {
		model = "whisper-1"
	}

	f, err := os.Open(audioPath)
	if err != nil {
		return "", fmt.Errorf("no se pudo abrir el audio descargado: %w", err)
	}
	defer f.Close()

	var body bytes.Buffer
	writer := multipart.NewWriter(&body)
	part, err := writer.CreateFormFile("file", filepath.Base(audioPath))
	if err != nil {
		return "", err
	}
	if _, err := io.Copy(part, f); err != nil {
		return "", fmt.Errorf("error leyendo el audio: %w", err)
	}
	_ = writer.WriteField("model", model)
	_ = writer.WriteField("response_format", "json")
	if err := writer.Close(); err != nil {
		return "", err
	}

	req, err := http.NewRequest("POST", baseURL+"/audio/transcriptions", &body)
	if err != nil {
		return "", err
	}
	req.Header.Set("Authorization", "Bearer "+ai.ClaveEnClaro())
	req.Header.Set("Content-Type", writer.FormDataContentType())

	resp, err := whisperHTTPClient.Do(req)
	if err != nil {
		return "", fmt.Errorf("no se pudo conectar con el servicio de transcripción: %w", err)
	}
	defer resp.Body.Close()
	raw, _ := io.ReadAll(io.LimitReader(resp.Body, 1024*1024))

	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		detalle := strings.TrimSpace(string(raw))
		if len(detalle) > 300 {
			detalle = detalle[:300]
		}
		return "", fmt.Errorf("el servicio de transcripción respondió %d: %s", resp.StatusCode, detalle)
	}

	var out struct {
		Text string `json:"text"`
	}
	if err := json.Unmarshal(raw, &out); err != nil {
		return "", fmt.Errorf("respuesta inesperada del servicio de transcripción")
	}
	texto := strings.TrimSpace(out.Text)
	if texto == "" {
		return "", fmt.Errorf("no se detectó texto en el audio")
	}
	return texto, nil
}
