package com.tomhempel.rbarometer.network

import android.content.Context
import android.widget.Toast
import com.tomhempel.rbarometer.LanguageManager

sealed class SyncResult {
    data object Success : SyncResult()
    data class Failure(val error: Throwable?, val usedOfflineCache: Boolean = false) : SyncResult()
    data object AuthRequired : SyncResult()
    data object Offline : SyncResult()
}

object SyncCoordinator {

    fun loadCachedTranslations(context: Context) {
        QuestionnaireSyncService.loadCachedTranslations(context)
    }

    /** Fetches app UI strings without login (login screen + offline cache refresh). */
    suspend fun refreshPublicTranslations(context: Context): Boolean {
        if (!NetworkUtils.isOnline(context)) return false
        return runCatching {
            val data = QuestionnaireApiClient.getPublicTranslations()
            QuestionnaireCache.saveTranslations(context, data)
        }.isSuccess
    }

    suspend fun refreshAfterLogin(
        context: Context,
        token: String,
        languageId: String,
        onProgress: SyncProgressCallback? = null,
    ): SyncResult {
        if (!NetworkUtils.isOnline(context)) {
            loadCachedTranslations(context)
            return SyncResult.Offline
        }
        val result = runCatching {
            QuestionnaireSyncService.refreshAll(
                context = context,
                token = token,
                onProgress = onProgress,
            )
        }
        val error = result.exceptionOrNull()
        if (error != null && TokenStore.isAuthError(error)) {
            return SyncResult.AuthRequired
        }
        if (result.isSuccess) return SyncResult.Success
        loadCachedTranslations(context)
        return SyncResult.Failure(error, usedOfflineCache = true)
    }

    suspend fun refreshManual(
        context: Context,
        token: String,
        onProgress: SyncProgressCallback? = null,
    ): SyncResult {
        if (!NetworkUtils.isOnline(context)) return SyncResult.Offline
        val result = runCatching {
            QuestionnaireSyncService.refreshAll(
                context = context,
                token = token,
                onProgress = onProgress,
            )
        }
        val error = result.exceptionOrNull()
        if (error != null && TokenStore.isAuthError(error)) return SyncResult.AuthRequired
        return if (result.isSuccess) SyncResult.Success else SyncResult.Failure(error)
    }

    suspend fun refreshClientsOnly(context: Context, token: String): SyncResult {
        if (!NetworkUtils.isOnline(context)) return SyncResult.Offline
        val result = runCatching {
            QuestionnaireSyncService.refreshAssignedClients(context, token)
        }
        val error = result.exceptionOrNull()
        if (error != null && TokenStore.isAuthError(error)) return SyncResult.AuthRequired
        return if (result.isSuccess) SyncResult.Success else SyncResult.Failure(error)
    }

    fun toastForResult(context: Context, languageId: String, result: SyncResult) {
        when (result) {
            is SyncResult.Failure -> {
                if (result.usedOfflineCache) {
                    Toast.makeText(
                        context,
                        LanguageManager.getText(languageId, "download_failed_use_offline"),
                        Toast.LENGTH_LONG,
                    ).show()
                }
            }
            SyncResult.Offline -> {
                Toast.makeText(
                    context,
                    LanguageManager.getText(languageId, "offline"),
                    Toast.LENGTH_LONG,
                ).show()
            }
            else -> {}
        }
    }
}
