package net.taehui.twilight.system

import com.fasterxml.jackson.databind.ObjectMapper
import com.github.pemistahl.lingua.api.Language
import com.github.pemistahl.lingua.api.LanguageDetectorBuilder
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 {
    private val languageSystem =
        LanguageDetectorBuilder.fromLanguages(Language.KOREAN, Language.ENGLISH, Language.JAPANESE).build()

    fun translate(
        language: String,
        text: String,
        logger: Logger
    ): CompletableFuture<String> {
        return if (text.length > 766) CompletableFuture.completedFuture(
            text
        ) else {
            val textLanguage = when (languageSystem.detectLanguageOf(text)) {
                Language.KOREAN -> "ko"
                Language.ENGLISH -> "en"
                Language.JAPANESE -> "ja"
                Language.CHINESE -> "zh-CN"
                Language.VIETNAMESE -> "vi"
                Language.INDONESIAN -> "id"
                Language.THAI -> "th"
                Language.DUTCH -> "de"
                Language.RUSSIAN -> "ru"
                Language.SPANISH -> "es"
                Language.ITALIAN -> "it"
                Language.FRENCH -> "fr"
                else -> ""
            }
            val targetLanguage = language.split('-')[0]
            if (textLanguage.isEmpty() || textLanguage == "en" || textLanguage == targetLanguage) CompletableFuture.completedFuture(
                text
            ) else DB.loadTranslatedText(
                text,
                targetLanguage
            ).thenApply { loadedTranslatedText ->
                try {
                    loadedTranslatedText.ifEmpty {
                        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
                            )
                            val translatedText = ObjectMapper().readValue(
                                it.execute(dataPost, BasicHttpClientResponseHandler()),
                                JSON.N2MT::class.java
                            ).message.result.translatedText
                            DB.saveTranslatedText(text, targetLanguage, translatedText)
                            translatedText
                        }
                    }
                } catch (e: HttpResponseException) {
                    if (e.statusCode != 429) {
                        logger.logFault(e)
                    }
                    text
                }
            }
        }
    }
}