package com.syncflow

import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK
import androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL
import androidx.biometric.BiometricPrompt
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Lock
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.lifecycleScope
import androidx.navigation.compose.rememberNavController
import com.syncflow.data.preferences.AppPreferences
import com.syncflow.ui.navigation.SyncFlowNavGraph
import com.syncflow.ui.theme.SyncFlowTheme
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import javax.inject.Inject

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject lateinit var appPreferences: AppPreferences

    private var isLocked by mutableStateOf(false)
    private var showRetry by mutableStateOf(false)

    private val requestNotificationPermission =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) { /* proceed regardless */ }

    override fun onCreate(savedInstanceState: Bundle?) {
        installSplashScreen()
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        requestNotificationPermissionIfNeeded()
        setContent {
            SyncFlowTheme {
                Surface(modifier = Modifier.fillMaxSize()) {
                    SyncFlowNavGraph(rememberNavController())
                }
                if (isLocked) {
                    LockOverlay(
                        showRetry = showRetry,
                        onRetry = { triggerBiometric() },
                    )
                }
            }
        }
    }

    override fun onResume() {
        super.onResume()
        if (isLocked) triggerBiometric()
    }

    override fun onStop() {
        super.onStop()
        if (isChangingConfigurations) return
        lifecycleScope.launch {
            if (appPreferences.biometricLockEnabled.first() && canAuthenticate()) {
                isLocked = true
                showRetry = false
            }
        }
    }

    private fun triggerBiometric() {
        showRetry = false
        val authenticators = bestAuthenticators()
        val executor = ContextCompat.getMainExecutor(this)
        val prompt = BiometricPrompt(this, executor, object : BiometricPrompt.AuthenticationCallback() {
            override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
                isLocked = false
                showRetry = false
            }
            override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
                // Show the Unlock button so the user can tap to retry manually
                showRetry = true
            }
            override fun onAuthenticationFailed() {
                // Wrong biometric — BiometricPrompt retries automatically
            }
        })
        val promptInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            BiometricPrompt.PromptInfo.Builder()
                .setTitle("Unlock SyncFlow")
                .setSubtitle("Use fingerprint or PIN")
                .setAllowedAuthenticators(authenticators)
                .build()
        } else {
            BiometricPrompt.PromptInfo.Builder()
                .setTitle("Unlock SyncFlow")
                .setSubtitle("Use fingerprint")
                .setNegativeButtonText("Cancel")
                .build()
        }
        prompt.authenticate(promptInfo)
    }

    private fun bestAuthenticators(): Int {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) return BIOMETRIC_STRONG
        val bm = BiometricManager.from(this)
        // Prefer strong+credential; fall back to weak+credential so side-sensor phones work
        return if (bm.canAuthenticate(BIOMETRIC_STRONG or DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS)
            BIOMETRIC_STRONG or DEVICE_CREDENTIAL
        else
            BIOMETRIC_WEAK or DEVICE_CREDENTIAL
    }

    private fun requestNotificationPermissionIfNeeded() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
                != PackageManager.PERMISSION_GRANTED
            ) {
                requestNotificationPermission.launch(Manifest.permission.POST_NOTIFICATIONS)
            }
        }
    }

    private fun canAuthenticate(): Boolean {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R)
            return BiometricManager.from(this).canAuthenticate(BIOMETRIC_STRONG) == BiometricManager.BIOMETRIC_SUCCESS
        val bm = BiometricManager.from(this)
        return bm.canAuthenticate(BIOMETRIC_STRONG or DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS ||
            bm.canAuthenticate(BIOMETRIC_WEAK or DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS
    }
}

@Composable
private fun LockOverlay(showRetry: Boolean, onRetry: () -> Unit) {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(MaterialTheme.colorScheme.background),
        contentAlignment = Alignment.Center,
    ) {
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.spacedBy(12.dp),
        ) {
            Icon(Icons.Default.Lock, null, modifier = Modifier.size(56.dp), tint = MaterialTheme.colorScheme.primary)
            Text("SyncFlow is locked", style = MaterialTheme.typography.titleMedium)
            if (showRetry) {
                Button(onClick = onRetry) { Text("Unlock") }
            } else {
                Text(
                    "Use fingerprint or PIN to unlock",
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                )
            }
        }
    }
}
