package com.yorvana

import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.navigation3.runtime.NavKey
import com.yorvana.data.preferences.AppPreferences
import com.yorvana.ui.TestTags
import com.yorvana.ui.navigation.AppNavGraph
import com.yorvana.ui.navigation.Setup
import com.yorvana.ui.navigation.VehicleList
import com.yorvana.ui.navigation.restoreSavedNavRoute
import com.yorvana.ui.theme.YorvanaTheme
import com.yorvana.util.CrashReporter
import kotlinx.coroutines.launch

class MainActivity : ComponentActivity() {
    private var skipNextRefresh = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()

        val application = application as YorvanaApplication
        application.billingManager.startConnection()
        skipNextRefresh = true

        setContent {
            YorvanaTheme {
                MainContent(application)
            }
        }
    }

    override fun onResume() {
        super.onResume()
        if (skipNextRefresh) {
            skipNextRefresh = false
        } else {
            val yorvanaApplication = application as YorvanaApplication
            yorvanaApplication.billingManager.refresh()
            lifecycleScope.launch {
                yorvanaApplication.vehicleRepository.refresh()
                yorvanaApplication.recordRepository.refresh()
                yorvanaApplication.categoryRepository.refresh()
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        if (!isChangingConfigurations) {
            (application as YorvanaApplication).billingManager.endConnection()
        }
    }
}

@Composable
internal fun MainContent(application: YorvanaApplication) {
    val context = LocalContext.current
    var startDestination by remember { mutableStateOf<NavKey?>(null) }
    var crashLog by remember { mutableStateOf<String?>(null) }
    var showMigrationSuccess by remember { mutableStateOf(false) }

    val initialUri = remember { application.preferences.getVaultUriSync() }
    val preferences by
        application.preferences.preferences.collectAsStateWithLifecycle(
            initialValue = AppPreferences(vaultUriString = initialUri),
        )

    // Sync vault storage and navigation with DataStore preferences.
    LaunchedEffect(preferences.vaultUriString, crashLog) {
        if (crashLog != null) {
            return@LaunchedEffect
        }
        runCatching { application.applyVaultUri(preferences.vaultUriString) }

        val target =
            if (preferences.vaultUriString != null) {
                context.restoreSavedNavRoute() ?: VehicleList
            } else {
                Setup
            }
        startDestination = target
    }

    // Handle one-shot effects (migration success and initial crash check).
    LaunchedEffect(Unit) {
        launch {
            application.vaultMigrationEvents.collect {
                showMigrationSuccess = true
            }
        }

        val log = CrashReporter.read(application)
        if (log != null) {
            crashLog = log
            startDestination = null // Don't navigate if crashing
        }
    }

    if (showMigrationSuccess) {
        AlertDialog(
            onDismissRequest = { showMigrationSuccess = false },
            title = {
                Text(
                    text = stringResource(R.string.settings_vault_changed_title),
                    modifier = Modifier.testTag(TestTags.SETTINGS_VAULT_CHANGE_SUCCESS_TITLE),
                )
            },
            text = { Text(stringResource(R.string.settings_vault_changed_success)) },
            confirmButton = {
                TextButton(
                    onClick = { showMigrationSuccess = false },
                ) {
                    Text(stringResource(R.string.action_ok))
                }
            },
        )
    }

    if (crashLog != null) {
        val log = crashLog!!
        AlertDialog(
            onDismissRequest = {
                CrashReporter.clear(application)
                crashLog = null
            },
            title = { Text("Previous crash detected") },
            text = {
                Text(
                    text = log,
                    fontSize = 11.sp,
                    modifier =
                        Modifier
                            .fillMaxWidth()
                            .heightIn(max = 320.dp)
                            .verticalScroll(rememberScrollState()),
                )
            },
            confirmButton = {
                TextButton(onClick = {
                    val intent =
                        Intent(Intent.ACTION_SEND).apply {
                            type = "text/plain"
                            putExtra(Intent.EXTRA_SUBJECT, "Yorvana crash log")
                            putExtra(Intent.EXTRA_TEXT, log)
                        }
                    val chooser = Intent.createChooser(intent, "Share crash log")
                    if (context !is Activity) {
                        chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    }
                    try {
                        context.startActivity(chooser)
                    } catch (_: ActivityNotFoundException) {
                    }
                }) {
                    Text("Share")
                }
            },
            dismissButton = {
                TextButton(onClick = {
                    CrashReporter.clear(application)
                    crashLog = null
                }) {
                    Text("Dismiss")
                }
            },
        )
    }

    // Re-create AppNavGraph when the active vault changes so back stack entries
    // from the previous vault cannot point at stale record or vehicle IDs.
    startDestination?.let { dest ->
        key(dest, preferences.vaultUriString) {
            AppNavGraph(startDestination = dest)
        }
    }
}
