package com.tomhempel.rbarometer.data

import com.tomhempel.rbarometer.MyApp
import com.tomhempel.rbarometer.security.SensitiveDataCrypto

object CoachScoringReviewRepository {

    private val dao get() = MyApp.database.coachScoringReviewDao()

    private fun key(clientCode: String) = SensitiveDataCrypto.clientCodeKey(clientCode)

    suspend fun saveDecision(
        clientCode: String,
        profileID: String,
        profileName: String,
        coachBand: String,
        calculatedBand: String,
        weightedTotal: Double,
    ) {
        ClientRepository.ensureClient(clientCode)
        val now = System.currentTimeMillis()
        val existing = dao.getAllForClient(key(clientCode)).find { it.profileID == profileID }
        dao.upsert(
            CoachScoringReviewEntity(
                clientCodeKey = key(clientCode),
                profileID = profileID,
                profileName = profileName,
                coachBand = coachBand,
                calculatedBand = calculatedBand,
                weightedTotal = weightedTotal,
                updatedAt = now,
                uploadedAt = existing?.uploadedAt,
            ),
        )
    }

    suspend fun getAllForClient(clientCode: String): List<CoachScoringReview> =
        dao.getAllForClient(key(clientCode)).map { it.toDomain(clientCode) }

    suspend fun getAllPendingUploads(): List<CoachScoringReview> {
        val keyToCode = ClientRepository.getAllClientCodes()
            .associateBy { SensitiveDataCrypto.clientCodeKey(it) }
        return dao.getAllPendingUploads().mapNotNull { entity ->
            val code = keyToCode[entity.clientCodeKey] ?: return@mapNotNull null
            entity.toDomain(code)
        }
    }

    suspend fun countPendingUploads(): Int = dao.countPendingUploads()

    suspend fun markUploaded(clientCode: String, profileID: String, uploadedAt: Long) {
        dao.markUploaded(key(clientCode), profileID, uploadedAt)
    }

    private fun CoachScoringReviewEntity.toDomain(clientCode: String) = CoachScoringReview(
        clientCode = clientCode,
        profileID = profileID,
        profileName = profileName,
        coachBand = coachBand,
        calculatedBand = calculatedBand,
        weightedTotal = weightedTotal,
        updatedAt = updatedAt,
        uploadedAt = uploadedAt,
    )
}
