// Copyright (C) 2026 Jason M. Schwefel. All Rights Reserved.
package com.coldboreballisticsllc.scopedope.ui.screens.ammo

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.ContentCopy
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.coldboreballisticsllc.scopedope.domain.model.AmmoLoad
import com.coldboreballisticsllc.scopedope.ballistics.BcModel
import com.coldboreballisticsllc.scopedope.ui.components.ActionButton
import com.coldboreballisticsllc.scopedope.ui.components.NumericField
import com.coldboreballisticsllc.scopedope.ui.components.SectionDivider
import com.coldboreballisticsllc.scopedope.ui.session.SessionViewModel
import com.coldboreballisticsllc.scopedope.ui.theme.*

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AmmoScreen(
    onBack:    () -> Unit,
    sessionVm: SessionViewModel = hiltViewModel(),
    viewModel: AmmoViewModel    = hiltViewModel(),
) {
    val ammoList by viewModel.filteredAmmo.collectAsState()
    val calibers by viewModel.calibers.collectAsState()
    val query    by viewModel.searchQuery.collectAsState()

    // Dialog state: null = hidden, AmmoLoad = open (id==0 → create/copy, id!=0 → edit user)
    var editingAmmo     by remember { mutableStateOf<AmmoLoad?>(null) }
    var showAddDialog   by remember { mutableStateOf(false) }
    var confirmDeleteId by remember { mutableStateOf<Int?>(null) }

    Scaffold(
        topBar = {
            TopAppBar(
                title  = { Text("Select Ammo", style = MaterialTheme.typography.titleLarge) },
                navigationIcon = {
                    IconButton(onClick = onBack) {
                        Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
                    }
                },
                actions = {
                    IconButton(onClick = { showAddDialog = true }) {
                        Icon(Icons.Default.Add, contentDescription = "Add custom ammo",
                             tint = ColorAmber)
                    }
                },
                colors = TopAppBarDefaults.topAppBarColors(
                    containerColor    = ColorBackground,
                    titleContentColor = ColorTextPrimary,
                ),
            )
        },
        containerColor = ColorBackground,
    ) { padding ->
        Column(Modifier.padding(padding).fillMaxSize()) {
            OutlinedTextField(
                value         = query,
                onValueChange = viewModel::setQuery,
                label         = { Text("Search ammo") },
                singleLine    = true,
                modifier      = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
                colors        = OutlinedTextFieldDefaults.colors(
                    focusedBorderColor   = ColorAmber,
                    unfocusedBorderColor = ColorBorder,
                    focusedLabelColor    = ColorAmber,
                    cursorColor          = ColorAmber,
                ),
            )

            if (calibers.isNotEmpty()) {
                val selected by viewModel.selectedCaliber.collectAsState()
                CaliberChipRow(
                    calibers = calibers,
                    selected = selected,
                    onSelect = viewModel::selectCaliber,
                )
            }

            SectionDivider(Modifier.padding(horizontal = 16.dp))

            val userAmmo    = ammoList.filter { it.isUserDefined }
            val builtinAmmo = ammoList.filter { !it.isUserDefined }

            LazyColumn(Modifier.fillMaxSize()) {
                if (userAmmo.isNotEmpty()) {
                    item { AmmoSectionHeader("My Ammo") }
                    items(userAmmo, key = { "u${it.id}" }) { ammo ->
                        AmmoRow(
                            ammo         = ammo,
                            onClick      = { sessionVm.selectAmmo(ammo); onBack() },
                            onEditOrCopy = { editingAmmo = ammo },
                            onDelete     = { confirmDeleteId = ammo.id },
                        )
                        SectionDivider(Modifier.padding(horizontal = 16.dp))
                    }
                }
                if (builtinAmmo.isNotEmpty()) {
                    item { AmmoSectionHeader("Built-in") }
                    items(builtinAmmo, key = { "b${it.id}" }) { ammo ->
                        AmmoRow(
                            ammo         = ammo,
                            onClick      = { sessionVm.selectAmmo(ammo); onBack() },
                            onEditOrCopy = {
                                editingAmmo = ammo.copy(id = 0, name = "(Custom) ${ammo.name}", isUserDefined = false)
                            },
                            onDelete     = null,
                        )
                        SectionDivider(Modifier.padding(horizontal = 16.dp))
                    }
                }
            }
        }
    }

    // Create new from scratch
    if (showAddDialog) {
        AmmoEditDialog(
            initial   = null,
            onDismiss = { showAddDialog = false },
            onSave    = { load ->
                viewModel.addUserAmmo(load)
                showAddDialog = false
            },
        )
    }

    // Edit / copy dialog
    editingAmmo?.let { ammo ->
        AmmoEditDialog(
            initial   = ammo,
            onDismiss = { editingAmmo = null },
            onSave    = { load ->
                if (load.id == 0) viewModel.addUserAmmo(load)
                else              viewModel.updateUserAmmo(load)
                editingAmmo = null
            },
            onDelete  = if (ammo.id != 0) {{ confirmDeleteId = ammo.id; editingAmmo = null }} else null,
        )
    }

    // Delete confirmation
    confirmDeleteId?.let { id ->
        val target = ammoList.find { it.id == id }
        AlertDialog(
            onDismissRequest = { confirmDeleteId = null },
            title     = { Text("Delete Ammo?") },
            text      = { Text("Remove \"${target?.name ?: "this entry"}\"? This cannot be undone.") },
            confirmButton = {
                TextButton(
                    onClick = { viewModel.deleteUserAmmo(id); confirmDeleteId = null },
                    colors  = ButtonDefaults.textButtonColors(contentColor = ColorError),
                ) { Text("Delete") }
            },
            dismissButton = {
                TextButton(onClick = { confirmDeleteId = null }) { Text("Cancel") }
            },
            containerColor    = ColorSurface,
            titleContentColor = ColorTextPrimary,
            textContentColor  = ColorTextMuted,
        )
    }
}

@Composable
private fun AmmoSectionHeader(title: String) {
    Text(
        text     = title,
        style    = MaterialTheme.typography.labelMedium,
        color    = ColorTextMuted,
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 6.dp),
    )
}

@Composable
private fun CaliberChipRow(
    calibers: List<String>,
    selected: String?,
    onSelect: (String?) -> Unit,
) {
    LazyRow(
        modifier              = Modifier.padding(horizontal = 12.dp, vertical = 4.dp),
        horizontalArrangement = Arrangement.spacedBy(6.dp),
    ) {
        item {
            FilterChip(
                selected = selected == null,
                onClick  = { onSelect(null) },
                label    = { Text("All") },
                colors   = FilterChipDefaults.filterChipColors(
                    selectedContainerColor = ColorAmber,
                    selectedLabelColor     = ColorBackground,
                ),
            )
        }
        items(calibers) { cal ->
            FilterChip(
                selected = selected == cal,
                onClick  = { onSelect(cal) },
                label    = { Text(cal) },
                colors   = FilterChipDefaults.filterChipColors(
                    selectedContainerColor = ColorAmber,
                    selectedLabelColor     = ColorBackground,
                ),
            )
        }
    }
}

@Composable
private fun AmmoRow(
    ammo:        AmmoLoad,
    onClick:     () -> Unit,
    onEditOrCopy: () -> Unit,
    onDelete:    (() -> Unit)?,
) {
    var menuOpen by remember { mutableStateOf(false) }

    Row(
        modifier              = Modifier
            .fillMaxWidth()
            .clickable(onClick = onClick)
            .padding(start = 16.dp, top = 6.dp, bottom = 6.dp, end = 0.dp),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment     = Alignment.CenterVertically,
    ) {
        Column(Modifier.weight(1f)) {
            Text(
                text  = ammo.name,
                style = MaterialTheme.typography.bodyLarge,
                color = if (ammo.isUserDefined) ColorAmber else ColorTextPrimary,
            )
            Text(
                text  = ammo.caliber,
                style = MaterialTheme.typography.bodyMedium,
                color = ColorTextMuted,
            )
        }
        Column(horizontalAlignment = Alignment.End, modifier = Modifier.padding(end = 4.dp)) {
            Text(
                text  = "${ammo.muzzleVelFps} fps",
                style = MaterialTheme.typography.labelSmall,
                color = ColorDataDist,
            )
            Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(4.dp)) {
                Text(
                    text  = "BC ${ammo.bcModel.name} ${ammo.bc}",
                    style = MaterialTheme.typography.labelMedium,
                    color = if (ammo.bcModel == BcModel.G1) ColorAmber else ColorTextMuted,
                )
                if (ammo.bcModel == BcModel.G1) {
                    Text(
                        text  = "G1",
                        style = MaterialTheme.typography.labelSmall,
                        color = ColorBackground,
                        modifier = Modifier
                            .background(ColorAmber, shape = MaterialTheme.shapes.extraSmall)
                            .padding(horizontal = 4.dp, vertical = 1.dp),
                    )
                }
            }
        }
        Box {
            IconButton(onClick = { menuOpen = true }) {
                Icon(Icons.Default.MoreVert, contentDescription = "Options", tint = ColorTextMuted)
            }
            DropdownMenu(
                expanded          = menuOpen,
                onDismissRequest  = { menuOpen = false },
                containerColor    = ColorSurface,
            ) {
                if (ammo.isUserDefined) {
                    DropdownMenuItem(
                        text         = { Text("Edit", color = ColorTextPrimary) },
                        leadingIcon  = { Icon(Icons.Default.Edit, null, tint = ColorAmberDim) },
                        onClick      = { menuOpen = false; onEditOrCopy() },
                    )
                    if (onDelete != null) {
                        DropdownMenuItem(
                            text        = { Text("Delete", color = ColorError) },
                            leadingIcon = { Icon(Icons.Default.Delete, null, tint = ColorError) },
                            onClick     = { menuOpen = false; onDelete() },
                        )
                    }
                } else {
                    DropdownMenuItem(
                        text        = { Text("Copy to My Ammo", color = ColorTextPrimary) },
                        leadingIcon = { Icon(Icons.Default.ContentCopy, null, tint = ColorAmberDim) },
                        onClick     = { menuOpen = false; onEditOrCopy() },
                    )
                }
            }
        }
    }
}

@Composable
private fun AmmoEditDialog(
    initial:  AmmoLoad?,
    onDismiss: () -> Unit,
    onSave:    (AmmoLoad) -> Unit,
    onDelete:  (() -> Unit)? = null,
) {
    val isEdit = (initial?.id ?: 0) != 0

    var caliber          by remember { mutableStateOf(initial?.caliber ?: "") }
    var name             by remember { mutableStateOf(initial?.name ?: "") }
    var velFps           by remember { mutableStateOf(initial?.muzzleVelFps?.toString() ?: "") }
    var bcG7Str by remember {
        mutableStateOf(if (initial != null) {
            val v = if (initial.bcG7 != 0.0) initial.bcG7
                    else if (initial.bcModel == BcModel.G7) initial.bc else 0.0
            if (v != 0.0) "%.4g".format(v) else ""
        } else "")
    }
    var bcG1Str by remember {
        mutableStateOf(if (initial != null) {
            val v = if (initial.bcG1 != 0.0) initial.bcG1
                    else if (initial.bcModel == BcModel.G1) initial.bc else 0.0
            if (v != 0.0) "%.4g".format(v) else ""
        } else "")
    }
    var bcModel          by remember { mutableStateOf(initial?.bcModel ?: BcModel.G7) }
    var bulletWeightGrStr by remember {
        mutableStateOf(
            initial?.bulletWeightGr?.let { if (it == 0.0) "" else "%.4g".format(it) } ?: ""
        )
    }
    var mvSensStr by remember {
        mutableStateOf(
            initial?.mvSensitivityFpsPerF?.let { if (it == 0.0) "" else "%.4g".format(it) } ?: ""
        )
    }
    var mvRefTempStr by remember {
        mutableStateOf(
            initial?.mvReferenceTempF?.let { if (it == 59.0) "" else "%.4g".format(it) } ?: ""
        )
    }
    var formFactorStr by remember {
        mutableStateOf(
            initial?.formFactor?.let { if (it == 0.0) "" else "%.4g".format(it) } ?: ""
        )
    }
    var bulletDiamMmStr by remember {
        mutableStateOf(
            initial?.bulletDiameterMm?.let { if (it == 0.0) "" else "%.4g".format(it) } ?: ""
        )
    }
    var bulletLenMmStr by remember {
        mutableStateOf(
            initial?.bulletLengthMm?.let { if (it == 0.0) "" else "%.4g".format(it) } ?: ""
        )
    }

    AlertDialog(
        onDismissRequest = onDismiss,
        containerColor   = ColorSurface,
        title = {
            Text(
                text  = when {
                    isEdit              -> "Edit Ammo"
                    initial != null     -> "Copy to My Ammo"
                    else                -> "Add Custom Ammo"
                },
                color = ColorTextPrimary,
            )
        },
        text = {
            Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
                OutlinedTextField(
                    value         = caliber,
                    onValueChange = { caliber = it },
                    label         = { Text("Caliber") },
                    singleLine    = true,
                    colors        = ammoFieldColors(),
                )
                OutlinedTextField(
                    value         = name,
                    onValueChange = { name = it },
                    label         = { Text("Name") },
                    singleLine    = true,
                    colors        = ammoFieldColors(),
                )
                NumericField(
                    value         = velFps,
                    onValueChange = { velFps = it },
                    label         = "Muzzle velocity",
                    suffix        = "fps",
                )
                NumericField(
                    value         = bcG7Str,
                    onValueChange = { bcG7Str = it },
                    label         = "BC G7",
                )
                NumericField(
                    value         = bcG1Str,
                    onValueChange = { bcG1Str = it },
                    label         = "BC G1",
                )
                NumericField(
                    value         = bulletWeightGrStr,
                    onValueChange = { bulletWeightGrStr = it },
                    label         = "Bullet weight",
                    suffix        = "gr",
                )
                NumericField(
                    value         = mvSensStr,
                    onValueChange = { mvSensStr = it },
                    label         = "MV sensitivity",
                    suffix        = "fps/°F",
                )
                NumericField(
                    value         = mvRefTempStr,
                    onValueChange = { mvRefTempStr = it },
                    label         = "MV ref temp (blank = 59 °F)",
                    suffix        = "°F",
                )
                Text(
                    text  = "4DOF Parameters (optional)",
                    style = MaterialTheme.typography.labelMedium,
                    color = ColorTextMuted,
                )
                NumericField(
                    value         = formFactorStr,
                    onValueChange = { formFactorStr = it },
                    label         = "Form factor (FF)",
                )
                NumericField(
                    value         = bulletDiamMmStr,
                    onValueChange = { bulletDiamMmStr = it },
                    label         = "Bullet diameter",
                    suffix        = "mm",
                )
                NumericField(
                    value         = bulletLenMmStr,
                    onValueChange = { bulletLenMmStr = it },
                    label         = "Bullet length",
                    suffix        = "mm",
                )
                Row(verticalAlignment = Alignment.CenterVertically) {
                    Text(
                        "BC Model:",
                        color = ColorTextMuted,
                        style = MaterialTheme.typography.labelMedium,
                    )
                    Spacer(Modifier.width(8.dp))
                    BcModel.entries.forEach { m ->
                        Row(
                            verticalAlignment = Alignment.CenterVertically,
                            modifier          = Modifier.clickable { bcModel = m },
                        ) {
                            RadioButton(
                                selected = bcModel == m,
                                onClick  = { bcModel = m },
                                colors   = RadioButtonDefaults.colors(selectedColor = ColorAmber),
                            )
                            Text(m.name, color = ColorTextPrimary,
                                 style = MaterialTheme.typography.bodyMedium)
                        }
                    }
                }
                if (bcModel == BcModel.G1 && (velFps.toIntOrNull() ?: 0) > 1200) {
                    Text(
                        text  = "G1 BC is less accurate beyond 400 yd. Use G7 if available.",
                        style = MaterialTheme.typography.bodySmall,
                        color = ColorAmber,
                    )
                }
                // Offer a G7 estimate when G1 is entered but G7 is blank
                val g1Val = bcG1Str.toDoubleOrNull() ?: 0.0
                if (g1Val > 0.0 && bcG7Str.isBlank()) {
                    TextButton(
                        onClick  = { bcG7Str = "%.4g".format(g1Val / 2.5) },
                        modifier = Modifier.align(Alignment.Start),
                    ) {
                        Text("Estimate G7 from G1 (÷ 2.5 — rough)", color = ColorAmberDim,
                             style = MaterialTheme.typography.bodySmall)
                    }
                }

                // Delete (edit mode only)
                if (onDelete != null) {
                    Spacer(Modifier.height(4.dp))
                    TextButton(
                        onClick  = onDelete,
                        modifier = Modifier.fillMaxWidth(),
                        colors   = ButtonDefaults.textButtonColors(contentColor = ColorError),
                    ) {
                        Icon(Icons.Default.Delete, null, Modifier.size(16.dp))
                        Spacer(Modifier.width(6.dp))
                        Text("Delete this ammo entry")
                    }
                }
            }
        },
        confirmButton = {
            val vel        = velFps.toIntOrNull()
            val bcG7       = bcG7Str.toDoubleOrNull() ?: 0.0
            val bcG1       = bcG1Str.toDoubleOrNull() ?: 0.0
            val activeBC   = if (bcModel == BcModel.G7) bcG7 else bcG1
            val weight     = bulletWeightGrStr.toDoubleOrNull() ?: 0.0
            val mvSens     = mvSensStr.toDoubleOrNull() ?: 0.0
            val mvRef      = mvRefTempStr.toDoubleOrNull() ?: 59.0
            val formFactor = formFactorStr.toDoubleOrNull() ?: 0.0
            val bulletDiam = bulletDiamMmStr.toDoubleOrNull() ?: 0.0
            val bulletLen  = bulletLenMmStr.toDoubleOrNull() ?: 0.0
            val valid      = caliber.isNotBlank() && name.isNotBlank() && vel != null && activeBC > 0.0
            ActionButton(
                text    = if (isEdit) "Save" else if (initial != null) "Save Copy" else "Add",
                enabled = valid,
                onClick = {
                    onSave(AmmoLoad(
                        id                   = if (isEdit) initial!!.id else 0,
                        caliber              = caliber.trim(),
                        name                 = name.trim(),
                        muzzleVelFps         = vel!!,
                        bc                   = activeBC,
                        bcG1                 = bcG1,
                        bcG7                 = bcG7,
                        bcModel              = bcModel,
                        formFactor           = formFactor,
                        bulletDiameterMm     = bulletDiam,
                        bulletLengthMm       = bulletLen,
                        bulletWeightGr       = weight,
                        mvSensitivityFpsPerF = mvSens,
                        mvReferenceTempF     = mvRef,
                        isUserDefined        = true,
                    ))
                },
            )
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Cancel", color = ColorAmberDim)
            }
        },
    )
}

@Composable
private fun ammoFieldColors() = OutlinedTextFieldDefaults.colors(
    focusedBorderColor   = ColorAmber,
    unfocusedBorderColor = ColorBorder,
    focusedLabelColor    = ColorAmber,
    cursorColor          = ColorAmber,
)
