ContactSyncMapper.kt 44 lignes · 1906 octets
package fr.ebii.card2vcf.sync

import fr.ebii.card2vcf.data.CrmContactEntity
import kotlinx.serialization.encodeToString

/** Mappe un contact Room local vers le JSON `ContactInput` serveur. */
object ContactSyncMapper {
    fun toCreatePayload(entity: CrmContactEntity): String =
        syncJson.encodeToString(entity.toRequest())

    fun toUpdatePayload(entity: CrmContactEntity): String = toCreatePayload(entity)

    private fun CrmContactEntity.toRequest(): CreateContactRequest {
        val (prenom, nom) = resolveNames()
        return CreateContactRequest(
            prenom = prenom,
            nom = nom,
            entrepriseId = entrepriseServerId?.takeIf { it.isNotBlank() },
            // Nom scanné transmis seulement sans lien serveur : le serveur résout ou crée.
            entrepriseNom = company?.trim()
                ?.takeIf { it.isNotEmpty() && entrepriseServerId.isNullOrBlank() },
            fonction = jobTitle.orEmpty(),
            emails = emails.filter { it.isNotBlank() }.map { ContactValeurDto(valeur = it.trim()) },
            telephones = phones.filter { it.isNotBlank() }.map { ContactValeurDto(valeur = it.trim()) },
            notes = notes.orEmpty(),
            statut = statut?.takeIf { it.isNotBlank() } ?: "prospect",
            etape = etape?.takeIf { it.isNotBlank() } ?: "nouveau",
            tags = tags,
        )
    }

    private fun CrmContactEntity.resolveNames(): Pair<String, String> {
        val fn = firstName?.trim().orEmpty()
        val ln = lastName?.trim().orEmpty()
        if (fn.isNotEmpty() || ln.isNotEmpty()) return fn to ln
        val full = fullName?.trim().orEmpty()
        if (full.isEmpty()) return "" to ""
        val parts = full.split(Regex("\\s+"), limit = 2)
        return when (parts.size) {
            1 -> "" to parts[0]
            else -> parts[0] to parts.drop(1).joinToString(" ")
        }
    }
}