package com.harshmallow.pilottoolkit.ui.modules

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.ui.Modifier
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
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.*

@Composable
fun CrosswindModule() {
    val colors = ToolkitTheme.colors
    var runwayInput by remember { mutableStateOf("") }
    var windInput by remember { mutableStateOf("") }
    var gustInput by remember { mutableStateOf("") }

    // Wind input: accept raw digits while typing, format on focus loss
    fun handleWindInput(raw: String) {
        // Strip non-digits and slash, cap at 5 digits
        windInput = raw.replace(Regex("[^0-9]"), "").take(5)
    }

    fun formatWindInput() {
        val digits = windInput.replace(Regex("[^0-9]"), "")
        windInput = if (digits.length > 3) {
            digits.substring(0, 3) + "/" + digits.substring(3)
        } else {
            digits
        }
    }

    // Parse direction and speed from "xxxxx" or "xxx/xx"
    fun parseWind(): Pair<Double, Double>? {
        val clean = windInput.replace("/", "")
        if (clean.length >= 4) {
            val dir = clean.substring(0, 3).toDoubleOrNull()
            val spd = clean.substring(3).toDoubleOrNull()
            if (dir != null && spd != null) return Pair(dir, spd)
        }
        return null
    }

    val rwyRaw = runwayInput.toDoubleOrNull()
    val wind = parseWind()
    val gustSpd = gustInput.toDoubleOrNull()

    data class XWindResult(
        val crosswind: Int, val headwind: Int, val isTailwind: Boolean,
        val gustCrosswind: Int? = null, val gustHeadwind: Int? = null, val gustIsTailwind: Boolean = false
    )

    val results: XWindResult? = if (rwyRaw != null && wind != null) {
        val (windDir, windSpd) = wind
        val rwyHeading = if (rwyRaw <= 36) rwyRaw * 10 else rwyRaw
        val angleRad = ((windDir - rwyHeading) * PI) / 180.0
        val xw = abs(windSpd * sin(angleRad))
        val hw = windSpd * cos(angleRad)

        var gxw: Int? = null; var ghw: Int? = null; var gtw = false
        if (gustSpd != null && gustSpd > windSpd) {
            gxw = abs(gustSpd * sin(angleRad)).roundToInt()
            ghw = (gustSpd * cos(angleRad)).roundToInt()
            gtw = (gustSpd * cos(angleRad)) < 0
        }

        XWindResult(xw.roundToInt(), hw.roundToInt(), hw < 0, gxw, ghw, gtw)
    } else null

    Column(verticalArrangement = Arrangement.spacedBy(18.dp)) {
        ToolkitTextField(value = runwayInput,
            onValueChange = { runwayInput = it.replace(Regex("^0+(?=\\d)"), "") },
            label = "Runway (01–36 or heading)", placeholder = "e.g. 27 or 270",
            keyboardType = KeyboardType.Number)

        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp)) {
            Column(Modifier.weight(1f)) {
                FieldLabel("Wind (dir/spd)")
                OutlinedTextField(
                    value = windInput,
                    onValueChange = { handleWindInput(it) },
                    placeholder = { Text("e.g. 28025", fontSize = 14.sp, color = colors.textMuted) },
                    modifier = Modifier.fillMaxWidth()
                        .onFocusChanged { if (!it.isFocused) formatWindInput() },
                    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,
                    )
                )
            }
            Column(Modifier.weight(1f)) {
                ToolkitTextField(value = gustInput, onValueChange = { gustInput = it },
                    label = "Gust (kts)", placeholder = "e.g. 25",
                    keyboardType = KeyboardType.Number, sublabel = "optional")
            }
        }

        ClearButton(onClick = { runwayInput = ""; windInput = ""; gustInput = "" })

        if (results != null) {
            ResultCard {
                val hwLabel = if (results.isTailwind) "Tailwind" else "Headwind"
                val hwColor = if (results.isTailwind) colors.danger else colors.text
                ResultRow(label = "Crosswind", value = "${results.crosswind} kts")
                ResultRowColored(label = hwLabel, value = "${abs(results.headwind)} kts", color = hwColor)

                if (results.gustCrosswind != null && results.gustHeadwind != null) {
                    ResultDivider()
                    val gLabel = if (results.gustIsTailwind) "Gust Tailwind" else "Gust Headwind"
                    val gColor = if (results.gustIsTailwind) colors.danger else colors.text
                    ResultRow(label = "Gust Crosswind", value = "${results.gustCrosswind} kts")
                    ResultRowColored(label = gLabel, value = "${abs(results.gustHeadwind)} kts", color = gColor)
                }
            }
        }
    }
}
