package com.estateunified.panel import com.google.gson.Gson import com.google.gson.JsonObject import com.google.gson.reflect.TypeToken import java.nio.charset.StandardCharsets import java.nio.file.Files import java.nio.file.Path import java.util.UUID internal data class DemoPaymentDto( val id: String = UUID.randomUUID().toString(), val ownerUserId: String = "", val listingId: String = "", val listingTitle: String = "", val dealId: String? = null, val purpose: String = "VIEWING_SLOT", val amountAmd: Long = 0, val note: String = "", val result: String = "SUCCESS", val resultReason: String = "", val isDemo: Boolean = true, val createdAtIso: String = java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME.format( java.time.LocalDateTime.now(), ), ) internal class DemoPaymentsStore( private val gson: Gson, private val file: Path, ) { private val lock = Any() fun absolutePath(): String = file.toAbsolutePath().normalize().toString() fun readAllRaw(): String = synchronized(lock) { if (!Files.isRegularFile(file)) return "[]" Files.readString(file, StandardCharsets.UTF_8).ifBlank { "[]" } } fun listForUser(userId: String): List = synchronized(lock) { load().filter { it.ownerUserId == userId || (userId.isBlank() && it.ownerUserId.isBlank()) } } fun add(dto: DemoPaymentDto): DemoPaymentDto { synchronized(lock) { val list = load().toMutableList() list.add(0, dto) persist(list) } return dto } private fun load(): List { if (!Files.isRegularFile(file)) return emptyList() val text = Files.readString(file, StandardCharsets.UTF_8) if (text.isBlank()) return emptyList() return runCatching { gson.fromJson>(text, listType) ?: emptyList() }.getOrElse { emptyList() } } private fun persist(list: List) { Files.createDirectories(file.toAbsolutePath().parent) Files.writeString(file, gson.toJson(list), StandardCharsets.UTF_8) } companion object { private val listType = object : TypeToken>() {}.type } } internal fun demoPaymentFromJson( body: JsonObject, ownerUserId: String = "", ): DemoPaymentDto? { val listingId = body.getAsJsonPrimitive("listingId")?.asString ?: return null val listingTitle = body.getAsJsonPrimitive("listingTitle")?.asString ?: "" val purpose = body.getAsJsonPrimitive("purpose")?.asString ?: "VIEWING_SLOT" val amt = body.getAsJsonPrimitive("amountAmd")?.asLong ?: return null val note = body.getAsJsonPrimitive("note")?.asString ?: "" val dealId = if (body.has("dealId") && !body.get("dealId").isJsonNull) { body.getAsJsonPrimitive("dealId")?.asString } else { null } return DemoPaymentDto( ownerUserId = ownerUserId, listingId = listingId, listingTitle = listingTitle, purpose = purpose, amountAmd = amt, note = note, dealId = dealId, ) }