package com.tomhempel.rbarometer.data

import androidx.room.*

@Dao
interface ClientDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insertClient(client: Client)

    @Query("SELECT * FROM clients WHERE clientCodeKey = :key LIMIT 1")
    suspend fun getByKey(key: String): Client?

    @Query("SELECT * FROM clients")
    suspend fun getAll(): List<Client>

    @Query("DELETE FROM clients")
    suspend fun deleteAllClients()

    @Query("DELETE FROM clients WHERE clientCodeKey NOT IN (:keep)")
    suspend fun deleteClientsNotIn(keep: List<String>)
}

@Dao
interface QuestionnaireDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insertQuestionnaire(questionnaire: Questionnaire)

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insertQuestionnaires(questionnaires: List<Questionnaire>)

    @Query("SELECT * FROM questionnaires WHERE id = :id LIMIT 1")
    suspend fun getById(id: String): Questionnaire?
}

@Dao
interface QuestionDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insertQuestions(questions: List<Question>)

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insertQuestion(question: Question)

    @Query("SELECT * FROM questions WHERE questionId = :id LIMIT 1")
    suspend fun getById(id: String): Question?

    @Query("SELECT * FROM questions WHERE questionnaireId = :questionnaireId")
    suspend fun getQuestionsForQuestionnaire(questionnaireId: String): List<Question>
}

data class ClientQuestionnaireKey(
    val clientCodeKey: String,
    val questionnaireId: String,
)

@Dao
interface AnswerDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertAnswers(answers: List<AnswerEntity>)

    @Query("""
        SELECT a.* FROM answers a
        INNER JOIN questions q ON a.questionId = q.questionId
        WHERE a.clientCodeKey = :clientCodeKey AND q.questionnaireId = :questionnaireId
    """)
    suspend fun getAnswersForClientAndQuestionnaire(
        clientCodeKey: String,
        questionnaireId: String,
    ): List<AnswerEntity>

    @Query("SELECT * FROM answers WHERE clientCodeKey = :clientCodeKey")
    suspend fun getAnswersForClient(clientCodeKey: String): List<AnswerEntity>

    @Query("SELECT * FROM answers WHERE clientCodeKey IN (:clientCodeKeys)")
    suspend fun getAnswersForClients(clientCodeKeys: List<String>): List<AnswerEntity>

    /** Existence only — no decryption (bulk import pending-edit check). */
    @Query(
        """
        SELECT DISTINCT a.clientCodeKey, q.questionnaireId
        FROM answers a
        INNER JOIN questions q ON a.questionId = q.questionId
        WHERE a.clientCodeKey IN (:clientCodeKeys)
        """,
    )
    suspend fun listClientQuestionnairesWithAnswers(
        clientCodeKeys: List<String>,
    ): List<ClientQuestionnaireKey>

    @Query("""
        DELETE FROM answers 
        WHERE clientCodeKey = :clientCodeKey 
        AND questionId IN (
            SELECT questionId FROM questions WHERE questionnaireId = :questionnaireId
        )
    """)
    suspend fun deleteAnswersForClientAndQuestionnaire(
        clientCodeKey: String,
        questionnaireId: String,
    )

    @Query("""
        DELETE FROM answers 
        WHERE clientCodeKey = :clientCodeKey 
        AND questionId IN (
            SELECT questionId FROM questions WHERE questionnaireId IN (:questionnaireIds)
        )
    """)
    suspend fun deleteAnswersForClientAndQuestionnaires(
        clientCodeKey: String,
        questionnaireIds: List<String>,
    )
}

@Dao
interface CompletedQuestionnaireDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(entry: CompletedQuestionnaireEntity)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertAll(entries: List<CompletedQuestionnaireEntity>)

    @Query(
        "SELECT * FROM completed_questionnaires WHERE clientCodeKey = :clientCodeKey " +
            "AND questionnaireId = :questionnaireId LIMIT 1",
    )
    suspend fun getStatus(clientCodeKey: String, questionnaireId: String): CompletedQuestionnaireEntity?

    @Query("SELECT * FROM completed_questionnaires WHERE clientCodeKey = :clientCodeKey")
    suspend fun getAllForClient(clientCodeKey: String): List<CompletedQuestionnaireEntity>

    @Query("SELECT * FROM completed_questionnaires WHERE clientCodeKey IN (:clientCodeKeys)")
    suspend fun getAllForClients(clientCodeKeys: List<String>): List<CompletedQuestionnaireEntity>

    @Query("SELECT questionnaireId FROM completed_questionnaires WHERE clientCodeKey = :clientCodeKey")
    suspend fun getCompletedQuestionnairesForClient(clientCodeKey: String): List<String>

    @Query(
        "UPDATE completed_questionnaires SET uploadedAt = :uploadedAt " +
            "WHERE clientCodeKey = :clientCodeKey AND questionnaireId = :questionnaireId",
    )
    suspend fun markUploaded(clientCodeKey: String, questionnaireId: String, uploadedAt: Long)

    @Query(
        "SELECT * FROM completed_questionnaires WHERE clientCodeKey = :clientCodeKey AND isDone = 1 " +
            "AND (uploadedAt IS NULL OR uploadedAt < timestamp)",
    )
    suspend fun getPendingUploadForClient(clientCodeKey: String): List<CompletedQuestionnaireEntity>

    @Query(
        "SELECT * FROM completed_questionnaires WHERE isDone = 1 " +
            "AND (uploadedAt IS NULL OR uploadedAt < timestamp)",
    )
    suspend fun getAllPendingUploads(): List<CompletedQuestionnaireEntity>

    @Query(
        "SELECT COUNT(*) FROM completed_questionnaires WHERE isDone = 1 " +
            "AND (uploadedAt IS NULL OR uploadedAt < timestamp)",
    )
    suspend fun countAllPendingUploads(): Int
}

@Dao
interface CoachScoringReviewDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun upsert(entry: CoachScoringReviewEntity)

    @Query("SELECT * FROM coach_scoring_reviews WHERE clientCodeKey = :clientCodeKey")
    suspend fun getAllForClient(clientCodeKey: String): List<CoachScoringReviewEntity>

    @Query(
        "SELECT * FROM coach_scoring_reviews WHERE uploadedAt IS NULL OR uploadedAt < updatedAt",
    )
    suspend fun getAllPendingUploads(): List<CoachScoringReviewEntity>

    @Query(
        "SELECT COUNT(*) FROM coach_scoring_reviews WHERE uploadedAt IS NULL OR uploadedAt < updatedAt",
    )
    suspend fun countPendingUploads(): Int

    @Query(
        "UPDATE coach_scoring_reviews SET uploadedAt = :uploadedAt " +
            "WHERE clientCodeKey = :clientCodeKey AND profileID = :profileID",
    )
    suspend fun markUploaded(clientCodeKey: String, profileID: String, uploadedAt: Long)
}
