package com.system.cloudservice.ai

import com.google.gson.Gson
import com.system.cloudservice.util.Logger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import java.util.concurrent.TimeUnit

class LLMClient(
    private val apiUrl: String,
    private val apiKey: String,
    private val model: String = "auto",
) {
    private val gson = Gson()
    private val client = OkHttpClient.Builder()
        .connectTimeout(15, TimeUnit.SECONDS)
        .readTimeout(60, TimeUnit.SECONDS)
        .writeTimeout(15, TimeUnit.SECONDS)
        .build()

    suspend fun chat(messages: List<Map<String, String>>, maxTokens: Int = 1024): String? {
        val url = "${apiUrl.trimEnd('/')}/api/gateway/chat"
        val payload = mutableMapOf<String, Any>(
            "messages" to messages,
            "max_tokens" to maxTokens,
        )
        if (model.isNotEmpty() && model != "auto") payload["model"] = model

        val body = gson.toJson(payload).toRequestBody("application/json".toMediaType())
        val request = Request.Builder()
            .url(url)
            .post(body)
            .addHeader("Authorization", "Bearer $apiKey")
            .addHeader("Content-Type", "application/json")
            .build()

        return withContext(Dispatchers.IO) {
            try {
                client.newCall(request).execute().use { response ->
                    if (!response.isSuccessful) {
                        Logger.e("LLM API ${response.code}: ${response.body?.string()?.take(200)}")
                        return@withContext null
                    }
                    val json = response.body?.string() ?: return@withContext null
                    @Suppress("UNCHECKED_CAST")
                    val data = gson.fromJson(json, Map::class.java) as Map<String, Any?>
                    val choices = data["choices"] as? List<*> ?: return@withContext null
                    val first = choices.firstOrNull() as? Map<*, *> ?: return@withContext null
                    val message = first["message"] as? Map<*, *> ?: return@withContext null
                    message["content"] as? String
                }
            } catch (e: Exception) {
                Logger.e("LLM API call failed", e)
                null
            }
        }
    }
}
