package com.harshmallow.pilottoolkit.ui.modules

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontFamily
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.components.*
import com.harshmallow.pilottoolkit.ui.theme.ToolkitTheme
import kotlin.math.floor

@Composable
fun CrewRestModule() {
    val colors = ToolkitTheme.colors

    var deptInput by rememberSaveable { mutableStateOf("") }
    var eteInput by rememberSaveable { mutableStateOf("") }
    var crew1 by rememberSaveable { mutableStateOf("") }
    var crew2 by rememberSaveable { mutableStateOf("") }
    var crew3 by rememberSaveable { mutableStateOf("") }
    var crew4 by rememberSaveable { mutableStateOf("") }
    var locked by rememberSaveable { mutableStateOf(false) }

    val HANDS_ON = 30 // minutes all crew on deck after departure and before arrival

    // Parse "HHMM" or "HH:MM" into total minutes — departure (0–23 hours)
    fun parseTime(str: String): Int? {
        val clean = str.replace(Regex("[^0-9]"), "")
        if (clean.length !in 3..4) return null
        val padded = clean.padStart(4, '0')
        val h = padded.substring(0, 2).toIntOrNull() ?: return null
        val m = padded.substring(2, 4).toIntOrNull() ?: return null
        if (h > 23 || m > 59) return null
        return h * 60 + m
    }

    // Parse ETE — supports HH:MM (with colon), HHMM (4 digits), or total minutes (1-3 digits)
    fun parseEte(str: String): Int? {
        val hasColon = str.contains(":")
        val clean = str.replace(Regex("[^0-9]"), "")
        if (clean.isEmpty()) return null
        if (hasColon) {
            val parts = str.split(":")
            if (parts.size != 2) return null
            val h = parts[0].toIntOrNull() ?: return null
            val m = parts[1].toIntOrNull() ?: return null
            if (m > 59) return null
            return h * 60 + m
        }
        if (clean.length <= 3) {
            val mins = clean.toIntOrNull() ?: return null
            return if (mins > 0) mins else null
        }
        if (clean.length == 4) {
            val h = clean.substring(0, 2).toIntOrNull() ?: return null
            val m = clean.substring(2, 4).toIntOrNull() ?: return null
            if (m > 59) return null
            return h * 60 + m
        }
        return null
    }

    // Format minutes to "HH:MMz" (wraps at 24h)
    fun fmtZulu(mins: Int): String {
        val wrapped = ((mins % 1440) + 1440) % 1440
        val h = wrapped / 60
        val m = wrapped % 60
        return "%02d:%02dz".format(h, m)
    }

    // Format duration in minutes to "Xh Ym (N min)"
    fun fmtDuration(mins: Int): String {
        val h = mins / 60
        val m = mins % 60
        val hm = when {
            h == 0 -> "$m min"
            m == 0 -> "${h}h"
            else -> "${h}h ${m}m"
        }
        return if (h > 0) "$hm ($mins min)" else hm
    }

    // Short duration format without total minutes
    fun fmtDurationShort(mins: Int): String {
        val h = mins / 60
        val m = mins % 60
        return when {
            h == 0 -> "$m min"
            m == 0 -> "${h}h"
            else -> "${h}h ${m}m"
        }
    }

    // Auto-format on focus loss — departure always formats, ETE only formats 4-digit HHMM
    fun formatDeptOnBlur(value: String): String {
        val clean = value.replace(Regex("[^0-9]"), "")
        return if (clean.length in 3..4) {
            val padded = clean.padStart(4, '0')
            padded.substring(0, 2) + ":" + padded.substring(2)
        } else value
    }

    fun formatEteOnBlur(value: String): String {
        val clean = value.replace(Regex("[^0-9]"), "")
        return if (!value.contains(":") && clean.length == 4) {
            clean.substring(0, 2) + ":" + clean.substring(2)
        } else value
    }

    fun handleTimeInput(raw: String): String {
        return raw.replace(Regex("[^0-9:]"), "").take(5)
    }

    val activeCrew = listOf(crew1, crew2, crew3, crew4).filter { it.trim().isNotEmpty() }
    val crewCount = activeCrew.size
    val deptMinutes = parseTime(deptInput)
    val eteMinutes = parseEte(eteInput)
    val restWindow = if (eteMinutes != null) eteMinutes - (HANDS_ON * 2) else null
    val canCalculate = deptMinutes != null && eteMinutes != null && crewCount >= 3 && (restWindow ?: 0) > 0

    data class RestSlot(val id: String, val restMinutes: Int, val begins: Int, val ends: Int)

    val results: List<RestSlot>? = if (canCalculate && deptMinutes != null && restWindow != null) {
        val perPerson = floor(restWindow.toDouble() / crewCount).toInt()
        val restStart = deptMinutes + HANDS_ON
        activeCrew.mapIndexed { i, id ->
            RestSlot(id, perPerson, restStart + (perPerson * i), restStart + (perPerson * (i + 1)))
        }
    } else null

    Column(verticalArrangement = Arrangement.spacedBy(18.dp)) {
        // Departure and ETE side by side
        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp)) {
            Column(Modifier.weight(1f)) {
                FieldLabel("Departure (Zulu)")
                OutlinedTextField(
                    value = deptInput,
                    onValueChange = { deptInput = handleTimeInput(it) },
                    placeholder = { Text("e.g. 14:30", fontSize = 14.sp, color = colors.textMuted) },
                    modifier = Modifier.fillMaxWidth()
                        .onFocusChanged { if (!it.isFocused) deptInput = formatDeptOnBlur(deptInput) },
                    singleLine = true, shape = RoundedCornerShape(8.dp),
                    readOnly = locked,
                    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,
                    )
                )
            }
            Column(Modifier.weight(1f)) {
                FieldLabel("ETE")
                OutlinedTextField(
                    value = eteInput,
                    onValueChange = { eteInput = handleTimeInput(it) },
                    placeholder = { Text("e.g. 10:30 or 630", fontSize = 14.sp, color = colors.textMuted) },
                    modifier = Modifier.fillMaxWidth()
                        .onFocusChanged { if (!it.isFocused) eteInput = formatEteOnBlur(eteInput) },
                    singleLine = true, shape = RoundedCornerShape(8.dp),
                    readOnly = locked,
                    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,
                    )
                )
            }
        }

        // Crew members header
        Text("CREW MEMBERS", fontSize = 11.sp, fontWeight = FontWeight.Bold,
            color = colors.textMuted, letterSpacing = 0.5.sp)

        // Crew fields in 2x2 grid
        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp)) {
            Column(Modifier.weight(1f)) {
                ToolkitTextField(value = crew1, onValueChange = { if (!locked) crew1 = it },
                    label = "Crew 1", placeholder = "ID or name")
            }
            Column(Modifier.weight(1f)) {
                ToolkitTextField(value = crew2, onValueChange = { if (!locked) crew2 = it },
                    label = "Crew 2", placeholder = "ID or name")
            }
        }
        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp)) {
            Column(Modifier.weight(1f)) {
                ToolkitTextField(value = crew3, onValueChange = { if (!locked) crew3 = it },
                    label = "Crew 3", placeholder = "ID or name")
            }
            Column(Modifier.weight(1f)) {
                ToolkitTextField(value = crew4, onValueChange = { if (!locked) crew4 = it },
                    label = "Crew 4", placeholder = "optional", sublabel = "optional")
            }
        }

        // Lock toggle + Clear button
        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp),
            verticalAlignment = Alignment.CenterVertically) {
            // Lock toggle
            Box(
                modifier = Modifier.clip(RoundedCornerShape(8.dp))
                    .background(if (locked) colors.accent.copy(alpha = 0.15f) else colors.surfaceAlt)
                    .clickable { locked = !locked }
                    .padding(horizontal = 14.dp, vertical = 10.dp)
            ) {
                Text(
                    if (locked) "\uD83D\uDD12 Locked" else "\uD83D\uDD13 Unlocked",
                    fontSize = 13.sp, fontWeight = FontWeight.SemiBold,
                    color = if (locked) colors.accent else colors.textMuted
                )
            }
            if (!locked) {
                ClearButton(onClick = {
                    deptInput = ""; eteInput = ""
                    crew1 = ""; crew2 = ""; crew3 = ""; crew4 = ""
                })
            }
        }

        // Warning: ETE too short
        if (eteMinutes != null && (restWindow ?: 0) <= 0 && crewCount >= 3) {
            Box(
                Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                    .background(colors.warningBg)
                    .border(1.dp, colors.warningBorder, RoundedCornerShape(8.dp))
                    .padding(12.dp)
            ) {
                Text("ETE of ${fmtDurationShort(eteMinutes)} is too short for rest periods. Minimum ETE is 1h 01m (60 minutes all-hands + at least 1 minute rest).",
                    fontSize = 13.sp, fontWeight = FontWeight.Medium, color = colors.warning, lineHeight = 20.sp)
            }
        }

        // Warning: not enough crew
        if (deptMinutes != null && eteMinutes != null && crewCount < 3) {
            Box(
                Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                    .background(colors.warningBg)
                    .border(1.dp, colors.warningBorder, RoundedCornerShape(8.dp))
                    .padding(12.dp)
            ) {
                Text("Enter at least 3 crew members for augmented rest calculation.",
                    fontSize = 13.sp, fontWeight = FontWeight.Medium, color = colors.warning, lineHeight = 20.sp)
            }
        }

        // Results
        if (results != null && deptMinutes != null && eteMinutes != null && restWindow != null) {
            ResultCard {
                // Flight summary
                Text("FLIGHT SUMMARY", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                    color = colors.textMuted, letterSpacing = 0.5.sp)
                Spacer(Modifier.height(8.dp))

                Text("Departure: ${fmtZulu(deptMinutes)}    ETE: ${fmtDuration(eteMinutes)}    Arrival: ${fmtZulu(deptMinutes + eteMinutes)}",
                    fontSize = 13.sp, color = colors.textSecondary, fontFamily = FontFamily.Monospace)
                Spacer(Modifier.height(4.dp))

                Text("All hands: ${fmtZulu(deptMinutes)}–${fmtZulu(deptMinutes + HANDS_ON)} & ${fmtZulu(deptMinutes + eteMinutes - HANDS_ON)}–${fmtZulu(deptMinutes + eteMinutes)}",
                    fontSize = 13.sp, color = colors.textSecondary)
                Spacer(Modifier.height(4.dp))

                Row {
                    Text("Rest window: ", fontSize = 13.sp, color = colors.textSecondary)
                    Text(fmtDuration(restWindow), fontSize = 13.sp, fontWeight = FontWeight.Bold, color = colors.text)
                    Text("    Per crew: ", fontSize = 13.sp, color = colors.textSecondary)
                    Text(fmtDuration(floor(restWindow.toDouble() / crewCount).toInt()),
                        fontSize = 13.sp, fontWeight = FontWeight.Bold, color = colors.text)
                }

                Spacer(Modifier.height(12.dp))
                HorizontalDivider(color = colors.border)
                Spacer(Modifier.height(12.dp))

                Text("REST SCHEDULE", fontSize = 11.sp, fontWeight = FontWeight.Bold,
                    color = colors.textMuted, letterSpacing = 0.5.sp)
                Spacer(Modifier.height(12.dp))

                results.forEachIndexed { i, slot ->
                    Row(
                        Modifier.fillMaxWidth().padding(vertical = 6.dp),
                        horizontalArrangement = Arrangement.SpaceBetween,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text(slot.id, fontSize = 14.sp, fontWeight = FontWeight.SemiBold, color = colors.text)
                        Column(horizontalAlignment = Alignment.End) {
                            Text("${fmtZulu(slot.begins)} – ${fmtZulu(slot.ends)}",
                                fontSize = 14.sp, fontWeight = FontWeight.SemiBold,
                                color = colors.accent, fontFamily = FontFamily.Monospace)
                            Text("(${fmtDurationShort(slot.restMinutes)})",
                                fontSize = 12.sp, color = colors.textMuted)
                        }
                    }
                    if (i < results.size - 1) {
                        HorizontalDivider(modifier = Modifier.padding(vertical = 4.dp), color = colors.border)
                    }
                }
            }
        }
    }
}
