package com.example.elva.util

import android.content.Context
import android.util.Base64
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import dagger.hilt.android.qualifiers.ApplicationContext
import org.json.JSONObject
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class AuthManager @Inject constructor(
    @ApplicationContext private val context: Context
) {

    private val masterKey = MasterKey.Builder(context)
        .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
        .build()

    private val prefs = EncryptedSharedPreferences.create(
        context,
        "auth_prefs",
        masterKey,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )

    companion object {
        private const val KEY_ACCESS_TOKEN = "access_token"
        private const val KEY_USER_ID = "user_id"
        private const val KEY_USER_EMAIL = "user_email"
        private const val KEY_USER_USERNAME = "user_username"
        private const val KEY_USER_UUID = "user_uuid"
    }

    fun saveAuthData(
        token: String,
        userId: Int,
        email: String,
        username: String,
        uuid: String = ""
    ) {
        android.util.Log.d("AuthManager", "saveAuthData called with: token=${token.take(20)}..., userId=$userId, email=$email, username=$username, uuid=$uuid")
        try {
            val success = prefs.edit()
                .putString(KEY_ACCESS_TOKEN, token)
                .putInt(KEY_USER_ID, userId)
                .putString(KEY_USER_EMAIL, email)
                .putString(KEY_USER_USERNAME, username)
                .putString(KEY_USER_UUID, uuid)
                .commit() // Используем commit() для синхронного сохранения

            android.util.Log.d("AuthManager", "SharedPreferences commit result: $success")

            // Проверяем что данные сохранились
            val savedToken = prefs.getString(KEY_ACCESS_TOKEN, null)
            val savedUserId = prefs.getInt(KEY_USER_ID, -1)
            val savedEmail = prefs.getString(KEY_USER_EMAIL, null)
            val savedUsername = prefs.getString(KEY_USER_USERNAME, null)

            android.util.Log.d("AuthManager", "Verification after save:")
            android.util.Log.d("AuthManager", "  - token: ${if(savedToken != null) "exists(${savedToken.take(20)}...)" else "null"}")
            android.util.Log.d("AuthManager", "  - userId: $savedUserId")
            android.util.Log.d("AuthManager", "  - email: $savedEmail")
            android.util.Log.d("AuthManager", "  - username: $savedUsername")

            if (savedToken != null && savedToken == token) {
                android.util.Log.d("AuthManager", "saveAuthData: Data saved and verified successfully")
            } else {
                android.util.Log.e("AuthManager", "saveAuthData: WARNING - Token verification failed!")
                android.util.Log.e("AuthManager", "  Expected: ${token.take(20)}...")
                android.util.Log.e("AuthManager", "  Got: ${savedToken?.take(20) ?: "null"}")
            }
        } catch (e: Exception) {
            android.util.Log.e("AuthManager", "Error saving auth data", e)
        }
    }

    // Вспомогательные методы для сохранения данных по отдельности
    fun saveAuthToken(token: String) {
        prefs.edit()
            .putString(KEY_ACCESS_TOKEN, token)
            .apply()
    }

    fun saveUserId(userId: Int) {
        prefs.edit()
            .putInt(KEY_USER_ID, userId)
            .apply()
    }

    fun saveUserEmail(email: String) {
        prefs.edit()
            .putString(KEY_USER_EMAIL, email)
            .apply()
    }

    fun saveUserUsername(username: String) {
        prefs.edit()
            .putString(KEY_USER_USERNAME, username)
            .apply()
    }

    fun saveUserUuid(uuid: String) {
        prefs.edit()
            .putString(KEY_USER_UUID, uuid)
            .apply()
    }

    fun getAccessToken(): String? = prefs.getString(KEY_ACCESS_TOKEN, null)

    fun getUserId(): Int = prefs.getInt(KEY_USER_ID, -1)

    fun getUserEmail(): String? = prefs.getString(KEY_USER_EMAIL, null)

    fun getUserUsername(): String? = prefs.getString(KEY_USER_USERNAME, null)

    fun getUserUuid(): String? = prefs.getString(KEY_USER_UUID, null)

    fun isLoggedIn(): Boolean {
        val token = getAccessToken()
        val expired = isTokenExpired()
        val result = token != null && !expired
        android.util.Log.d("AuthManager", "isLoggedIn: token=${if(token != null) "exists(${token.take(20)}...)" else "null"}, expired=$expired, result=$result")
        if (token != null) {
            android.util.Log.d("AuthManager", "Token details: userId=${getUserId()}, email=${getUserEmail()}, username=${getUserUsername()}")
        }
        return result
    }

    fun isTokenExpired(): Boolean {
        val token = getAccessToken() ?: return true
        return try {
            val parts = token.split(".")
            if (parts.size != 3) return true

            val payload = String(Base64.decode(parts[1], Base64.URL_SAFE))
            val json = JSONObject(payload)
            val exp = json.getLong("exp")

            exp < System.currentTimeMillis() / 1000
        } catch (e: Exception) {
            true
        }
    }

    fun logout() {
        prefs.edit().clear().apply()
    }
}

