package com.example.wabi.view.screeens.logIn

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.util.Log
import android.widget.Toast
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.navigation.NavHostController
import com.example.wabi.domain.navigation.NavigationProvider
import com.example.wabi.domain.navigation.Routes
import com.example.wabi.domain.repository.PrefManager
import com.example.wabi.domain.repository.UserShareDate
import com.example.wabi.domain.supabase.SupabaseServiceImpl
import com.example.wabi.models.screens.SignInState
import com.example.wabi.models.screens.SignUpState
import com.example.wabi.models.screens.SignUpUser
import com.example.wabi.view.screeens.logIn.items.signUpItems.SignUpStateDestination
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import java.io.ByteArrayOutputStream
import java.util.UUID
import javax.inject.Inject

@HiltViewModel
class LogInViewModel @Inject constructor(
    private val supabase: SupabaseServiceImpl, private val nav: NavigationProvider
) : ViewModel() {

    private val _signInData = mutableStateOf(SignInState())
    val signInData: SignInState get() = _signInData.value

    private val _signUpData = mutableStateOf(SignUpState())
    val signUpData: SignUpState get() = _signUpData.value

    private val _signUpUser = mutableStateOf(SignUpUser())
    val signUpUser: SignUpUser get() = _signUpUser.value

    private var _emailExists = MutableStateFlow<Boolean>(false)
    val emailExists = _emailExists.asStateFlow()

    fun updateDataSignIn(newData: SignInState) {
        _signInData.value = newData
    }

    fun updateDataSignUp(newData: SignUpState) {
        _signUpData.value = newData
    }

    fun updateUserDataSignUp(newData: SignUpUser) {
        _signUpUser.value = newData
    }

    fun signIn(navController: NavHostController, printError: MutableState<Boolean>) {
        if (_signInData.value.email != "" && _signInData.value.password != "") {
            viewModelScope.launch {
                val response = supabase.signIn(_signInData.value.email, _signInData.value.password)
                if (response.error == "") {

                    UserShareDate.userIsLogging.value = true
                    printError.value = false

                    PrefManager.initPrefManager(UserShareDate.context!!)
                    PrefManager.saveDataCurrentUser(
                        _signInData.value.email, _signInData.value.password
                    )

                    nav.goToNextScreen(
                        navHostController = navController, Routes.LOGIN, Routes.PROFILE
                    )
                } else {
                    Log.d("signIn", "Ошибка входа!")
                    printError.value = true
                }
            }
        }
    }

    fun validateEmail(email: String): Boolean {
        return email != "" && android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
    }

    fun checkEmailExists(email: String) {
        viewModelScope.launch {
            _emailExists.value = supabase.emailIsExists(email)
            Log.d("email is exists", "result: ${_emailExists.value}")
        }
    }

    fun signUp(
    ) {
        viewModelScope.launch {
            var response = supabase.signUp(
                userEmail = _signUpData.value.email, userPasword = _signUpData.value.passwordOne
            )

            if (response.error == "") {

                Log.d("current user", supabase.getCurrentUser().toString())

                val uuidBasket = UUID.randomUUID().toString()

                updateUserDataSignUp(
                    _signUpUser.value.copy(
                        id = supabase.getCurrentUser()!!.id,
                        email = _signUpData.value.email,
                        image = if (_signUpUser.value.imageOfBytes != null) {
                            "https://reusjamfhgxymxwkykmb.supabase.co/storage/v1/object/public/image/user/$uuidBasket.png"
                        } else {
                            null
                        },
                        basketCode = uuidBasket
                    )
                )

                if (_signUpUser.value.imageOfBytes != null) {
                    supabase.uploadImageToStorage(
                        where = "image/user",
                        name = "$uuidBasket.png",
                        image = _signUpUser.value.imageOfBytes!!
                    )
                }

                response = supabase.addUser(_signUpUser.value)

                if (response.error == "") {
                    UserShareDate.userIsLogging.value = true
                    PrefManager.initPrefManager(UserShareDate.context!!)
                    PrefManager.saveDataCurrentUser(
                        _signInData.value.email, _signInData.value.password
                    )
                    Toast.makeText(UserShareDate.context!!, "Добро пожаловать!", Toast.LENGTH_LONG)
                        .show()
                } else {
                    Log.e("signUn", "Error registration!")
                }
            } else {
                Log.e("signUn", "Error registration!")
            }
        }
    }

    fun switchSignUpStation(printError: MutableState<Int>, stationChanger: MutableState<Int>) {
        if (_signUpData.value.email != "" && _signUpData.value.passwordOne != "" && _signUpData.value.passwordTwo != "") {
            if (checkCorrectPassword(_signUpData.value.passwordOne) && checkCorrectPassword(
                    _signUpData.value.passwordTwo
                )
            ) {
                if (_signUpData.value.passwordOne == _signUpData.value.passwordTwo) {
                    viewModelScope.launch {
                        val checkEmail = supabase.emailIsExists(_signUpData.value.email)
                        if (!checkEmail) {
                            printError.value = 0

                            stationChanger.value = SignUpStateDestination.createProfile

                            Log.d("signUn", "go to created profile")
                        } else {
                            printError.value = 1
                        }
                    }
                } else {
                    printError.value = 3
                }
            } else {
                printError.value = 2
            }
        } else {
            printError.value = 4
        }
    }

    private fun checkCorrectPassword(password: String): Boolean {
        return password.length > 5
    }

    fun converterBitMapToByteArray(uri: Uri): ByteArray {
        val inputStream = UserShareDate.context!!.contentResolver.openInputStream(uri)
        val bitmap = BitmapFactory.decodeStream(inputStream)
        val byteArrayInputStream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayInputStream)
        return byteArrayInputStream.toByteArray()
    }

    fun uploadUserImage(image: ByteArray, name: String) {
        viewModelScope.launch {
            supabase.uploadImageToStorage(where = "image/user", name = "$name.png", image = image)
        }
    }

    fun sendEmailForResetPassword(email: String): Boolean {
        var result = false
        viewModelScope.launch {
            val response = supabase.resetPasswordForEmail(email)
            result = response.error == ""
        }
        return result
    }

}