package com.harshmallow.pilottoolkit.ui.modules

import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.harshmallow.pilottoolkit.ui.theme.ToolkitTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONArray
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.*

/* ─── Data Model ─── */
data class Passdown(
    val id: String = UUID.randomUUID().toString().take(12),
    val date: String = "", // yyyy-MM-dd
    val registration: String = "",
    val airport: String = "",
    val fbo: String = "",
    val fboPhone: String = "",
    val pic: String = "",
    val sic: String = "",
    val ca1: String = "",
    val oncomingPic: String = "",
    val oncomingSic: String = "",
    val maintenance: String = "",
    val narrative: String = "",
    val createdAt: String = "",
    val updatedAt: String = "",
    val lastSentAt: String = "",
)

/* ─── JSON Storage ─── */
private const val PREFS_NAME = "passdown_storage"
private const val KEY_PASSDOWNS = "passdowns_json"
private const val KEY_LOOKUPS = "lookups_json"
private const val KEY_RETENTION = "retention_months"

private fun getPrefs(context: Context) = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)

fun getRetentionMonths(context: Context): Int = getPrefs(context).getInt(KEY_RETENTION, 12)
fun saveRetentionMonths(context: Context, months: Int) = getPrefs(context).edit().putInt(KEY_RETENTION, months).apply()

private fun passdownToJson(p: Passdown): JSONObject = JSONObject().apply {
    put("id", p.id); put("date", p.date); put("registration", p.registration)
    put("airport", p.airport); put("fbo", p.fbo); put("fboPhone", p.fboPhone)
    put("pic", p.pic); put("sic", p.sic); put("ca1", p.ca1)
    put("oncomingPic", p.oncomingPic); put("oncomingSic", p.oncomingSic)
    put("maintenance", p.maintenance); put("narrative", p.narrative)
    put("createdAt", p.createdAt); put("updatedAt", p.updatedAt)
    if (p.lastSentAt.isNotEmpty()) put("lastSentAt", p.lastSentAt)
}

private fun jsonToPassdown(j: JSONObject): Passdown = Passdown(
    id = j.optString("id"), date = j.optString("date"), registration = j.optString("registration"),
    airport = j.optString("airport"), fbo = j.optString("fbo"), fboPhone = j.optString("fboPhone"),
    pic = j.optString("pic"), sic = j.optString("sic"), ca1 = j.optString("ca1"),
    oncomingPic = j.optString("oncomingPic"), oncomingSic = j.optString("oncomingSic"),
    maintenance = j.optString("maintenance"), narrative = j.optString("narrative"),
    createdAt = j.optString("createdAt"), updatedAt = j.optString("updatedAt"),
    lastSentAt = j.optString("lastSentAt", ""),
)

fun getAllPassdowns(context: Context): List<Passdown> {
    val json = getPrefs(context).getString(KEY_PASSDOWNS, "[]") ?: "[]"
    val arr = JSONArray(json)
    return (0 until arr.length()).map { jsonToPassdown(arr.getJSONObject(it)) }
        .sortedByDescending { it.createdAt }
}

fun savePassdownRecord(context: Context, p: Passdown) {
    val all = getAllPassdowns(context).toMutableList()
    val idx = all.indexOfFirst { it.id == p.id }
    if (idx >= 0) all[idx] = p else all.add(0, p)
    val arr = JSONArray()
    all.forEach { arr.put(passdownToJson(it)) }
    getPrefs(context).edit().putString(KEY_PASSDOWNS, arr.toString()).apply()
}

fun deletePassdownRecord(context: Context, id: String) {
    val all = getAllPassdowns(context).filter { it.id != id }
    val arr = JSONArray()
    all.forEach { arr.put(passdownToJson(it)) }
    getPrefs(context).edit().putString(KEY_PASSDOWNS, arr.toString()).apply()
}

fun purgeOldPassdowns(context: Context, months: Int): Int {
    if (months <= 0) return 0
    val cal = Calendar.getInstance().apply { add(Calendar.MONTH, -months) }
    val cutoff = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US).format(cal.time)
    val all = getAllPassdowns(context)
    val keep = all.filter { it.createdAt.isEmpty() || it.createdAt >= cutoff }
    val purged = all.size - keep.size
    if (purged > 0) {
        val arr = JSONArray()
        keep.forEach { arr.put(passdownToJson(it)) }
        getPrefs(context).edit().putString(KEY_PASSDOWNS, arr.toString()).apply()
    }
    return purged
}

/* ─── Lookups ─── */
fun getLookups(context: Context, type: String): List<String> {
    val json = getPrefs(context).getString(KEY_LOOKUPS, "{}") ?: "{}"
    val obj = JSONObject(json)
    val arr = obj.optJSONArray(type) ?: return emptyList()
    return (0 until arr.length()).map { arr.getString(it) }.sorted()
}

fun addLookup(context: Context, type: String, value: String) {
    if (value.isBlank()) return
    val json = getPrefs(context).getString(KEY_LOOKUPS, "{}") ?: "{}"
    val obj = JSONObject(json)
    val arr = obj.optJSONArray(type) ?: JSONArray()
    val existing = (0 until arr.length()).map { arr.getString(it) }.toMutableSet()
    existing.add(value.trim())
    obj.put(type, JSONArray(existing.toList()))
    getPrefs(context).edit().putString(KEY_LOOKUPS, obj.toString()).apply()
}

fun deleteLookup(context: Context, type: String, value: String) {
    val json = getPrefs(context).getString(KEY_LOOKUPS, "{}") ?: "{}"
    val obj = JSONObject(json)
    val arr = obj.optJSONArray(type) ?: return
    val remaining = (0 until arr.length()).map { arr.getString(it) }.filter { it != value }
    obj.put(type, JSONArray(remaining))
    getPrefs(context).edit().putString(KEY_LOOKUPS, obj.toString()).apply()
}

fun clearAllLookups(context: Context) {
    getPrefs(context).edit().putString(KEY_LOOKUPS, "{}").apply()
}

/* ─── Phone Formatting ─── */
fun formatPhone(raw: String): String {
    val digits = raw.replace(Regex("\\D"), "")
    return if (digits.length == 10) "(${digits.substring(0, 3)}) ${digits.substring(3, 6)}-${digits.substring(6)}"
    else raw
}

fun phoneToTel(formatted: String): String {
    val digits = formatted.replace(Regex("\\D"), "")
    return when {
        digits.length == 10 -> "+1$digits"
        formatted.trim().startsWith("+") -> "+$digits"
        else -> digits
    }
}

/* ─── Text Export ─── */
fun formatDatePilot(dateStr: String): String {
    val months = arrayOf("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
    val parts = dateStr.split("-")
    if (parts.size != 3) return dateStr
    return "${parts[2].toIntOrNull() ?: parts[2]} ${months.getOrElse((parts[1].toIntOrNull() ?: 1) - 1) { "?" }} ${parts[0]}"
}

fun passdownToPlainText(p: Passdown): String {
    val lines = mutableListOf(
        "PASSDOWN — ${formatDatePilot(p.date).uppercase()}",
        "REG: ${p.registration.ifEmpty { "—" }} | APT: ${p.airport.ifEmpty { "—" }} | FBO: ${p.fbo.ifEmpty { "—" }}",
    )
    if (p.fboPhone.isNotEmpty()) lines.add("FBO Phone: ${p.fboPhone}")
    lines.add("")
    lines.add("CREW:")
    lines.add("  PIC: ${p.pic.ifEmpty { "—" }}")
    lines.add("  SIC: ${p.sic.ifEmpty { "—" }}")
    if (p.ca1.isNotEmpty()) lines.add("  Lead CA: ${p.ca1}")
    if (p.oncomingPic.isNotEmpty() || p.oncomingSic.isNotEmpty()) {
        lines.add("")
        lines.add("ONCOMING CREW:")
        if (p.oncomingPic.isNotEmpty()) lines.add("  PIC: ${p.oncomingPic}")
        if (p.oncomingSic.isNotEmpty()) lines.add("  SIC: ${p.oncomingSic}")
    }
    lines.add("")
    lines.add("MAINTENANCE STATUS:")
    lines.add(p.maintenance.ifEmpty { "(none)" })
    lines.add("")
    lines.add("NARRATIVE:")
    lines.add(p.narrative.ifEmpty { "(none)" })
    return lines.joinToString("\n")
}

fun todayDate(): String {
    val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.US)
    sdf.timeZone = TimeZone.getDefault()
    return sdf.format(Date())
}

data class ImportResult(val imported: Int, val skipped: Int, val total: Int)

fun parsePtzStream(inputStream: java.io.InputStream): List<Passdown> {
    val json = java.util.zip.GZIPInputStream(inputStream).use { gz ->
        gz.bufferedReader(Charsets.UTF_8).readText()
    }
    val arr = JSONArray(json)
    return (0 until arr.length())
        .map { jsonToPassdown(arr.getJSONObject(it)) }
        .filter { it.id.isNotBlank() }
}

fun importSelectedPassdownRecords(context: Context, selected: List<Passdown>): Int {
    var imported = 0
    for (p in selected) {
        savePassdownRecord(context, p)
        if (p.registration.isNotBlank()) addLookup(context, "registration", p.registration)
        if (p.airport.isNotBlank()) addLookup(context, "airport", p.airport)
        if (p.fbo.isNotBlank()) addLookup(context, "fbo", p.fbo)
        listOf(p.pic, p.sic, p.ca1, p.oncomingPic, p.oncomingSic).forEach { v ->
            if (v.isNotBlank()) addLookup(context, "crew", v)
        }
        imported++
    }
    return imported
}

fun importPassdownPtz(context: Context, inputStream: java.io.InputStream): ImportResult {
    val entries = parsePtzStream(inputStream)
    val existingIds = getAllPassdowns(context).map { it.id }.toSet()
    val toImport = entries.filter { !existingIds.contains(it.id) }
    val imported = importSelectedPassdownRecords(context, toImport)
    return ImportResult(imported, entries.size - imported, entries.size)
}

/* ─── Autocomplete Field ─── */
@Composable
fun AutocompleteField(
    value: String, onValueChange: (String) -> Unit,
    options: List<String>, placeholder: String,
    uppercase: Boolean = false,
    keyboardType: KeyboardType = KeyboardType.Email,
    onBlurTransform: ((String) -> String)? = null
) {
    val colors = ToolkitTheme.colors
    var expanded by remember { mutableStateOf(false) }
    var hasFocus by remember { mutableStateOf(false) }
    val filtered = options.filter { it.contains(value, ignoreCase = true) }
    val showDropdown = expanded && hasFocus && filtered.isNotEmpty() && value.isNotEmpty()

    Column {
        OutlinedTextField(
            value = value,
            onValueChange = { v ->
                onValueChange(if (uppercase) v.uppercase() else v)
                expanded = true
            },
            placeholder = { Text(placeholder, fontSize = 13.sp, color = colors.textMuted) },
            modifier = Modifier.fillMaxWidth()
                .onFocusChanged { fs ->
                    hasFocus = fs.isFocused
                    if (fs.isFocused) expanded = true
                    if (!fs.isFocused) {
                        expanded = false
                        if (onBlurTransform != null && value.isNotBlank()) {
                            onValueChange(onBlurTransform(value))
                        }
                    }
                },
            singleLine = true,
            shape = RoundedCornerShape(8.dp),
            keyboardOptions = KeyboardOptions(keyboardType = keyboardType),
            colors = OutlinedTextFieldDefaults.colors(
                focusedBorderColor = colors.accent, unfocusedBorderColor = colors.border,
                focusedTextColor = colors.text, unfocusedTextColor = colors.text,
                cursorColor = colors.accent,
                focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent,
            ),
            textStyle = LocalTextStyle.current.copy(fontSize = 13.sp, fontWeight = FontWeight.Medium),
        )
        if (showDropdown) {
            Card(
                modifier = Modifier.fillMaxWidth(),
                shape = RoundedCornerShape(0.dp, 0.dp, 8.dp, 8.dp),
                colors = CardDefaults.cardColors(containerColor = colors.surface),
                elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
                border = androidx.compose.foundation.BorderStroke(1.dp, colors.border)
            ) {
                Column(modifier = Modifier.heightIn(max = 160.dp).verticalScroll(rememberScrollState())) {
                    filtered.take(6).forEach { opt ->
                        Text(
                            text = opt, fontSize = 13.sp, color = colors.text,
                            modifier = Modifier.fillMaxWidth()
                                .clickable { onValueChange(opt); expanded = false }
                                .padding(horizontal = 12.dp, vertical = 10.dp)
                        )
                    }
                }
            }
        }
    }
}

/* ═══════════════════════════════════
   PassdownModule Composable
   ═══════════════════════════════════ */
@Composable
fun PassdownModule(importUri: android.net.Uri? = null, onImportConsumed: () -> Unit = {}) {
    val colors = ToolkitTheme.colors
    val context = LocalContext.current
    val scope = rememberCoroutineScope()
    val clipboardManager = LocalClipboardManager.current

    var view by remember { mutableStateOf("form") } // "form" | "history" | "detail" | "manage" | "import"
    var passdowns by remember { mutableStateOf(getAllPassdowns(context)) }
    var lookupCache by remember { mutableStateOf(mapOf<String, List<String>>()) }
    var selectedPassdown by remember { mutableStateOf<Passdown?>(null) }
    var editingId by remember { mutableStateOf<String?>(null) }
    var saveStatus by remember { mutableStateOf<Pair<String, String>?>(null) } // type, msg
    var copyStatus by remember { mutableStateOf(false) }
    var importStatus by remember { mutableStateOf<Pair<String, String>?>(null) }
    var importPreview by remember { mutableStateOf<List<Passdown>?>(null) }
    var importPreviewExistingIds by remember { mutableStateOf(emptySet<String>()) }
    var importSelected by remember { mutableStateOf(emptySet<String>()) }
    var confirmClearAll by remember { mutableStateOf(false) }
    var filterReg by remember { mutableStateOf("") }
    var filterDateFrom by remember { mutableStateOf("") }
    var filterDateTo by remember { mutableStateOf("") }

    // File picker for .ptz import
    val importLauncher = androidx.activity.compose.rememberLauncherForActivityResult(
        contract = androidx.activity.result.contract.ActivityResultContracts.GetContent()
    ) { uri ->
        if (uri == null) return@rememberLauncherForActivityResult
        try {
            val inputStream = context.contentResolver.openInputStream(uri) ?: throw Exception("Cannot read file")
            val entries = parsePtzStream(inputStream)
            if (entries.isEmpty()) {
                importStatus = "error" to "No valid passdowns found in file."
                return@rememberLauncherForActivityResult
            }
            val existingIds = getAllPassdowns(context).map { it.id }.toSet()
            importPreview = entries
            importPreviewExistingIds = existingIds
            importSelected = entries.filter { !existingIds.contains(it.id) }.map { it.id }.toSet()
            view = "import"
        } catch (e: Exception) {
            importStatus = "error" to "Import failed: ${e.message}"
        }
    }

    // Form fields
    var reg by remember { mutableStateOf("") }
    var date by remember { mutableStateOf(todayDate()) }
    var airport by remember { mutableStateOf("") }
    var fbo by remember { mutableStateOf("") }
    var fboPhone by remember { mutableStateOf("") }
    var pic by remember { mutableStateOf("") }
    var sic by remember { mutableStateOf("") }
    var ca1 by remember { mutableStateOf("") }
    var oncomingPic by remember { mutableStateOf("") }
    var oncomingSic by remember { mutableStateOf("") }
    var maintenance by remember { mutableStateOf("") }
    var narrative by remember { mutableStateOf("") }

    fun refreshData() {
        passdowns = getAllPassdowns(context)
        lookupCache = mapOf(
            "registration" to getLookups(context, "registration"),
            "airport" to getLookups(context, "airport"),
            "fbo" to getLookups(context, "fbo"),
            "crew" to getLookups(context, "crew"),
        )
    }

    fun clearForm() {
        reg = ""; date = todayDate(); airport = ""; fbo = ""; fboPhone = ""
        pic = ""; sic = ""; ca1 = ""
        oncomingPic = ""; oncomingSic = ""
        maintenance = ""; narrative = ""; editingId = null; saveStatus = null
    }

    LaunchedEffect(Unit) { refreshData() }

    // Clear save status after delay
    LaunchedEffect(saveStatus) {
        if (saveStatus != null) {
            kotlinx.coroutines.delay(2500)
            saveStatus = null
        }
    }

    LaunchedEffect(copyStatus) {
        if (copyStatus) {
            kotlinx.coroutines.delay(2000)
            copyStatus = false
        }
    }

    LaunchedEffect(importStatus) {
        if (importStatus != null) {
            kotlinx.coroutines.delay(4000)
            importStatus = null
        }
    }

    // Handle incoming .ptz file from intent
    LaunchedEffect(importUri) {
        if (importUri != null) {
            try {
                val inputStream = context.contentResolver.openInputStream(importUri)
                    ?: throw Exception("Cannot read file")
                val entries = parsePtzStream(inputStream)
                if (entries.isEmpty()) {
                    view = "history"
                    importStatus = "error" to "No valid passdowns found in file."
                } else {
                    val existingIds = getAllPassdowns(context).map { it.id }.toSet()
                    importPreview = entries
                    importPreviewExistingIds = existingIds
                    importSelected = entries.filter { !existingIds.contains(it.id) }.map { it.id }.toSet()
                    view = "import"
                }
            } catch (e: Exception) {
                view = "history"
                importStatus = "error" to "Import failed: ${e.message}"
            }
            onImportConsumed()
        }
    }

    fun handleSave() {
        if (reg.isBlank() && date.isBlank()) {
            saveStatus = "error" to "Registration and date are required."
            return
        }
        val now = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US).format(Date())
        val existing = if (editingId != null) passdowns.find { it.id == editingId } else null
        val record = Passdown(
            id = editingId ?: UUID.randomUUID().toString().take(12),
            date = date, registration = reg.trim().uppercase(), airport = airport.trim().uppercase(),
            fbo = fbo.trim(), fboPhone = fboPhone.trim(),
            pic = pic.trim(), sic = sic.trim(), ca1 = ca1.trim(),
            oncomingPic = oncomingPic.trim(), oncomingSic = oncomingSic.trim(),
            maintenance = maintenance.trim(), narrative = narrative.trim(),
            createdAt = existing?.createdAt ?: now, updatedAt = now,
            lastSentAt = existing?.lastSentAt ?: "",
        )
        savePassdownRecord(context, record)
        listOf(record.registration to "registration", record.airport to "airport", record.fbo to "fbo").forEach { (v, t) ->
            if (v.isNotBlank()) addLookup(context, t, v)
        }
        listOf(record.pic, record.sic, record.ca1, record.oncomingPic, record.oncomingSic).forEach { v ->
            if (v.isNotBlank()) addLookup(context, "crew", v)
        }
        refreshData()
        saveStatus = "success" to if (editingId != null) "Passdown updated." else "Passdown saved."
        if (editingId == null) clearForm()
        editingId = null
    }

    fun handleEdit(p: Passdown) {
        reg = p.registration; date = p.date; airport = p.airport
        fbo = p.fbo; fboPhone = p.fboPhone
        pic = p.pic; sic = p.sic; ca1 = p.ca1
        oncomingPic = p.oncomingPic; oncomingSic = p.oncomingSic
        maintenance = p.maintenance; narrative = p.narrative
        editingId = p.id
        view = "form"
    }

    fun handleDelete(id: String) {
        deletePassdownRecord(context, id)
        refreshData()
        if (selectedPassdown?.id == id) selectedPassdown = null
        view = "history"
    }

    fun handleSend(p: Passdown) {
        try {
            // Stamp lastSentAt and persist
            val sentAt = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US).apply {
                timeZone = TimeZone.getTimeZone("UTC")
            }.format(Date())
            val updated = p.copy(lastSentAt = sentAt)
            savePassdownRecord(context, updated)
            passdowns = getAllPassdowns(context)
            selectedPassdown = updated

            // Generate .ptz attachment
            val json = JSONArray().apply { put(passdownToJson(updated)) }.toString(2)
            val reg = updated.registration.ifEmpty { "NOREG" }.replace(Regex("[^A-Za-z0-9]"), "")
            val date = updated.date.ifEmpty { "nodate" }.replace(Regex("[^0-9-]"), "")
            val filename = "PASSDOWN_${reg}_${date}.ptz"
            val file = java.io.File(context.cacheDir, filename)
            java.util.zip.GZIPOutputStream(file.outputStream()).use { gz ->
                gz.write(json.toByteArray(Charsets.UTF_8))
            }
            val fileUri = androidx.core.content.FileProvider.getUriForFile(
                context, "${context.packageName}.fileprovider", file
            )
            // Unified intent: .ptz attachment + plain text body + recipients
            val to = listOf(updated.pic).filter { it.contains("@") }.toTypedArray()
            val cc = listOf(updated.sic, updated.ca1, updated.oncomingPic, updated.oncomingSic)
                .filter { it.contains("@") }.toTypedArray()
            val subject = "Passdown — ${formatDatePilot(updated.date)} — ${updated.registration.ifEmpty { "N/A" }}"
            val body = passdownToPlainText(updated)
            val intent = Intent(Intent.ACTION_SEND).apply {
                type = "message/rfc822"
                putExtra(Intent.EXTRA_STREAM, fileUri)
                putExtra(Intent.EXTRA_TITLE, filename)
                putExtra(Intent.EXTRA_EMAIL, to)
                putExtra(Intent.EXTRA_CC, cc)
                putExtra(Intent.EXTRA_SUBJECT, subject)
                putExtra(Intent.EXTRA_TEXT, body)
                clipData = android.content.ClipData.newUri(context.contentResolver, filename, fileUri)
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            }
            context.startActivity(Intent.createChooser(intent, "Send Passdown"))
        } catch (_: Exception) { }
    }

    var showStalePrompt by remember { mutableStateOf(false) }

    fun handleSendWithStaleCheck(p: Passdown) {
        val today = todayDate()
        if (p.date.isNotEmpty() && p.date != today) {
            showStalePrompt = true
        } else {
            handleSend(p)
        }
    }

    fun handleUpdateDateAndSend(p: Passdown) {
        val today = todayDate()
        val now = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US).format(Date())
        val updated = p.copy(date = today, updatedAt = now)
        savePassdownRecord(context, updated)
        passdowns = getAllPassdowns(context)
        selectedPassdown = updated
        showStalePrompt = false
        handleSend(updated)
    }

    fun exportBatchPtz(batch: List<Passdown>) {
        try {
            val json = JSONArray().apply {
                batch.forEach { put(passdownToJson(it)) }
            }.toString(2)
            val regs = batch.map { it.registration }.filter { it.isNotEmpty() }.distinct()
            val regPart = if (regs.size == 1) regs[0].replace(Regex("[^A-Za-z0-9]"), "") else "${batch.size}records"
            val dates = batch.map { it.date }.filter { it.isNotEmpty() }.sorted()
            val datePart = if (dates.size >= 2) "${dates.first()}_${dates.last()}" else dates.firstOrNull() ?: "nodate"
            val filename = "PASSDOWN_BATCH_${regPart}_${datePart}.ptz"
            val file = java.io.File(context.cacheDir, filename)
            java.util.zip.GZIPOutputStream(file.outputStream()).use { gz ->
                gz.write(json.toByteArray(Charsets.UTF_8))
            }
            val fileUri = androidx.core.content.FileProvider.getUriForFile(
                context, "${context.packageName}.fileprovider", file
            )
            val intent = Intent(Intent.ACTION_SEND).apply {
                type = "application/octet-stream"
                putExtra(Intent.EXTRA_STREAM, fileUri)
                putExtra(Intent.EXTRA_TITLE, filename)
                clipData = android.content.ClipData.newUri(context.contentResolver, filename, fileUri)
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            }
            context.startActivity(Intent.createChooser(intent, "Export Batch Passdown"))
        } catch (_: Exception) { }
    }

    /* ── FORM VIEW ── */
    if (view == "form") {
        Column(verticalArrangement = Arrangement.spacedBy(14.dp)) {
            // Header
            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically) {
                Text(
                    if (editingId != null) "✎ Editing" else "New Passdown",
                    fontSize = 13.sp, fontWeight = FontWeight.SemiBold,
                    color = if (editingId != null) colors.warning else colors.textMuted
                )
                TextButton(onClick = { view = "history" }) {
                    Text("History (${passdowns.size})", fontSize = 13.sp,
                        fontWeight = FontWeight.SemiBold, color = colors.accent)
                }
            }

            // Crew (Email)
            Column(
                Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                    .background(colors.surfaceAlt).border(1.dp, colors.border, RoundedCornerShape(8.dp))
                    .padding(14.dp),
                verticalArrangement = Arrangement.spacedBy(8.dp)
            ) {
                Text("CREW (EMAIL)", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                    color = colors.textMuted, letterSpacing = 0.5.sp)
                AutocompleteField(value = pic, onValueChange = { pic = it },
                    options = lookupCache["crew"] ?: emptyList(), placeholder = "pic@company.com")
                AutocompleteField(value = sic, onValueChange = { sic = it },
                    options = lookupCache["crew"] ?: emptyList(), placeholder = "sic@company.com")
                AutocompleteField(value = ca1, onValueChange = { ca1 = it },
                    options = lookupCache["crew"] ?: emptyList(), placeholder = "leadca@company.com")
            }

            // Registration + Date
            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp)) {
                Column(Modifier.weight(1f)) {
                    Text("REGISTRATION", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                        color = colors.textMuted, letterSpacing = 0.5.sp, modifier = Modifier.padding(bottom = 6.dp))
                    AutocompleteField(value = reg, onValueChange = { reg = it },
                        options = lookupCache["registration"] ?: emptyList(),
                        placeholder = "e.g. N292ME", uppercase = true, keyboardType = KeyboardType.Text)
                }
                Column(Modifier.weight(1f)) {
                    Text("DATE", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                        color = colors.textMuted, letterSpacing = 0.5.sp, modifier = Modifier.padding(bottom = 6.dp))
                    OutlinedTextField(
                        value = date, onValueChange = { date = it },
                        placeholder = { Text("yyyy-mm-dd", fontSize = 13.sp, color = colors.textMuted) },
                        modifier = Modifier.fillMaxWidth(), singleLine = true,
                        shape = RoundedCornerShape(8.dp),
                        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                        colors = OutlinedTextFieldDefaults.colors(
                            focusedBorderColor = colors.accent, unfocusedBorderColor = colors.border,
                            focusedTextColor = colors.text, unfocusedTextColor = colors.text,
                            cursorColor = colors.accent,
                            focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent,
                        ),
                        textStyle = LocalTextStyle.current.copy(fontSize = 13.sp, fontWeight = FontWeight.Medium),
                    )
                }
            }

            // Airport + FBO
            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp)) {
                Column(Modifier.weight(2f)) {
                    Text("AIRPORT (ICAO)", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                        color = colors.textMuted, letterSpacing = 0.5.sp, modifier = Modifier.padding(bottom = 6.dp))
                    AutocompleteField(value = airport, onValueChange = { airport = it },
                        options = lookupCache["airport"] ?: emptyList(),
                        placeholder = "e.g. KPTK", uppercase = true, keyboardType = KeyboardType.Text)
                }
                Column(Modifier.weight(3f)) {
                    Text("FBO", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                        color = colors.textMuted, letterSpacing = 0.5.sp, modifier = Modifier.padding(bottom = 6.dp))
                    AutocompleteField(value = fbo, onValueChange = { fbo = it },
                        options = lookupCache["fbo"] ?: emptyList(),
                        placeholder = "e.g. Aerodynamics, Inc.", keyboardType = KeyboardType.Text)
                }
            }

            // FBO Phone
            Column {
                Text("FBO PHONE", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                    color = colors.textMuted, letterSpacing = 0.5.sp, modifier = Modifier.padding(bottom = 6.dp))
                OutlinedTextField(
                    value = fboPhone, onValueChange = { fboPhone = it },
                    placeholder = { Text("e.g. (248) 666-3500", fontSize = 13.sp, color = colors.textMuted) },
                    modifier = Modifier.fillMaxWidth().onFocusChanged { fs ->
                        if (!fs.isFocused && fboPhone.isNotBlank()) fboPhone = formatPhone(fboPhone.trim())
                    },
                    singleLine = true, shape = RoundedCornerShape(8.dp),
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone),
                    colors = OutlinedTextFieldDefaults.colors(
                        focusedBorderColor = colors.accent, unfocusedBorderColor = colors.border,
                        focusedTextColor = colors.text, unfocusedTextColor = colors.text,
                        cursorColor = colors.accent,
                        focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent,
                    ),
                    textStyle = LocalTextStyle.current.copy(fontSize = 13.sp, fontWeight = FontWeight.Medium),
                )
            }

            // Maintenance Status
            Column {
                Text("MAINTENANCE STATUS", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                    color = colors.textMuted, letterSpacing = 0.5.sp, modifier = Modifier.padding(bottom = 2.dp))
                Text("Oil levels, MELs, nuisances, open items", fontSize = 11.sp,
                    color = colors.textMuted, modifier = Modifier.padding(bottom = 6.dp))
                OutlinedTextField(
                    value = maintenance, onValueChange = { maintenance = it },
                    placeholder = { Text("Oil: _/_/_\nMEL: \nNuisances: ", fontSize = 13.sp, color = colors.textMuted) },
                    modifier = Modifier.fillMaxWidth().heightIn(min = 100.dp),
                    shape = RoundedCornerShape(8.dp), maxLines = 8,
                    colors = OutlinedTextFieldDefaults.colors(
                        focusedBorderColor = colors.accent, unfocusedBorderColor = colors.border,
                        focusedTextColor = colors.text, unfocusedTextColor = colors.text,
                        cursorColor = colors.accent,
                        focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent,
                    ),
                    textStyle = LocalTextStyle.current.copy(fontSize = 13.sp, lineHeight = 20.sp),
                )
            }

            // Narrative
            Column {
                Text("PASSDOWN NARRATIVE", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                    color = colors.textMuted, letterSpacing = 0.5.sp, modifier = Modifier.padding(bottom = 6.dp))
                OutlinedTextField(
                    value = narrative, onValueChange = { narrative = it },
                    placeholder = { Text("Anything else the next crew should know...", fontSize = 13.sp, color = colors.textMuted) },
                    modifier = Modifier.fillMaxWidth().heightIn(min = 100.dp),
                    shape = RoundedCornerShape(8.dp), maxLines = 8,
                    colors = OutlinedTextFieldDefaults.colors(
                        focusedBorderColor = colors.accent, unfocusedBorderColor = colors.border,
                        focusedTextColor = colors.text, unfocusedTextColor = colors.text,
                        cursorColor = colors.accent,
                        focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent,
                    ),
                    textStyle = LocalTextStyle.current.copy(fontSize = 13.sp, lineHeight = 20.sp),
                )
            }

            // Oncoming Crew (Email)
            Column(
                Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                    .background(colors.surfaceAlt).border(1.dp, colors.border, RoundedCornerShape(8.dp))
                    .padding(14.dp),
                verticalArrangement = Arrangement.spacedBy(8.dp)
            ) {
                Text("ONCOMING CREW (EMAIL)", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                    color = colors.textMuted, letterSpacing = 0.5.sp)
                AutocompleteField(value = oncomingPic, onValueChange = { oncomingPic = it },
                    options = lookupCache["crew"] ?: emptyList(), placeholder = "oncoming_pic@company.com")
                AutocompleteField(value = oncomingSic, onValueChange = { oncomingSic = it },
                    options = lookupCache["crew"] ?: emptyList(), placeholder = "oncoming_sic@company.com")
            }

            // Save / Clear
            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(10.dp),
                verticalAlignment = Alignment.CenterVertically) {
                Button(
                    onClick = { handleSave() },
                    colors = ButtonDefaults.buttonColors(containerColor = colors.accent),
                    shape = RoundedCornerShape(6.dp),
                    contentPadding = PaddingValues(horizontal = 20.dp, vertical = 10.dp)
                ) {
                    Text(if (editingId != null) "Update Passdown" else "Save Passdown",
                        fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = Color.White)
                }
                TextButton(onClick = { clearForm() }) {
                    Text("Clear", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colors.accent)
                }
            }
            if (saveStatus != null) {
                Text(saveStatus!!.second, fontSize = 12.sp, fontWeight = FontWeight.SemiBold,
                    color = if (saveStatus!!.first == "error") colors.danger else colors.accent)
            }
        }
    }

    /* ── HISTORY VIEW ── */
    else if (view == "history") {
        val hasFilters = filterReg.isNotEmpty() || filterDateFrom.isNotEmpty() || filterDateTo.isNotEmpty()
        val filtered = passdowns.filter { p ->
            if (filterReg.isNotEmpty() && !p.registration.equals(filterReg, ignoreCase = true)) return@filter false
            if (filterDateFrom.isNotEmpty() && p.date < filterDateFrom) return@filter false
            if (filterDateTo.isNotEmpty() && p.date > filterDateTo) return@filter false
            true
        }
        Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically) {
                Text("${passdowns.size} passdown${if (passdowns.size != 1) "s" else ""} saved",
                    fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colors.textMuted)
                Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                    TextButton(onClick = { importLauncher.launch("*/*") }) {
                        Text("Import", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colors.accent)
                    }
                    TextButton(onClick = { clearForm(); view = "form" }) {
                        Text("+ New", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colors.accent)
                    }
                }
            }

            // Filter bar
            if (passdowns.isNotEmpty()) {
                Column(
                    Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                        .background(colors.surfaceAlt).border(1.dp, colors.border, RoundedCornerShape(8.dp))
                        .padding(12.dp),
                    verticalArrangement = Arrangement.spacedBy(8.dp)
                ) {
                    AutocompleteField(value = filterReg, onValueChange = { filterReg = it },
                        options = lookupCache["registration"] ?: emptyList(),
                        placeholder = "Registration (all)", uppercase = true, keyboardType = KeyboardType.Text)
                    Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                        OutlinedTextField(
                            value = filterDateFrom, onValueChange = { filterDateFrom = it },
                            placeholder = { Text("From (yyyy-mm-dd)", fontSize = 12.sp, color = colors.textMuted) },
                            modifier = Modifier.weight(1f),
                            textStyle = androidx.compose.ui.text.TextStyle(fontSize = 12.sp, color = colors.text),
                            singleLine = true,
                            shape = RoundedCornerShape(8.dp),
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedBorderColor = colors.accent,
                                unfocusedBorderColor = colors.border,
                                cursorColor = colors.accent,
                            )
                        )
                        OutlinedTextField(
                            value = filterDateTo, onValueChange = { filterDateTo = it },
                            placeholder = { Text("To (yyyy-mm-dd)", fontSize = 12.sp, color = colors.textMuted) },
                            modifier = Modifier.weight(1f),
                            textStyle = androidx.compose.ui.text.TextStyle(fontSize = 12.sp, color = colors.text),
                            singleLine = true,
                            shape = RoundedCornerShape(8.dp),
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedBorderColor = colors.accent,
                                unfocusedBorderColor = colors.border,
                                cursorColor = colors.accent,
                            )
                        )
                    }
                    if (hasFilters) {
                        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween,
                            verticalAlignment = Alignment.CenterVertically) {
                            Text(buildString {
                                append("${filtered.size} result${if (filtered.size != 1) "s" else ""}")
                                if (filterReg.isNotEmpty()) append(" for ${filterReg.uppercase()}")
                                if (filterDateFrom.isNotEmpty()) append(" from ${formatDatePilot(filterDateFrom)}")
                                if (filterDateTo.isNotEmpty()) append(" to ${formatDatePilot(filterDateTo)}")
                            }, fontSize = 12.sp, color = colors.textMuted)
                            Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
                                if (filtered.isNotEmpty()) {
                                    TextButton(onClick = { exportBatchPtz(filtered) }) {
                                        Text("Export (${filtered.size})", fontSize = 12.sp,
                                            fontWeight = FontWeight.SemiBold, color = colors.accent)
                                    }
                                }
                                TextButton(onClick = { filterReg = ""; filterDateFrom = ""; filterDateTo = "" }) {
                                    Text("Clear", fontSize = 12.sp, fontWeight = FontWeight.SemiBold, color = colors.accent)
                                }
                            }
                        }
                    }
                }
            }

            if (importStatus != null) {
                Box(Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                    .background(if (importStatus!!.first == "error") colors.dangerBg else colors.resultBg)
                    .border(1.dp,
                        if (importStatus!!.first == "error") colors.dangerBorder else colors.resultBorder,
                        RoundedCornerShape(8.dp))
                    .padding(10.dp, 10.dp)) {
                    Text(importStatus!!.second, fontSize = 12.sp, fontWeight = FontWeight.SemiBold,
                        color = if (importStatus!!.first == "error") colors.danger else colors.accent)
                }
            }

            if (filtered.isEmpty()) {
                Box(Modifier.fillMaxWidth().padding(32.dp), contentAlignment = Alignment.Center) {
                    Text(
                        if (hasFilters) "No passdowns match the current filters."
                        else "No passdowns yet. Create your first one.",
                        fontSize = 13.sp, color = colors.textMuted
                    )
                }
            } else {
                val today = todayDate()
                val yesterday = run {
                    val cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
                    cal.add(Calendar.DAY_OF_MONTH, -1)
                    String.format("%04d-%02d-%02d", cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH))
                }
                filtered.forEach { p ->
                    val age = when (p.date) { today -> "today"; yesterday -> "yesterday"; else -> "older" }
                    val regColor = when (age) { "today" -> colors.accent; "yesterday" -> colors.textSecondary; else -> colors.textMuted }
                    val regWeight = if (age == "today") FontWeight.Bold else FontWeight.SemiBold
                    val itemAlpha = if (age == "older") 0.6f else 1f
                    val leftBorderColor = when (age) { "today" -> colors.accent; "yesterday" -> colors.textMuted.copy(alpha = 0.25f); else -> colors.border }
                    Box(
                        Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                            .border(1.dp, colors.border, RoundedCornerShape(8.dp))
                            .drawWithContent {
                                drawContent()
                                drawRect(
                                    color = leftBorderColor,
                                    topLeft = androidx.compose.ui.geometry.Offset.Zero,
                                    size = androidx.compose.ui.geometry.Size(3.dp.toPx(), size.height)
                                )
                            }
                            .clickable { selectedPassdown = p; showStalePrompt = false; view = "detail" }
                            .padding(start = 6.dp, top = 12.dp, end = 12.dp, bottom = 12.dp)
                    ) {
                        Column(modifier = Modifier.alpha(itemAlpha)) {
                            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween,
                                verticalAlignment = Alignment.CenterVertically) {
                                Text(p.registration.ifEmpty { "—" }, fontSize = 14.sp,
                                    fontWeight = regWeight, color = regColor, letterSpacing = 0.3.sp)
                                Row(horizontalArrangement = Arrangement.spacedBy(6.dp),
                                    verticalAlignment = Alignment.CenterVertically) {
                                    if (p.lastSentAt.isNotEmpty()) {
                                        Text("✉", fontSize = 10.sp, color = colors.textMuted)
                                    }
                                    Text(formatDatePilot(p.date), fontSize = 12.sp, color = colors.textMuted)
                                }
                            }
                            Spacer(Modifier.height(4.dp))
                            Text(
                                listOfNotNull(
                                    p.airport.ifEmpty { null }, p.fbo.ifEmpty { null },
                                    if (p.pic.isNotEmpty()) "PIC: ${p.pic}" else null
                                ).joinToString(" · ").ifEmpty { "No location" },
                                fontSize = 12.sp, color = colors.textSecondary
                            )
                        }
                    }
                }
            }

            // Manage link
            Box(Modifier.fillMaxWidth().padding(top = 12.dp), contentAlignment = Alignment.Center) {
                TextButton(onClick = { confirmClearAll = false; view = "manage" }) {
                    Text("Manage Saved Entries", fontSize = 12.sp, color = colors.textMuted,
                        fontWeight = FontWeight.Normal)
                }
            }
        }
    }

    /* ── IMPORT PREVIEW VIEW ── */
    else if (view == "import" && importPreview != null) {
        val entries = importPreview!!
        val existingIds = importPreviewExistingIds
        val selectedCount = importSelected.size
        val dupCount = entries.count { existingIds.contains(it.id) }

        fun handleImportCommit() {
            val toImport = entries.filter { importSelected.contains(it.id) }
            if (toImport.isEmpty()) {
                importPreview = null; importSelected = emptySet(); view = "history"
                return
            }
            val imported = importSelectedPassdownRecords(context, toImport)
            passdowns = getAllPassdowns(context)
            lookupCache = mapOf(
                "registration" to getLookups(context, "registration"),
                "airport" to getLookups(context, "airport"),
                "fbo" to getLookups(context, "fbo"),
                "crew" to getLookups(context, "crew"),
            )
            importPreview = null; importSelected = emptySet()
            importStatus = "success" to "Imported $imported passdown${if (imported != 1) "s" else ""}."
            view = "history"
        }

        Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
            // Nav
            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically) {
                TextButton(onClick = { importPreview = null; view = "history" }) {
                    Text("← Cancel", fontSize = 12.sp, fontWeight = FontWeight.SemiBold, color = colors.accent)
                }
                Text("Import Preview", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colors.textMuted)
            }

            // Summary
            Box(Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                .background(colors.surfaceAlt).border(1.dp, colors.border, RoundedCornerShape(8.dp))
                .padding(12.dp)) {
                Text(buildString {
                    append("${entries.size} passdown${if (entries.size != 1) "s" else ""} in file")
                    if (dupCount > 0) append(" · $dupCount duplicate${if (dupCount != 1) "s" else ""}")
                    append(" · $selectedCount selected")
                }, fontSize = 12.sp, color = colors.textSecondary)
            }

            // Select all / none
            Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                TextButton(
                    onClick = { importSelected = entries.map { it.id }.toSet() },
                    enabled = importSelected.size < entries.size
                ) {
                    Text("Select All", fontSize = 11.sp, fontWeight = FontWeight.SemiBold, color = colors.accent)
                }
                TextButton(
                    onClick = { importSelected = emptySet() },
                    enabled = importSelected.isNotEmpty()
                ) {
                    Text("Select None", fontSize = 11.sp, fontWeight = FontWeight.SemiBold, color = colors.accent)
                }
            }

            // Entry list
            entries.forEach { p ->
                val isDup = existingIds.contains(p.id)
                val checked = importSelected.contains(p.id)
                Row(
                    Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                        .border(1.dp,
                            if (isDup) colors.warning.copy(alpha = 0.25f) else colors.border,
                            RoundedCornerShape(8.dp))
                        .background(if (checked) colors.accent.copy(alpha = 0.04f) else colors.surface)
                        .clickable {
                            importSelected = if (checked) importSelected - p.id else importSelected + p.id
                        }
                        .padding(10.dp)
                        .alpha(if (checked) 1f else 0.5f),
                    horizontalArrangement = Arrangement.spacedBy(10.dp),
                    verticalAlignment = Alignment.Top
                ) {
                    Checkbox(
                        checked = checked,
                        onCheckedChange = { isChecked ->
                            importSelected = if (isChecked) importSelected + p.id else importSelected - p.id
                        },
                        colors = CheckboxDefaults.colors(checkedColor = colors.accent),
                        modifier = Modifier.size(20.dp)
                    )
                    Column(Modifier.weight(1f)) {
                        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween,
                            verticalAlignment = Alignment.CenterVertically) {
                            Text(p.registration.ifEmpty { "—" }, fontSize = 13.sp,
                                fontWeight = FontWeight.Bold, color = colors.accent, letterSpacing = 0.3.sp)
                            Row(horizontalArrangement = Arrangement.spacedBy(6.dp),
                                verticalAlignment = Alignment.CenterVertically) {
                                if (isDup) {
                                    Text("DUPLICATE", fontSize = 10.sp, fontWeight = FontWeight.SemiBold, color = colors.warning)
                                }
                                Text(formatDatePilot(p.date), fontSize = 12.sp, color = colors.textMuted)
                            }
                        }
                        Text(
                            listOfNotNull(
                                p.airport.ifEmpty { null }, p.fbo.ifEmpty { null },
                                if (p.pic.isNotEmpty()) "PIC: ${p.pic}" else null
                            ).joinToString(" · ").ifEmpty { "No location" },
                            fontSize = 11.sp, color = colors.textSecondary
                        )
                    }
                }
            }

            // Action buttons
            Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
                Button(
                    onClick = { handleImportCommit() },
                    enabled = selectedCount > 0,
                    colors = ButtonDefaults.buttonColors(containerColor = colors.accent),
                    shape = RoundedCornerShape(6.dp),
                    contentPadding = PaddingValues(horizontal = 20.dp, vertical = 10.dp)
                ) {
                    Text(
                        "Import${if (selectedCount > 0) " ($selectedCount)" else ""}",
                        fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = Color.White
                    )
                }
                TextButton(onClick = { importPreview = null; view = "history" }) {
                    Text("Cancel", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colors.accent)
                }
            }
        }
    }

    /* ── MANAGE LOOKUPS VIEW ── */
    else if (view == "manage") {
        val categories = listOf("registration" to "Registration", "airport" to "Airport", "fbo" to "FBO", "crew" to "Crew")

        Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically) {
                TextButton(onClick = { view = "history" }) {
                    Text("← History", fontSize = 12.sp, fontWeight = FontWeight.SemiBold, color = colors.accent)
                }
                Text("Manage Saved Entries", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colors.textMuted)
            }

            categories.forEach { (key, label) ->
                val items = lookupCache[key] ?: emptyList()
                Column(
                    Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                        .background(colors.surfaceAlt).border(1.dp, colors.border, RoundedCornerShape(8.dp))
                        .padding(12.dp),
                    verticalArrangement = Arrangement.spacedBy(4.dp)
                ) {
                    Text("$label (${items.size})", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                        color = colors.textMuted, letterSpacing = 0.5.sp, modifier = Modifier.padding(bottom = 4.dp))
                    if (items.isEmpty()) {
                        Text("No entries", fontSize = 12.sp, color = colors.textMuted)
                    } else {
                        items.forEach { item ->
                            Row(
                                Modifier.fillMaxWidth().clip(RoundedCornerShape(4.dp))
                                    .background(colors.surface).padding(horizontal = 8.dp, vertical = 6.dp),
                                horizontalArrangement = Arrangement.SpaceBetween,
                                verticalAlignment = Alignment.CenterVertically
                            ) {
                                Text(item, fontSize = 13.sp, color = colors.text)
                                TextButton(
                                    onClick = { deleteLookup(context, key, item); refreshData() },
                                    contentPadding = PaddingValues(0.dp)
                                ) {
                                    Text("✕", fontSize = 12.sp, fontWeight = FontWeight.SemiBold, color = colors.danger)
                                }
                            }
                        }
                    }
                }
            }

            HorizontalDivider(color = colors.border)

            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center,
                verticalAlignment = Alignment.CenterVertically) {
                if (!confirmClearAll) {
                    TextButton(onClick = { confirmClearAll = true }) {
                        Text("Clear All Saved Entries", fontSize = 12.sp, color = colors.danger)
                    }
                } else {
                    TextButton(onClick = { clearAllLookups(context); refreshData(); confirmClearAll = false }) {
                        Text("Confirm Clear All", fontSize = 12.sp, fontWeight = FontWeight.Bold, color = colors.danger)
                    }
                    TextButton(onClick = { confirmClearAll = false }) {
                        Text("Cancel", fontSize = 12.sp, color = colors.textMuted)
                    }
                }
            }
        }
    }

    /* ── DETAIL VIEW ── */
    else if (view == "detail" && selectedPassdown != null) {
        val p = selectedPassdown!!
        var showDeleteConfirm by remember { mutableStateOf(false) }

        Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
            // Nav
            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically) {
                TextButton(onClick = { view = "history" }) {
                    Text("← History", fontSize = 12.sp, fontWeight = FontWeight.SemiBold, color = colors.accent)
                }
                Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                    TextButton(onClick = {
                        clipboardManager.setText(AnnotatedString(passdownToPlainText(p)))
                        copyStatus = true
                    }) {
                        Text(if (copyStatus) "✓ Copied" else "Copy", fontSize = 12.sp,
                            fontWeight = FontWeight.SemiBold, color = colors.accent)
                    }
                    TextButton(onClick = { handleSendWithStaleCheck(p) }) {
                        Text("Send", fontSize = 12.sp, fontWeight = FontWeight.SemiBold, color = colors.accent)
                    }
                }
            }

            // Stale date prompt
            if (showStalePrompt) {
                Box(Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                    .background(colors.warningBg).border(1.dp, colors.warning.copy(alpha = 0.25f), RoundedCornerShape(8.dp))
                    .padding(14.dp)
                ) {
                    Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
                        Text("⚠ Passdown date (${formatDatePilot(p.date)}) is not today.",
                            fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colors.warning)
                        Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                            TextButton(onClick = { showStalePrompt = false; handleSend(p) }) {
                                Text("Send Anyway", fontSize = 12.sp, fontWeight = FontWeight.SemiBold, color = colors.warning)
                            }
                            Button(
                                onClick = { handleUpdateDateAndSend(p) },
                                colors = ButtonDefaults.buttonColors(containerColor = colors.accent),
                                shape = RoundedCornerShape(6.dp),
                                contentPadding = PaddingValues(horizontal = 14.dp, vertical = 8.dp)
                            ) {
                                Text("Update to Today & Send", fontSize = 12.sp, fontWeight = FontWeight.SemiBold)
                            }
                            TextButton(onClick = { showStalePrompt = false }) {
                                Text("Cancel", fontSize = 12.sp, color = colors.textMuted)
                            }
                        }
                    }
                }
            }

            // Last sent timestamp
            if (p.lastSentAt.isNotEmpty()) {
                val sentFmt = try {
                    val parsed = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US).apply {
                        timeZone = TimeZone.getTimeZone("UTC")
                    }.parse(p.lastSentAt)
                    SimpleDateFormat("d MMM yyyy, HHmm", Locale.US).apply {
                        timeZone = TimeZone.getTimeZone("UTC")
                    }.format(parsed!!) + "Z"
                } catch (_: Exception) { p.lastSentAt }
                Text("Sent $sentFmt", fontSize = 11.sp, color = colors.textMuted)
            }

            // Header card
            Box(Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                .background(colors.resultBg).border(1.dp, colors.resultBorder, RoundedCornerShape(8.dp))
                .padding(16.dp)
            ) {
                Column {
                    Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween,
                        verticalAlignment = Alignment.CenterVertically) {
                        Text(p.registration.ifEmpty { "—" }, fontSize = 18.sp,
                            fontWeight = FontWeight.Bold, color = colors.accent, letterSpacing = 0.4.sp)
                        Text(formatDatePilot(p.date), fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colors.text)
                    }
                    Spacer(Modifier.height(8.dp))
                    Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
                        if (p.airport.isNotEmpty()) Text("Airport: ${p.airport}", fontSize = 13.sp, color = colors.textSecondary)
                        if (p.fbo.isNotEmpty()) Text("FBO: ${p.fbo}", fontSize = 13.sp, color = colors.textSecondary)
                        if (p.fboPhone.isNotEmpty()) {
                            Row(modifier = Modifier.clickable {
                                val intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:${phoneToTel(p.fboPhone)}"))
                                try { context.startActivity(intent) } catch (_: Exception) { }
                            }) {
                                Text("Phone: ", fontSize = 13.sp, color = colors.textSecondary)
                                Text(p.fboPhone, fontSize = 13.sp, color = colors.accent, fontWeight = FontWeight.Medium)
                            }
                        }
                    }
                    Spacer(Modifier.height(8.dp))
                    // Crew
                    Text("PIC: ${p.pic.ifEmpty { "—" }}", fontSize = 13.sp, color = colors.textSecondary)
                    Text("SIC: ${p.sic.ifEmpty { "—" }}", fontSize = 13.sp, color = colors.textSecondary)
                    if (p.ca1.isNotEmpty()) Text("Lead CA: ${p.ca1}", fontSize = 13.sp, color = colors.textSecondary)
                    // Oncoming crew
                    if (p.oncomingPic.isNotEmpty() || p.oncomingSic.isNotEmpty()) {
                        Spacer(Modifier.height(6.dp))
                        Text("ONCOMING CREW", fontSize = 10.sp, fontWeight = FontWeight.Bold,
                            color = colors.textMuted, letterSpacing = 0.5.sp)
                        if (p.oncomingPic.isNotEmpty()) Text("PIC: ${p.oncomingPic}", fontSize = 13.sp, color = colors.textSecondary)
                        if (p.oncomingSic.isNotEmpty()) Text("SIC: ${p.oncomingSic}", fontSize = 13.sp, color = colors.textSecondary)
                    }
                }
            }

            // Maintenance
            if (p.maintenance.isNotEmpty()) {
                Column {
                    Text("MAINTENANCE STATUS", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                        color = colors.textMuted, letterSpacing = 0.5.sp, modifier = Modifier.padding(bottom = 4.dp))
                    Text(p.maintenance, fontSize = 13.sp, color = colors.text, lineHeight = 20.sp)
                }
            }

            // Narrative
            if (p.narrative.isNotEmpty()) {
                Column {
                    Text("NARRATIVE", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                        color = colors.textMuted, letterSpacing = 0.5.sp, modifier = Modifier.padding(bottom = 4.dp))
                    Text(p.narrative, fontSize = 13.sp, color = colors.text, lineHeight = 20.sp)
                }
            }

            HorizontalDivider(color = colors.border)

            // Edit / Delete
            Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
                TextButton(onClick = { handleEdit(p) }) {
                    Text("Edit", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colors.accent)
                }
                if (!showDeleteConfirm) {
                    TextButton(onClick = { showDeleteConfirm = true }) {
                        Text("Delete", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colors.danger)
                    }
                } else {
                    TextButton(onClick = { handleDelete(p.id) }) {
                        Text("Confirm Delete", fontSize = 13.sp, fontWeight = FontWeight.Bold, color = colors.danger)
                    }
                    TextButton(onClick = { showDeleteConfirm = false }) {
                        Text("Cancel", fontSize = 13.sp, color = colors.textMuted)
                    }
                }
            }
        }
    }
}
