package app.closer.data.repository

import app.closer.data.remote.FirestoreQuestionThreadDataSource
import app.closer.domain.model.QuestionAnswer
import app.closer.domain.model.QuestionMessage
import app.closer.domain.model.QuestionReaction
import app.closer.domain.model.QuestionThread
import app.closer.domain.model.QuestionThreadStatus
import app.closer.domain.repository.CoupleRepository
import app.closer.domain.repository.QuestionThreadRepository
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class QuestionThreadRepositoryImpl @Inject constructor(
    private val dataSource: FirestoreQuestionThreadDataSource,
    private val coupleRepository: CoupleRepository
) : QuestionThreadRepository {

    override suspend fun findOrCreateThreadId(
        coupleId: String,
        questionId: String,
        categoryId: String,
        userId: String
    ): String = dataSource.findThreadByQuestionId(coupleId, questionId)
        ?: dataSource.createThread(coupleId, questionId, categoryId, userId)

    override fun observeThread(coupleId: String, threadId: String): Flow<QuestionThread> =
        dataSource.observeThread(coupleId, threadId)

    override suspend fun submitAnswer(
        coupleId: String,
        threadId: String,
        userId: String,
        answer: QuestionAnswer
    ) {
        val countBefore = dataSource.getAnswerCount(coupleId, threadId)
        dataSource.submitAnswer(coupleId, threadId, userId, answer)
        val countAfter = dataSource.getAnswerCount(coupleId, threadId)
        val newStatus = when {
            countAfter >= 2 -> QuestionThreadStatus.REVEALED
            countAfter == 1 -> QuestionThreadStatus.ANSWERED_BY_ONE
            else -> QuestionThreadStatus.NOT_STARTED
        }
        // The thread's phase is driven by the answer docs, not this status field, so a failed
        // status write (e.g. a legacy lowercase doc the rules won't transition) must NOT fail
        // the whole submit — that previously surfaced "Thread unavailable" and blocked discussion.
        runCatching { dataSource.updateThreadStatus(coupleId, threadId, newStatus) }
        if (countBefore < 2 && newStatus == QuestionThreadStatus.REVEALED) {
            runCatching { coupleRepository.updateStreak(coupleId) }
        }
    }

    override fun observeAnswers(coupleId: String, threadId: String): Flow<List<QuestionAnswer>> =
        dataSource.observeAnswers(coupleId, threadId)

    override suspend fun sendMessage(coupleId: String, threadId: String, message: QuestionMessage) =
        dataSource.sendMessage(coupleId, threadId, message)

    override suspend fun sendImageMessage(coupleId: String, threadId: String, userId: String, imageBytes: ByteArray) =
        dataSource.sendImageMessage(coupleId, threadId, userId, imageBytes)

    override suspend fun loadDecryptedMedia(coupleId: String, mediaUrl: String): ByteArray? =
        dataSource.loadDecryptedMedia(coupleId, mediaUrl)

    override fun observeMessages(coupleId: String, threadId: String): Flow<List<QuestionMessage>> =
        dataSource.observeMessages(coupleId, threadId)

    override suspend fun addReaction(coupleId: String, threadId: String, reaction: QuestionReaction) =
        dataSource.addReaction(coupleId, threadId, reaction)

    override fun observeReactions(coupleId: String, threadId: String): Flow<List<QuestionReaction>> =
        dataSource.observeReactions(coupleId, threadId)
}
