package com.tt.honeyDue.auth

import android.content.Context
import androidx.credentials.CredentialManager
import androidx.credentials.CustomCredential
import androidx.credentials.GetCredentialRequest
import androidx.credentials.GetCredentialResponse
import androidx.credentials.exceptions.GetCredentialException
import com.tt.honeyDue.network.ApiConfig
import com.google.android.libraries.identity.googleid.GetGoogleIdOption
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential

/**
 * Result of a Google Sign In attempt
 */
sealed class GoogleSignInResult {
    data class Success(val idToken: String) : GoogleSignInResult()
    data class Error(val message: String, val exception: Exception? = null) : GoogleSignInResult()
    object Cancelled : GoogleSignInResult()
}

/**
 * Manager for Google Sign In using Android Credential Manager
 */
class GoogleSignInManager(private val context: Context) {

    private val credentialManager = CredentialManager.create(context)

    /**
     * Initiates Google Sign In flow and returns the ID token
     */
    suspend fun signIn(): GoogleSignInResult {
        return try {
            val googleIdOption = GetGoogleIdOption.Builder()
                .setFilterByAuthorizedAccounts(false)
                .setServerClientId(ApiConfig.GOOGLE_WEB_CLIENT_ID)
                .setAutoSelectEnabled(true)
                .build()

            val request = GetCredentialRequest.Builder()
                .addCredentialOption(googleIdOption)
                .build()

            val result = credentialManager.getCredential(
                request = request,
                context = context
            )

            handleSignInResult(result)
        } catch (e: GetCredentialException) {
            when {
                e.message?.contains("cancelled", ignoreCase = true) == true ||
                e.message?.contains("user cancelled", ignoreCase = true) == true -> {
                    GoogleSignInResult.Cancelled
                }
                else -> {
                    GoogleSignInResult.Error("Sign in failed: ${e.message}", e)
                }
            }
        } catch (e: Exception) {
            GoogleSignInResult.Error("Unexpected error during sign in: ${e.message}", e)
        }
    }

    private fun handleSignInResult(result: GetCredentialResponse): GoogleSignInResult {
        val credential = result.credential

        return when (credential) {
            is CustomCredential -> {
                if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
                    try {
                        val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)
                        val idToken = googleIdTokenCredential.idToken

                        if (idToken.isNotEmpty()) {
                            GoogleSignInResult.Success(idToken)
                        } else {
                            GoogleSignInResult.Error("Empty ID token received")
                        }
                    } catch (e: Exception) {
                        GoogleSignInResult.Error("Failed to parse Google credential: ${e.message}", e)
                    }
                } else {
                    GoogleSignInResult.Error("Unexpected credential type: ${credential.type}")
                }
            }
            else -> {
                GoogleSignInResult.Error("Unexpected credential type")
            }
        }
    }
}
