package net.taehui.twilight.system

import com.fasterxml.jackson.databind.ObjectMapper
import net.taehui.twilight.JSON
import net.taehui.twilight.Logger
import org.apache.hc.client5.http.HttpResponseException
import org.apache.hc.client5.http.classic.methods.HttpPost
import org.apache.hc.client5.http.entity.UrlEncodedFormEntity
import org.apache.hc.client5.http.impl.classic.BasicHttpClientResponseHandler
import org.apache.hc.client5.http.impl.classic.HttpClients
import org.apache.hc.core5.http.message.BasicNameValuePair
import java.nio.charset.StandardCharsets
import java.util.concurrent.CompletableFuture

object Translator {
    fun translate(
        language: String,
        text: String,
        logger: Logger
    ): CompletableFuture<String> {
        return if (text.length > 766) CompletableFuture.completedFuture(
            text
        ) else {
            DB.loadLanguage(text).thenApply { loadedLanguage ->
                var textLanguage = loadedLanguage
                if (textLanguage.isEmpty()) {
                    textLanguage = try {
                        HttpClients.createDefault().use {
                            val dataPost = HttpPost("https://openapi.naver.com/v1/papago/detectLangs")
                            dataPost.setHeader("X-Naver-Client-Id", Configure.nhn.nhnID)
                            dataPost.setHeader("X-Naver-Client-Secret", Configure.nhn.nhnPw)
                            dataPost.entity = UrlEncodedFormEntity(
                                listOf(
                                    BasicNameValuePair("query", text)
                                ), StandardCharsets.UTF_8
                            )
                            ObjectMapper().readValue(
                                it.execute(dataPost, BasicHttpClientResponseHandler()),
                                JSON.N2MTLanguage::class.java
                            ).langCode.apply {
                                DB.saveLanguage(text, this)
                            }
                        }
                    } catch (e: HttpResponseException) {
                        if (e.statusCode != 429) {
                            logger.logFault(e)
                        }
                        ""
                    }
                }

                val targetLanguage = language.split('-')[0]
                if (textLanguage.isEmpty() || textLanguage == "unk" || textLanguage == "en" || textLanguage == targetLanguage) {
                    text
                } else {
                    val loadedTranslatedText = DB.loadTranslatedText(text, targetLanguage)
                    var translatedText = loadedTranslatedText
                    if (translatedText.isEmpty()) {
                        translatedText = try {
                            HttpClients.createDefault().use {
                                val dataPost = HttpPost("https://openapi.naver.com/v1/papago/n2mt")
                                dataPost.setHeader("X-Naver-Client-Id", Configure.nhn.nhnID)
                                dataPost.setHeader("X-Naver-Client-Secret", Configure.nhn.nhnPw)
                                dataPost.entity = UrlEncodedFormEntity(
                                    listOf(
                                        BasicNameValuePair("source", textLanguage),
                                        BasicNameValuePair("target", targetLanguage),
                                        BasicNameValuePair("text", text)
                                    ), StandardCharsets.UTF_8
                                )
                                ObjectMapper().readValue(
                                    it.execute(dataPost, BasicHttpClientResponseHandler()),
                                    JSON.N2MT::class.java
                                ).message.result.translatedText.apply {
                                    DB.saveTranslatedText(text, targetLanguage, this)
                                }
                            }
                        } catch (e: HttpResponseException) {
                            if (e.statusCode != 429) {
                                logger.logFault(e)
                            }
                            text
                        }
                    }
                    translatedText
                }
            }
        }
    }
}