package network

import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.HttpTimeout
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.request.*
import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import model.RealTimeTrade

object AiService {
    private val client = HttpClient(CIO) {
        install(ContentNegotiation) {
            json(Json {
                ignoreUnknownKeys = true
                coerceInputValues = true
            })
        }
        install(HttpTimeout) {
            requestTimeoutMillis = 60_000  // 전체 요청 대기 시간을 60초로 설정
            connectTimeoutMillis = 10_000  // 서버 연결 대기 시간 10초
            socketTimeoutMillis = 60_000   // 데이터 수신 대기 시간 60초
        }
    }

//    private const val LLM_URL = "http://localhost:8080/completion"
    private const val LLM_URL = "http://127.0.0.1:8080/completion"
    /**
     * 종목명, 현재가, 실시간 체결내역을 바탕으로 AI 분석 결과를 가져옵니다.
     */
    suspend fun fetchAnalysis(
        stockName: String,
        currentPrice: String,
        trades: List<RealTimeTrade>
    ): String {
        // 최근 체결 내역 10개를 텍스트로 요약
        val tradeSummary = trades.take(10).joinToString("\n") { trade ->
            "- ${trade.time}: ${trade.price}원 (${trade.volume}주 ${if (trade.type.name == "BUY") "매수" else "매도"})"
        }

        // Gemma에게 전달할 프롬프트 구성
        val prompt = """
        <|begin_of_text|><|start_header_id|>system<|end_header_id|>
        당신은 20년 경력의 주식 트레이더입니다. 데이터를 분석하여 짧고 단호하게 조언합니다.<|eot_id|><|start_header_id|>user<|end_header_id|>
        다음 데이터를 분석하여 '수급 상황'과 '단기 전망'을 3줄 이내로 요약하세요.

        [종목] $stockName ($currentPrice)
        [최근 체결]
        $tradeSummary
        <|eot_id|><|start_header_id|>assistant<|end_header_id|>
    """.trimIndent()

        return try {
            val response = client.post(LLM_URL) {
                contentType(ContentType.Application.Json)
                setBody(LlamaRequest(prompt = prompt))
            }

            if (response.status == HttpStatusCode.OK) {
                val result: LlamaResponse = response.body()
                result.content.trim()
            } else {
                "AI 서버 응답 오류: ${response.status}"
            }
        } catch (e: Exception) {
            var msg = "분석 실패: 로컬 AI 서버(llama.cpp)가 실행 중인지 확인하세요. (${e.message})"
            println(msg)
            msg
        }
    }


    suspend fun getEmbedding(text: String): List<Double>? {
        return try {
            val response = client.post("http://127.0.0.1:8080/embedding") {
                contentType(ContentType.Application.Json)
                setBody(EmbeddingRequest(content = text))
            }
            if (response.status == HttpStatusCode.OK) {
                val res: EmbeddingResponse = response.body()
                res.embedding
            } else null
        } catch (e: Exception) {
            null
        }
    }


}


@Serializable
data class EmbeddingRequest(val content: String)

@Serializable
data class EmbeddingResponse(val embedding: List<Double>)

/**
 * llama.cpp 서버 요청 데이터 구조
 */
@Serializable
data class LlamaRequest(
    val prompt: String,
    val n_predict: Int = 256,       // 답변 길이를 엄격히 제한
    val temperature: Double = 0.4, // M3 Pro에서 더 일관된 답변을 위해 낮춤
    val stop: List<String> = listOf(
        "<|eot_id|>",
        "<|end_of_text|>",
        "<|start_header_id|>",
        "user",
        "model"
    ) // [중요] AI가 멈춰야 할 지점들을 명확히 지정
)

/**
 * llama.cpp 서버 응답 데이터 구조
 */
@Serializable
data class LlamaResponse(
    val content: String
)