package uz.mobiuz.mobiservice.dev.network.repository

import android.content.Context
import uz.mobiuz.mobiservice.dev.model.SharedPref
import uz.mobiuz.mobiservice.dev.model.UserAuth
import uz.mobiuz.mobiservice.dev.network.api.ApiService
import uz.mobiuz.mobiservice.dev.network.model.Action
import uz.mobiuz.mobiservice.dev.network.model.ChangePassword
import uz.mobiuz.mobiservice.dev.network.model.UiStateObject
import uz.mobiuz.mobiservice.dev.utils.extensions.getMessage
import uz.mobiuz.mobiservice.dev.utils.extensions.userMessage
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class AuthRepository @Inject constructor(
    private val apiService: ApiService,
    private val pref: SharedPref,
    @ApplicationContext val context: Context
) {

    suspend fun checkPhone(data: UserAuth): UiStateObject<Action> {
        return try {
            withContext(Dispatchers.IO){
                val res = apiService.checkPhone(data)
                withContext(Dispatchers.Main){
                    when {
                        res.status -> UiStateObject.SUCCESS(res.data ?: Action())
                        res.errors.isNotEmpty() -> UiStateObject.ERROR(res.errors.getMessage())
                        else -> UiStateObject.ERROR(res.message)
                    }
                }
            }
        } catch (e: Exception) {
            UiStateObject.ERROR(e.userMessage(context))
        }
    }

    suspend fun registerUser(data: UserAuth): UiStateObject<String> {
        return try {
            withContext(Dispatchers.IO){
                val res = apiService.register(data)
                withContext(Dispatchers.Main){
                    when {
                        res.status && res.data != null -> UiStateObject.SUCCESS(res.data!!)
                        res.errors.isNotEmpty() -> UiStateObject.ERROR(res.errors.getMessage())
                        else -> UiStateObject.ERROR(res.message)
                    }
                }
            }

        } catch (e: Exception) {
            UiStateObject.ERROR(e.userMessage(context))
        }
    }

    suspend fun checkSMSCode(data: UserAuth): UiStateObject<String> {
        return try {
            withContext(Dispatchers.IO){
                val res = apiService.checkSMSCode(data)
                withContext(Dispatchers.Main){
                    when {
                        res.status -> {
                            pref.userToken = res.data?.token
                            pref.isRegistered = true
                            UiStateObject.SUCCESS(res.message)
                        }
                        res.errors.isNotEmpty() -> UiStateObject.ERROR(res.errors.getMessage())
                        else -> UiStateObject.ERROR(res.message)
                    }
                }
            }
        } catch (e: Exception) {
            UiStateObject.ERROR(e.userMessage(context))
        }
    }

    suspend fun loginUser(data: UserAuth): UiStateObject<String> {
        return try {
            withContext(Dispatchers.IO){
                val res = apiService.login(data)
                withContext(Dispatchers.Main){
                    when {
                        res.status -> {
                            UiStateObject.SUCCESS(res.data!!)
                        }
                        res.errors.isNotEmpty() -> UiStateObject.ERROR(res.errors.getMessage())
                        else -> UiStateObject.ERROR(res.message)
                    }
                }
            }
        } catch (e: Exception) {
            UiStateObject.ERROR(e.userMessage(context))
        }
    }

    suspend fun checkResetCode(data: UserAuth): UiStateObject<String> {
        return try {
            withContext(Dispatchers.IO){
                val res = apiService.checkResetCode(data)
                withContext(Dispatchers.Main){
                    when {
                        res.status -> {
                            UiStateObject.SUCCESS(res.message)
                        }
                        res.errors.isNotEmpty() -> UiStateObject.ERROR(res.errors.getMessage())
                        else -> UiStateObject.ERROR(res.message)
                    }
                }
            }
        } catch (e: Exception) {
            UiStateObject.ERROR(e.userMessage(context))
        }
    }

    suspend fun resetPassword(data: UserAuth): UiStateObject<String> {
        return try {
            withContext(Dispatchers.IO){
                val res = apiService.resetPassword(data)
                withContext(Dispatchers.Main){
                    when {
                        res.status -> {
                            pref.isRegistered = true
                            pref.userToken = res.data?.token
                            UiStateObject.SUCCESS(res.message)
                        }
                        res.errors.isNotEmpty() -> UiStateObject.ERROR(res.errors.getMessage())
                        else -> UiStateObject.ERROR(res.message)
                    }
                }
            }
        } catch (e: Exception) {
            UiStateObject.ERROR(e.userMessage(context))
        }
    }

    suspend fun forgetPassword(data: UserAuth): UiStateObject<String> {
        return try {
            withContext(Dispatchers.IO){
                val res = apiService.forgetPassword(data)
                withContext(Dispatchers.Main){
                    when {
                        res.status -> {
                            UiStateObject.SUCCESS(res.data?:"")
                        }
                        res.errors.isNotEmpty() -> UiStateObject.ERROR(res.errors.getMessage())
                        else -> UiStateObject.ERROR(res.message)
                    }
                }
            }
        } catch (e: Exception) {
            UiStateObject.ERROR(e.userMessage(context))
        }
    }

    suspend fun resetSmsCode(data: UserAuth): UiStateObject<String> {
        return try {
            withContext(Dispatchers.IO){
                val res = apiService.reSendSms(data)
                withContext(Dispatchers.Main){
                    when {
                        res.status -> {
                            UiStateObject.SUCCESS(res.data ?: "")
                        }
                        res.errors.isNotEmpty() -> UiStateObject.ERROR(res.errors.getMessage())
                        else -> UiStateObject.ERROR(res.message)
                    }
                }
            }
        } catch (e: Exception) {
            UiStateObject.ERROR(e.userMessage(context))
        }
    }

    suspend fun checkPassword(data: UserAuth): UiStateObject<String> {
        return try {
            withContext(Dispatchers.IO){
                val res = apiService.checkPassword(data)
                withContext(Dispatchers.Main){
                    when {
                        res.status -> {
                            UiStateObject.SUCCESS(res.message)
                        }
                        res.errors.isNotEmpty() -> UiStateObject.ERROR(res.errors.getMessage(),true)
                        else -> UiStateObject.ERROR(res.message,true)
                    }
                }
            }
        } catch (e: Exception) {
            UiStateObject.ERROR(e.userMessage(context))
        }
    }

    suspend fun installPassword(data: ChangePassword): UiStateObject<String> {
        return try {
            withContext(Dispatchers.IO){
                val res = apiService.installPassword(data)
                withContext(Dispatchers.Main){
                    when {
                        res.status -> {
                            UiStateObject.SUCCESS(res.message)
                        }
                        res.errors.isNotEmpty() -> UiStateObject.ERROR(res.errors.getMessage())
                        else -> UiStateObject.ERROR(res.message)
                    }
                }
            }
        } catch (e: Exception) {
            UiStateObject.ERROR(e.userMessage(context))
        }
    }

}