#include "WhisperClient.h"
#include "WinHttpClient.h"
#include "../audio/AudioBuffer.h"
#include <nlohmann/json.hpp>
#include <iostream>
#include <fstream>

using json = nlohmann::json;

namespace secondvoice {

WhisperClient::WhisperClient(const std::string& api_key)
    : api_key_(api_key) {
}

std::optional<WhisperResponse> WhisperClient::transcribe(
    const std::vector<float>& audio_data,
    int sample_rate,
    int channels,
    const std::string& model,
    const std::string& language,
    float temperature,
    const std::string& prompt,
    const std::string& response_format) {

    // Save audio to temporary Opus/OGG file (smaller than WAV)
    AudioBuffer buffer(sample_rate, channels);
    buffer.addSamples(audio_data);

    std::string temp_file = "secondvoice_temp.ogg";
    if (!buffer.saveToOpus(temp_file)) {
        std::cerr << "Failed to save temporary Opus file" << std::endl;
        return std::nullopt;
    }

    std::cout << "Saved Opus file: " << temp_file << std::endl;

    // Read file into memory
    std::ifstream file(temp_file, std::ios::binary | std::ios::ate);
    if (!file.is_open()) {
        std::cerr << "Failed to open temporary WAV file" << std::endl;
        return std::nullopt;
    }

    std::streamsize size = file.tellg();
    file.seekg(0, std::ios::beg);
    std::vector<char> fileData(size);
    if (!file.read(fileData.data(), size)) {
        std::cerr << "Failed to read temporary WAV file" << std::endl;
        return std::nullopt;
    }
    file.close();

    // Prepare form fields
    std::map<std::string, std::string> fields = {
        {"model", model},
        {"language", language},
        {"response_format", response_format}
    };

    // Temperature only supported by whisper-1
    if (model == "whisper-1") {
        fields["temperature"] = std::to_string(temperature);
    }

    if (!prompt.empty()) {
        fields["prompt"] = prompt;
    }

    // Make request
    WinHttpClient client;
    std::map<std::string, std::string> headers = {
        {"Authorization", "Bearer " + api_key_}
    };

    auto response = client.postMultipart(
        "api.openai.com",
        "/v1/audio/transcriptions",
        fields,
        "file",
        "audio.ogg",
        "audio/ogg",
        fileData,
        headers
    );

    if (!response) {
        std::cerr << "Whisper API request failed" << std::endl;
        return std::nullopt;
    }

    if (response->statusCode != 200) {
        std::cerr << "Whisper API error " << response->statusCode << ": " << response->body << std::endl;
        return std::nullopt;
    }

    // Parse response - for "text" format, response is plain text
    // For "json" format, it's JSON
    WhisperResponse result;
    if (response_format == "text") {
        result.text = response->body;
    } else {
        try {
            json response_json = json::parse(response->body);
            result.text = response_json["text"].get<std::string>();
        } catch (const json::exception& e) {
            std::cerr << "Failed to parse Whisper response: " << e.what() << std::endl;
            return std::nullopt;
        }
    }

    return result;
}

} // namespace secondvoice
