package com.vejalnai.chat

import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL
import java.util.UUID

data class VejalNaiChatResponse(
    val rawJson: String,
)

class VejalNaiChatClient(
    private val baseUrl: String,
    private val widgetKey: String,
    private val visitorId: String = "android-" + UUID.randomUUID().toString(),
    private val locale: String = "bn",
) {
    fun sendMessage(
        body: String,
        name: String? = null,
        phone: String? = null,
        email: String? = null,
    ): VejalNaiChatResponse {
        val endpoint = URL(baseUrl.trimEnd('/') + "/api/widget/messages")
        val connection = endpoint.openConnection() as HttpURLConnection

        connection.requestMethod = "POST"
        connection.setRequestProperty("Accept", "application/json")
        connection.setRequestProperty("Content-Type", "application/json")
        connection.doOutput = true

        val payload = buildJsonPayload(body, name, phone, email)

        OutputStreamWriter(connection.outputStream, Charsets.UTF_8).use { writer ->
            writer.write(payload)
        }

        val stream = if (connection.responseCode in 200..299) {
            connection.inputStream
        } else {
            connection.errorStream
        }

        val response = BufferedReader(InputStreamReader(stream, Charsets.UTF_8)).use { reader ->
            reader.readText()
        }

        if (connection.responseCode !in 200..299) {
            throw IllegalStateException("VejalNai API error ${connection.responseCode}: $response")
        }

        return VejalNaiChatResponse(response)
    }

    private fun buildJsonPayload(body: String, name: String?, phone: String?, email: String?): String {
        val fields = linkedMapOf(
            "widget_key" to widgetKey,
            "visitor_id" to visitorId,
            "platform" to "android",
            "locale" to locale,
            "body" to body,
        )

        if (name != null) fields["name"] = name
        if (phone != null) fields["phone"] = phone
        if (email != null) fields["email"] = email

        return fields.entries.joinToString(prefix = "{", postfix = "}") { (key, value) ->
            "\"${escapeJson(key)}\":\"${escapeJson(value)}\""
        }
    }

    private fun escapeJson(value: String): String {
        return value
            .replace("\\", "\\\\")
            .replace("\"", "\\\"")
            .replace("\n", "\\n")
            .replace("\r", "\\r")
    }
}
