package com.example.development.mainActivity

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.development.domain.utils.Constants
import com.example.development.model.Reservation
import com.example.development.model.Review
import com.example.development.model.User
import io.github.jan.supabase.gotrue.auth
import io.github.jan.supabase.gotrue.providers.builtin.Email
import io.github.jan.supabase.gotrue.providers.builtin.OTP
import io.github.jan.supabase.postgrest.from
import kotlinx.coroutines.launch
import java.io.ByteArrayOutputStream
import io.github.jan.supabase.storage.storage


class MainViewModel():ViewModel() {
    private val _users = mutableStateOf(listOf<User>())
    val users: State<List<User>> = _users
    val titleImage = mutableStateOf("")

    fun onSignInEmailPassword(emailUser: String, passwordUser: String) {
        viewModelScope.launch {
            try {
                val user = Constants.supabase.auth.signInWith(Email) {
                    email = emailUser
                    password = passwordUser
                }
                println(user.toString())
                println(Constants.supabase.auth.currentUserOrNull()!!.id)
                println("Пользователь успешно зашел в аккаунт")
                FindUser()
            } catch (e: Exception) {
                println("Пользователь не зашел в аккаунт")
                println(e.message.toString())
            }
        }
    }

    fun onSignUpEmail(emailUser: String, passwordUser: String) {
        viewModelScope.launch {
            try {
                var user = Constants.supabase.auth.signUpWith(Email) {
                    email = emailUser
                    password = passwordUser
                }
                println(user.toString())
                println(Constants.supabase.auth.currentUserOrNull()!!.id)
                println("Пользователь зарегистрирован")
            } catch (e: Exception) {
                println("Пользователь не зарегистрирован")
                println(e.message.toString())
            }

        }
    }

    fun FindUser() {
        viewModelScope.launch {
            try {
                _users.value = Constants.supabase.from("users").select {
                    filter {
                        User::UID eq Constants.supabase.auth.currentUserOrNull()!!.id
                    }
                }.decodeList<User>()
                var result = "Пользователь найден"
                println(result)
            } catch (e: Exception) {
                println("Пользователь не найден")
                println(e.message.toString())
            }
        }
    }

    fun CreateUser(
        surname: String,
        name: String,
        phoneNumber: String
    ) {
        viewModelScope.launch {
            try {
                val basket = Constants.supabase.storage["image of users"]
                Constants.supabase.from("users").insert(
                    User(
                        role = 1,
                        UID = Constants.supabase.auth.currentUserOrNull()!!.id,
                        surname = surname,
                        name = name,
                        phone = phoneNumber,
                        email = Constants.supabase.auth.currentUserOrNull()!!.email.toString()/*,
                        avatar = basket.publicUrl("${Constants.supabase.auth.currentUserOrNull()!!.email}.jpg")*/
                    )
                )
                println("Пользователь добавлен в таблицу")
            } catch (e: Exception) {
                println("Пользователь не добавлен")
                println(e.message.toString())
            }
        }
    }

    fun UpdatePersonalData(
        firstName: String,
        secondName: String,
        email: String,
        phoneNumber: String
    ) {
        viewModelScope.launch {
            try {
                Constants.supabase.from("users").update(
                    {
                        User::name setTo firstName
                        User::surname setTo secondName
                        User::email setTo email
                        User::phone setTo phoneNumber
                    }
                )
            } catch (e: Exception) {
                println("Error")
                println(e.message.toString())
            }
        }
    }

    fun checkForRegistration() {
        viewModelScope.launch {
            try {
                _users.value = Constants.supabase.from("users")
                    .select() {
                        filter {
                            User::email eq Constants.supabase.auth.currentUserOrNull()!!.email
                        }
                    }.decodeList<User>()
                println("Email уже зарегистрирован")
            } catch (e: Exception) {
                println("Email еще не зарегистрирован")
                println(e.message.toString())
            }
        }
    }

    fun upadatePassword(pass: String) {
        viewModelScope.launch {
            try {
                Constants.supabase.auth.updateUser { password = pass }
                println("Success")
            } catch (e: Exception) {
                println("Error")
                println(e.message.toString())
            }
        }
    }

    fun addAvatar(byteArray: ByteArray) {
        viewModelScope.launch {
            try {
                val basket = Constants.supabase.storage["image of users"]
                basket.upload(
                    "${Constants.supabase.auth.currentUserOrNull()!!.email}.jpg",
                    byteArray,
                    true
                )
                println("Картинка успешно добавлена")
            } catch (e: Exception) {
                println("Картинка не добавлена")
                println(e.message.toString())
            }
        }
    }

    fun getRandomString(length: Int): String {
        val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9')
        return (1..length)
            .map { allowedChars.random() }
            .joinToString("")
    }

    fun logout(context: Context) {
        viewModelScope.launch {
            try {
                Constants.supabase.auth.signOut()
                println("Пользователь успешно вышел из аккаунта")
            }
            catch (e: Exception) {
                println("Ошибка при выходе из аккаунта")
                println(e.message.toString())
            }
        }
    }


    fun AddReview(
        estimation: Int,
        comment: String
    )
    {
        viewModelScope.launch {
            try {
                Constants.supabase.from("reviews").insert(
                    Review(
                        user = Constants.supabase.auth.currentUserOrNull()!!.id,
                        estimation = estimation,
                        comment = comment
                    )
                )
                println("Отзыв добавлен")
            }
            catch(e:Exception)
            {
                println("Отзыв не добавлен")
                println(e.message.toString())
            }
        }
    }

    fun AddReservation(
        id_table: Int,
        date_and_time: String,
        quantity_of_person: Int,
        comment: String
    ){
        viewModelScope.launch{
            try{
                Constants.supabase.from("reservations").insert(
                    Reservation(
                        id_user = Constants.supabase.auth.currentUserOrNull()!!.id.toInt(),
                        id_table = id_table,
                        date_and_time = date_and_time,
                        quantity_of_person = quantity_of_person,
                        comment = comment,
                        status = 2
                    )
                )
                println("Добавлен резерв стола")
            }
            catch(e:Exception)
            {
                println("Резерв не добавлен")
                println(e.message.toString())
            }
        }
    }

    fun bitmapToByteArray(context: Context, uri: Uri): ByteArray {
        val inputStream = context.contentResolver.openInputStream(uri)
        val bitmap = BitmapFactory.decodeStream(inputStream)
        val baos = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos)
        return baos.toByteArray()
    }
}