package space.nstart.pcp_tgu_service.config

/** Настраивает Jackson-сериализацию для payload'ов клиента Camunda. */
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.KotlinModule
import io.camunda.client.api.JsonMapper as CamundaJsonMapper
import io.camunda.client.impl.CamundaObjectMapper
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import space.nstart.pcp.pcp_types_lib.utils.UtcDateTimes
import java.time.LocalDateTime

@Configuration
class CamundaJacksonConfig {

    /**
     * The service code still depends on Jackson 2 APIs, while the shared Boot 4 stack
     * auto-configures Jackson 3 for WebFlux. Keep a dedicated Jackson 2 mapper for
     * internal parsing and Camunda payloads until the module is migrated.
     */
    @Bean
    fun objectMapper(): ObjectMapper {
        return JsonMapper.builder()
            .addModule(KotlinModule.Builder().build())
            .addModule(JavaTimeModule())
            .addModule(jackson2UtcLocalDateTimeModule())
            .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .build()
    }

    /** Создаёт JSON mapper для Camunda с поддержкой Kotlin-классов и Java time типов. */
    @Bean("camundaJsonMapper")
    fun camundaJsonMapper(objectMapper: ObjectMapper): CamundaJsonMapper {
        return CamundaObjectMapper(objectMapper)
    }
}


private fun jackson2UtcLocalDateTimeModule(): SimpleModule = SimpleModule("pcp-tgu-service-jackson2-utc-local-date-time")
    .addSerializer(LocalDateTime::class.java, Jackson2UtcLocalDateTimeSerializer())
    .addDeserializer(LocalDateTime::class.java, Jackson2UtcLocalDateTimeDeserializer())

private class Jackson2UtcLocalDateTimeSerializer : JsonSerializer<LocalDateTime>() {
    override fun serialize(value: LocalDateTime, gen: JsonGenerator, serializers: SerializerProvider) {
        gen.writeString(UtcDateTimes.format(value))
    }
}

private class Jackson2UtcLocalDateTimeDeserializer : JsonDeserializer<LocalDateTime>() {
    override fun deserialize(p: JsonParser, ctxt: DeserializationContext): LocalDateTime {
        val value = p.valueAsString ?: throw IllegalArgumentException("Expected ISO-8601 UTC date-time string")
        return UtcDateTimes.parse(value)
    }
}
