package com.nisemoe.nise.integrations;

import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.encodeToJsonElement
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter

/**
 * Docs @ https://discord.com/developers/docs/resources/channel#embed-object
 */
@Serializable
data class DiscordEmbed(
    var title: String? = null,
    var description: String? = null,
    var url: String? = null,
    var timestamp: String? = null,
    var color: Int? = null,
    @Serializable
    var fields: MutableList<DiscordEmbedField> = ArrayList(),

    var author: DiscordEmbedAuthor? = null,
    var image: DiscordEmbedImage? = null
) {

    fun setTimestamp() {
        val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.MSSZ")
        this.timestamp = ZonedDateTime.now().format(dateTimeFormatter)
    }

    fun setImageUrl(url: String) {
        this.image = DiscordEmbedImage(url)
    }

    fun setAuthor(name: String, url: String? = null, iconUrl: String? = null) {
        this.author = DiscordEmbedAuthor(name, url, iconUrl)
    }

    fun addEmbed(name: String, value: String, inline: Boolean = true) {
        this.fields.add(DiscordEmbedField(name, value, inline))
    }

}

@Serializable
data class DiscordEmbedImage (
    val url: String
)

@Serializable
data class DiscordEmbedAuthor(
    val name: String,
    val url: String? = null,
    val icon_url: String? = null
)

@Serializable
data class DiscordEmbedField(
    val name: String,
    val value: String,
    val inline: Boolean
)

@Service
class DiscordService {

    private val logger = LoggerFactory.getLogger(javaClass)

    private val httpClient: HttpClient = HttpClient.newBuilder()
        .version(HttpClient.Version.HTTP_1_1)
        .build()

    fun sendEmbeds(webhookUrl: String, embeds: List<DiscordEmbed>): Boolean {
        logger.debug("Sending Discord webhook with embed")

        val requestBody = buildJsonObject {
            put("embeds", buildJsonArray {
                embeds.forEach { add(Json.encodeToJsonElement(it)) }
            })
        }

        val request = HttpRequest.newBuilder()
            .uri(URI.create(webhookUrl))
            .POST(HttpRequest.BodyPublishers.ofString(Json.encodeToString(requestBody)))
            .header("Content-type", "application/json")
            .build()

        val response = httpClient.send(request, HttpResponse.BodyHandlers.ofString())
        return response.statusCode() == 204
    }

}

