package com.atridad.magiccounter.ui

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.History
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.SnapshotStateList
import kotlinx.coroutines.delay
import androidx.compose.ui.Modifier
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.atridad.magiccounter.ui.screens.GameScreen
import com.atridad.magiccounter.ui.screens.SetupScreen
import com.atridad.magiccounter.ui.state.GameState
import androidx.lifecycle.viewmodel.compose.viewModel
import com.atridad.magiccounter.ui.settings.AppSettingsViewModel
import com.atridad.magiccounter.ui.settings.ThemeMode
import com.atridad.magiccounter.ui.settings.MatchRecord
import com.atridad.magiccounter.ui.theme.MagicCounterTheme
import com.atridad.magiccounter.ui.theme.CustomIcons
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items

private sealed class Screen {
    data object Home : Screen()
    data object Setup : Screen()
    data object Settings : Screen()
    data class Game(val matchId: String, val bootState: GameState? = null) : Screen()
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MagicCounterApp() {
    val screenStack: SnapshotStateList<Screen> = remember { mutableStateListOf(Screen.Home) }
    val settingsVm: AppSettingsViewModel = viewModel()
    val theme = settingsVm.themeMode.collectAsState()
    val historyState = settingsVm.matchHistory.collectAsState()



    MagicCounterTheme(themeMode = theme.value) {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("Magic Counter", style = MaterialTheme.typography.titleLarge) },
                navigationIcon = {
                    if (screenStack.size > 1) {
                        IconButton(onClick = { screenStack.removeAt(screenStack.lastIndex) }) {
                            Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
                        }
                    }
                },
                actions = {

                    IconButton(onClick = { screenStack.add(Screen.Settings) }) {
                        Icon(Icons.Default.Settings, contentDescription = "App settings")
                    }
                }
            )
        },
        floatingActionButton = {
            // Show FAB only on home screen when no active game is running
            val currentScreen = screenStack.last()
            if (currentScreen is Screen.Home && historyState.value.none { it.ongoing }) {
                FloatingActionButton(
                    onClick = { screenStack.add(Screen.Setup) }
                ) {
                    Icon(Icons.Default.PlayArrow, contentDescription = "Start new game")
                }
            }
        }
    ) { paddingValues ->
        val currentScreen = screenStack.last()
        BackHandler(enabled = screenStack.size > 1) { screenStack.removeAt(screenStack.lastIndex) }
        when (currentScreen) {
            is Screen.Home -> HomeScreen(
                modifier = Modifier
                    .padding(paddingValues)
                    .fillMaxWidth()
                    .fillMaxSize(),
                history = historyState.value,
                onResume = { record -> screenStack.add(Screen.Game(record.id)) },
                onStopGame = { record ->
                    // Stop the active game by marking it as stopped
                    val current = historyState.value
                    val idx = current.indexOfFirst { it.id == record.id }
                    if (idx >= 0) {
                        val stoppedState = current[idx].state.copy(stopped = true)
                        val updatedRec = current[idx].copy(
                            state = stoppedState,
                            lastUpdatedEpochMs = System.currentTimeMillis(),
                            ongoing = false,
                            winnerPlayerId = null
                        )
                        val newList = current.toMutableList().apply { set(idx, updatedRec) }
                        settingsVm.saveHistory(newList)
                    }
                },
                onDelete = { id ->
                    val newList = historyState.value.filterNot { it.id == id }
                    settingsVm.saveHistory(newList)
                }
            )
            is Screen.Setup -> SetupScreen(
                modifier = Modifier
                    .padding(paddingValues)
                    .fillMaxSize(),
                onStart = { name, state ->
                    // Check if there's already an active game
                    if (historyState.value.any { it.ongoing }) {
                        // Navigate back to home screen if a game is already active
                        screenStack.removeAt(screenStack.lastIndex)
                        return@SetupScreen
                    }

                    // Create and persist a new MatchRecord
                    val newId = java.util.UUID.randomUUID().toString()
                    val now = System.currentTimeMillis()
                    val record = MatchRecord(
                        id = newId,
                        name = name,
                        startedAtEpochMs = now,
                        lastUpdatedEpochMs = now,
                        ongoing = true,
                        winnerPlayerId = null,
                        state = state
                    )
                    val updated = historyState.value.toMutableList().apply { add(0, record) }
                    settingsVm.saveHistory(updated)
                    // Replace Setup with the new Game screen (pop then push)
                    if (screenStack.isNotEmpty()) screenStack.removeAt(screenStack.lastIndex)
                    screenStack.add(Screen.Game(newId, state))
                }
            )
            is Screen.Game -> {
                val id = currentScreen.matchId
                val bootState = currentScreen.bootState
                val record = historyState.value.firstOrNull { it.id == id }
                val stateForGame = record?.state ?: bootState
                if (stateForGame == null) {
                    screenStack.removeAt(screenStack.lastIndex)
                } else {
                    GameScreen(
                        modifier = Modifier
                            .padding(paddingValues)
                            .fillMaxSize(),
                        state = stateForGame,
                        matchName = record?.name ?: "Game",
                        startedAtEpochMs = record?.startedAtEpochMs ?: System.currentTimeMillis(),
                        onProgress = { updated ->
                            val current = historyState.value
                            val idx = current.indexOfFirst { it.id == id }
                            if (idx >= 0) {
                                val updatedRec = current[idx].copy(state = updated, lastUpdatedEpochMs = System.currentTimeMillis())
                                val newList = current.toMutableList().apply { set(idx, updatedRec) }
                                settingsVm.saveHistory(newList)
                            }
                        },
                        onWinner = { winnerId, finalState ->
                            val current = historyState.value
                            val idx = current.indexOfFirst { it.id == id }
                            if (idx >= 0) {
                                val updatedRec = current[idx].copy(
                                    state = finalState,
                                    lastUpdatedEpochMs = System.currentTimeMillis(),
                                    ongoing = false,
                                    winnerPlayerId = winnerId
                                )
                                val newList = current.toMutableList().apply { set(idx, updatedRec) }
                                settingsVm.saveHistory(newList)
                            }
                        },
                        onStop = { stoppedState ->
                            val current = historyState.value
                            val idx = current.indexOfFirst { it.id == id }
                            if (idx >= 0) {
                                val updatedRec = current[idx].copy(
                                    state = stoppedState,
                                    lastUpdatedEpochMs = System.currentTimeMillis(),
                                    ongoing = false,
                                    winnerPlayerId = null
                                )
                                val newList = current.toMutableList().apply { set(idx, updatedRec) }
                                settingsVm.saveHistory(newList)
                                // Navigate back to home screen
                                screenStack.removeAt(screenStack.lastIndex)
                            }
                        },
                        onDelete = {
                            // Delete the current game
                            val current = historyState.value
                            val newList = current.filterNot { it.id == id }
                            settingsVm.saveHistory(newList)
                            // Navigate back to home screen
                            screenStack.removeAt(screenStack.lastIndex)
                        }
                    )
                }
            }
            is Screen.Settings -> SettingsContent(
                modifier = Modifier
                    .padding(paddingValues)
                    .fillMaxSize(),
                current = theme.value,
                onSelect = { settingsVm.setTheme(it) }
            )
        }


    }
    }
}

@Composable
private fun SettingsContent(modifier: Modifier, current: ThemeMode, onSelect: (ThemeMode) -> Unit) {
    Column(
        modifier = modifier.padding(24.dp),
        verticalArrangement = Arrangement.spacedBy(24.dp)
    ) {
        Text(
            "Appearance",
            style = MaterialTheme.typography.headlineSmall,
            color = MaterialTheme.colorScheme.primary
        )

        Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
            Text(
                "Theme",
                style = MaterialTheme.typography.titleMedium,
                color = MaterialTheme.colorScheme.onSurface
            )
            Row(
                horizontalArrangement = Arrangement.spacedBy(12.dp),
                modifier = Modifier.fillMaxWidth()
            ) {
                ThemeMode.entries.forEach { mode ->
                    androidx.compose.material3.FilterChip(
                        selected = current == mode,
                        onClick = { onSelect(mode) },
                        label = { Text(mode.name) },
                        modifier = Modifier.weight(1f)
                    )
                }
            }
        }
    }
}

@Composable
private fun HomeScreen(
    modifier: Modifier,
    history: List<MatchRecord>,
    onResume: (MatchRecord) -> Unit,
    onStopGame: (MatchRecord) -> Unit,
    onDelete: (String) -> Unit
) {
    var pendingDeleteId by remember { mutableStateOf<String?>(null) }

    if (history.isEmpty()) {
        // Empty state
        androidx.compose.foundation.layout.Box(
            modifier = modifier.fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Column(
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.spacedBy(16.dp)
            ) {
                Icon(
                    Icons.Default.History,
                    contentDescription = "Empty history",
                    modifier = Modifier.size(64.dp),
                    tint = MaterialTheme.colorScheme.onSurfaceVariant
                )
                Text(
                    "No games yet",
                    style = MaterialTheme.typography.headlineSmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )
                Text(
                    "Start your first Magic: The Gathering game to begin tracking life totals and more.",
                    style = MaterialTheme.typography.bodyMedium,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    textAlign = androidx.compose.ui.text.style.TextAlign.Center
                )
            }
        }
    } else {
        // Games list
        LazyColumn(
            modifier = modifier.fillMaxSize(),
            contentPadding = androidx.compose.foundation.layout.PaddingValues(16.dp),
            verticalArrangement = Arrangement.spacedBy(12.dp)
        ) {
            // Active game at the top (if any)
            val activeGame = history.firstOrNull { it.ongoing }
            if (activeGame != null) {
                item {
                    androidx.compose.material3.Card(
                        modifier = Modifier.fillMaxWidth(),
                        colors = androidx.compose.material3.CardDefaults.cardColors(
                            containerColor = MaterialTheme.colorScheme.primary
                        ),
                        onClick = { onResume(activeGame) }
                    ) {
                        Row(
                            modifier = Modifier.fillMaxWidth().padding(16.dp),
                            horizontalArrangement = Arrangement.SpaceBetween,
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            Column(modifier = Modifier.weight(1f)) {
                                Text(
                                    "Active Game",
                                    style = MaterialTheme.typography.titleMedium,
                                    color = MaterialTheme.colorScheme.onPrimary
                                )
                                Text(
                                    activeGame.name,
                                    style = MaterialTheme.typography.bodyLarge,
                                    color = MaterialTheme.colorScheme.onPrimary
                                )
                                GameDuration(
                                    startTime = activeGame.startedAtEpochMs,
                                    color = MaterialTheme.colorScheme.onPrimary
                                )
                            }
                            androidx.compose.material3.FilledTonalIconButton(
                                onClick = { onStopGame(activeGame) },
                                modifier = Modifier.size(56.dp),
                                colors = androidx.compose.material3.IconButtonDefaults.filledTonalIconButtonColors(
                                    containerColor = MaterialTheme.colorScheme.error,
                                    contentColor = MaterialTheme.colorScheme.onError
                                )
                            ) {
                                Icon(
                                    CustomIcons.Stop(MaterialTheme.colorScheme.onError),
                                    contentDescription = "Stop game",
                                    modifier = Modifier.size(24.dp)
                                )
                            }
                        }
                    }
                }
            }

            // Past games section
            val pastGames = history.filter { !it.ongoing }
            items(pastGames, key = { it.id }) { rec ->
                androidx.compose.material3.Card(
                    modifier = Modifier.fillMaxWidth(),
                    colors = androidx.compose.material3.CardDefaults.cardColors(
                        containerColor = MaterialTheme.colorScheme.surfaceVariant
                    ),
                    onClick = { onResume(rec) }
                ) {
                    Row(
                        modifier = Modifier.fillMaxWidth().padding(16.dp),
                        horizontalArrangement = Arrangement.SpaceBetween,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Column(modifier = Modifier.weight(1f)) {
                            Text(
                                rec.name,
                                style = MaterialTheme.typography.bodyLarge,
                                color = MaterialTheme.colorScheme.onSurfaceVariant
                            )
                            val winnerId = rec.winnerPlayerId ?: rec.state.winnerPlayerId
                            val winnerName = winnerId?.let { wId ->
                                rec.state.players.find { it.id == wId }?.name
                            }
                            val statusText = when {
                                winnerName != null -> "Winner: $winnerName"
                                rec.state.stopped -> "Stopped"
                                else -> "Finished"
                            }
                            Text(
                                statusText,
                                style = MaterialTheme.typography.bodyMedium,
                                color = if (winnerName != null) Color(0xFF2E7D32) else MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f)
                            )
                        }
                        Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                            androidx.compose.material3.FilledTonalIconButton(
                                onClick = { onResume(rec) },
                                modifier = Modifier.size(40.dp),
                                colors = androidx.compose.material3.IconButtonDefaults.filledTonalIconButtonColors(
                                    containerColor = MaterialTheme.colorScheme.secondary,
                                    contentColor = MaterialTheme.colorScheme.onSecondary
                                )
                            ) {
                                Icon(
                                    Icons.Default.Visibility,
                                    contentDescription = "View match",
                                    modifier = Modifier.size(20.dp)
                                )
                            }
                            androidx.compose.material3.FilledTonalIconButton(
                                onClick = { pendingDeleteId = rec.id },
                                modifier = Modifier.size(40.dp),
                                colors = androidx.compose.material3.IconButtonDefaults.filledTonalIconButtonColors(
                                    containerColor = MaterialTheme.colorScheme.error,
                                    contentColor = MaterialTheme.colorScheme.onError
                                )
                            ) {
                                Icon(
                                    Icons.Default.Delete,
                                    contentDescription = "Delete",
                                    modifier = Modifier.size(20.dp)
                                )
                            }
                        }
                    }
                }
            }
        }

        // Confirm delete dialog
        val pending = history.firstOrNull { it.id == pendingDeleteId }
        if (pendingDeleteId != null && pending != null) {
            AlertDialog(
                onDismissRequest = { pendingDeleteId = null },
                title = { Text("Delete match?") },
                text = { Text("Are you sure you want to delete \"${pending.name}\"?") },
                confirmButton = {
                    TextButton(onClick = {
                        onDelete(pendingDeleteId!!)
                        pendingDeleteId = null
                    }) { Text("Delete") }
                },
                dismissButton = { TextButton(onClick = { pendingDeleteId = null }) { Text("Cancel") } }
            )
        }
    }
}

@Composable
private fun GameDuration(
    startTime: Long,
    color: Color
) {
    var duration by remember { mutableStateOf("") }

    LaunchedEffect(startTime) {
        while (true) {
            val elapsed = System.currentTimeMillis() - startTime
            val seconds = (elapsed / 1000).toInt()
            val minutes = seconds / 60
            val remainingSeconds = seconds % 60

            duration = when {
                minutes > 0 -> "Duration: ${minutes}m ${remainingSeconds}s"
                else -> "${remainingSeconds}s"
            }
            delay(1000)
        }
    }

    Text(
        text = duration,
        style = MaterialTheme.typography.bodyMedium,
        color = color.copy(alpha = 0.8f)
    )
}
