package com.tomhempel.rbarometer.data

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

object AnswerRepository {

    private val answerDao get() = MyApp.database.answerDao()

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

    suspend fun getAnswersForClient(clientCode: String): List<Answer> =
        answerDao.getAnswersForClient(key(clientCode)).map { it.toDomain(clientCode) }

    /**
     * Which (client, questionnaire) pairs already have answer rows — no Keystore decrypt.
     * Used for bulk import pending-edit checks only.
     */
    suspend fun localAnswerPresence(clientCodes: List<String>): Set<Pair<String, String>> {
        if (clientCodes.isEmpty()) return emptySet()
        val keyToCode = clientCodes.associateBy { key(it) }
        return answerDao.listClientQuestionnairesWithAnswers(keyToCode.keys.toList())
            .mapNotNull { row ->
                val code = keyToCode[row.clientCodeKey] ?: return@mapNotNull null
                code to row.questionnaireId
            }
            .toSet()
    }

    fun toEntities(answers: List<Answer>): List<AnswerEntity> =
        answers.map { it.toEntity() }

    suspend fun deleteAnswersForClientAndQuestionnaires(
        clientCode: String,
        questionnaireIds: List<String>,
    ) {
        if (questionnaireIds.isEmpty()) return
        answerDao.deleteAnswersForClientAndQuestionnaires(key(clientCode), questionnaireIds)
    }

    suspend fun getAnswersForClientAndQuestionnaire(
        clientCode: String,
        questionnaireId: String,
    ): List<Answer> =
        answerDao.getAnswersForClientAndQuestionnaire(key(clientCode), questionnaireId)
            .map { it.toDomain(clientCode) }

    suspend fun insertAnswers(answers: List<Answer>) {
        if (answers.isEmpty()) return
        answerDao.insertAnswers(answers.map { it.toEntity() })
    }

    suspend fun deleteAnswersForClientAndQuestionnaire(clientCode: String, questionnaireId: String) {
        answerDao.deleteAnswersForClientAndQuestionnaire(key(clientCode), questionnaireId)
    }

    fun findAnswerValue(answers: List<Answer>, roomQuestionId: String): String? =
        answers.find { it.questionId == roomQuestionId }?.answerValue

    private fun Answer.toEntity() = AnswerEntity(
        clientCodeKey = key(clientCode),
        questionId = questionId,
        answerValueEnc = SensitiveDataCrypto.encrypt(answerValue),
    )

    private fun AnswerEntity.toDomain(clientCode: String) = Answer(
        clientCode = clientCode,
        questionId = questionId,
        answerValue = SensitiveDataCrypto.decrypt(answerValueEnc),
    )
}
