package com.harshmallow.pilottoolkit.ui.modules

import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
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 kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.net.HttpURLConnection
import java.net.URL
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.TimeZone

private val ARINC_URLS = mapOf(
    "atlantic" to listOf(
        "https://www.radio.arinc.net/atlantic/",
        "https://radio.arinc.net/atlantic/"
    ),
    "pacific" to listOf(
        "https://www.radio.arinc.net/pacific/",
        "https://radio.arinc.net/pacific/"
    )
)

@Composable
fun HFModule() {
    val colors = ToolkitTheme.colors
    val context = LocalContext.current
    val scope = rememberCoroutineScope()

    var region by remember { mutableStateOf("atlantic") }
    var pageDate by remember { mutableStateOf<Date?>(null) }
    var dateMismatch by remember { mutableStateOf(false) }
    var fetchError by remember { mutableStateOf<String?>(null) }
    var isFetching by remember { mutableStateOf(false) }
    var resolvedUrl by remember { mutableStateOf(ARINC_URLS["atlantic"]!!.first()) }
    var now by remember { mutableStateOf(System.currentTimeMillis()) }

    // Tick every minute to update staleness display
    LaunchedEffect(Unit) {
        while (true) {
            delay(60_000)
            now = System.currentTimeMillis()
        }
    }

    // Staleness calculation
    val staleMins = if (pageDate != null) ((now - pageDate!!.time) / 60_000).toInt() else -1
    val isStale = staleMins >= 240
    val stalenessText = when {
        staleMins < 0 -> null
        staleMins < 1 -> "Just now"
        staleMins < 60 -> "${staleMins}m ago"
        staleMins < 1440 -> "${staleMins / 60}h ${staleMins % 60}m ago"
        else -> "${staleMins / 1440}d ${(staleMins % 1440) / 60}h ago"
    }

    data class ParseResult(val time: Date, val year: Int, val mon: Int, val day: Int)

    // Parse "Valid from Feb. 22, 2026, 1200Z - 1900Z" (Atlantic) or "Valid from Feb. 22, 2026, 1615Z" (Pacific)
    // Atlantic: use END time (when frequencies expire)
    // Pacific: use the single time
    fun parseValidFrom(html: String, reg: String): ParseResult? {
        val months = mapOf("Jan" to 0, "Feb" to 1, "Mar" to 2, "Apr" to 3, "May" to 4, "Jun" to 5,
            "Jul" to 6, "Aug" to 7, "Sep" to 8, "Oct" to 9, "Nov" to 10, "Dec" to 11)

        // Try Atlantic format: "Valid from Mon. DD, YYYY, HHmmZ - HHmmZ"
        val atlRegex = Regex("""Valid from\s+(\w+)\.\s+(\d+),\s+(\d{4}),\s+(\d{4})Z\s*-\s*(\d{4})Z""", RegexOption.IGNORE_CASE)
        val atlMatch = atlRegex.find(html)
        if (atlMatch != null) {
            val mon = months[atlMatch.groupValues[1]] ?: return null
            val day = atlMatch.groupValues[2].toInt()
            val year = atlMatch.groupValues[3].toInt()
            val hhmm = atlMatch.groupValues[5] // END time
            val hh = hhmm.substring(0, 2).toInt()
            val mm = hhmm.substring(2, 4).toInt()
            val cal = java.util.Calendar.getInstance(TimeZone.getTimeZone("UTC"))
            cal.set(year, mon, day, hh, mm, 0)
            cal.set(java.util.Calendar.MILLISECOND, 0)
            return ParseResult(cal.time, year, mon, day)
        }

        // Pacific format: "Valid from Mon. DD, YYYY, HHmmZ"
        val pacRegex = Regex("""Valid from\s+(\w+)\.\s+(\d+),\s+(\d{4}),\s+(\d{4})Z""", RegexOption.IGNORE_CASE)
        val pacMatch = pacRegex.find(html) ?: return null
        val mon = months[pacMatch.groupValues[1]] ?: return null
        val day = pacMatch.groupValues[2].toInt()
        val year = pacMatch.groupValues[3].toInt()
        val hhmm = pacMatch.groupValues[4]
        val hh = hhmm.substring(0, 2).toInt()
        val mm = hhmm.substring(2, 4).toInt()
        val cal = java.util.Calendar.getInstance(TimeZone.getTimeZone("UTC"))
        cal.set(year, mon, day, hh, mm, 0)
        cal.set(java.util.Calendar.MILLISECOND, 0)
        return ParseResult(cal.time, year, mon, day)
    }

    fun fetchPageAge() {
        scope.launch {
            isFetching = true
            fetchError = null
            dateMismatch = false
            val urls = ARINC_URLS[region]!!
            var lastError: String? = null
            for (tryUrl in urls) {
                try {
                    val result = withContext(Dispatchers.IO) {
                        val url = URL(tryUrl)
                        val conn = url.openConnection() as HttpURLConnection
                        conn.requestMethod = "GET"
                        conn.connectTimeout = 10_000
                        conn.readTimeout = 10_000
                        conn.setRequestProperty("User-Agent", "PilotToolkit/1.0")
                        try {
                            conn.connect()
                            val html = conn.inputStream.bufferedReader().readText()
                            parseValidFrom(html, region)
                        } finally {
                            conn.disconnect()
                        }
                    }
                    if (result != null) {
                        pageDate = result.time
                        now = System.currentTimeMillis()
                        resolvedUrl = tryUrl
                        // Date mismatch check: accept today or yesterday UTC
                        val todayCal = java.util.Calendar.getInstance(TimeZone.getTimeZone("UTC"))
                        val yesterdayCal = java.util.Calendar.getInstance(TimeZone.getTimeZone("UTC")).apply {
                            add(java.util.Calendar.DAY_OF_MONTH, -1)
                        }
                        val matchesToday = result.year == todayCal.get(java.util.Calendar.YEAR) &&
                            result.mon == todayCal.get(java.util.Calendar.MONTH) &&
                            result.day == todayCal.get(java.util.Calendar.DAY_OF_MONTH)
                        val matchesYesterday = result.year == yesterdayCal.get(java.util.Calendar.YEAR) &&
                            result.mon == yesterdayCal.get(java.util.Calendar.MONTH) &&
                            result.day == yesterdayCal.get(java.util.Calendar.DAY_OF_MONTH)
                        if (!matchesToday && !matchesYesterday) {
                            dateMismatch = true
                        }
                        isFetching = false
                        return@launch // Success — stop trying further URLs
                    } else {
                        lastError = "Could not find \"Valid from\" timestamp on ARINC page."
                    }
                } catch (e: Exception) {
                    lastError = "Unable to reach ARINC: ${e.message?.take(60) ?: "unknown error"}"
                }
            }
            // All URLs exhausted
            fetchError = lastError
            resolvedUrl = urls.first()
            isFetching = false
        }
    }

    val url = resolvedUrl

    Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
        // Region selector
        SegmentedSelector(
            options = listOf("Atlantic", "Pacific"),
            selected = if (region == "atlantic") 0 else 1,
            onSelect = {
                val newRegion = if (it == 0) "atlantic" else "pacific"
                region = newRegion
                pageDate = null; fetchError = null; dateMismatch = false
                resolvedUrl = ARINC_URLS[newRegion]!!.first()
            }
        )

        // Refresh button + staleness
        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically) {
            Button(
                onClick = { fetchPageAge() },
                enabled = !isFetching,
                colors = ButtonDefaults.buttonColors(
                    containerColor = colors.accent.copy(alpha = 0.1f), contentColor = colors.accent),
                shape = RoundedCornerShape(6.dp),
                contentPadding = PaddingValues(horizontal = 14.dp, vertical = 8.dp)
            ) {
                Text(if (isFetching) "Checking…" else "↻ Check Page Age",
                    fontSize = 12.sp, fontWeight = FontWeight.SemiBold)
            }
            if (stalenessText != null) {
                Text(
                    text = (if (isStale) "⚠ " else "") + stalenessText,
                    fontSize = 12.sp, fontWeight = FontWeight.Medium,
                    color = if (isStale) colors.warning else colors.textMuted
                )
            }
        }

        // Staleness warning
        if (isStale) {
            Box(modifier = Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                .background(colors.warningBg).border(1.dp, colors.warningBorder, RoundedCornerShape(8.dp))
                .padding(12.dp)) {
                Text("⚠ ARINC page is over 4 hours old. Frequencies may have changed.",
                    fontSize = 13.sp, fontWeight = FontWeight.Medium, color = colors.warning)
            }
        }

        // Fetch error
        if (fetchError != null) {
            Box(modifier = Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                .background(colors.dangerBg).border(1.dp, colors.dangerBorder, RoundedCornerShape(8.dp))
                .padding(12.dp)) {
                Text(fetchError!!, fontSize = 13.sp, color = colors.danger)
            }
        }

        // Date mismatch warning
        if (dateMismatch) {
            Box(modifier = Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                .background(colors.dangerBg).border(1.dp, colors.dangerBorder, RoundedCornerShape(8.dp))
                .padding(12.dp)) {
                Text("⛔ ARINC page date does not match today's date — verify data is current.",
                    fontSize = 13.sp, fontWeight = FontWeight.Medium, color = colors.danger)
            }
        }

        // Page date detail
        if (pageDate != null) {
            val fmt = SimpleDateFormat("dd MMM yyyy, HHmm", Locale.US)
            fmt.timeZone = TimeZone.getTimeZone("UTC")
            val dateStr = fmt.format(pageDate!!) + "Z"
            val validLabel = if (region == "atlantic") "FREQUENCIES VALID UNTIL" else "FREQUENCIES VALID FROM"
            Box(modifier = Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                .background(colors.resultBg).border(1.dp, colors.resultBorder, RoundedCornerShape(8.dp))
                .padding(14.dp)) {
                Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
                    Text(validLabel, fontSize = 11.sp, fontWeight = FontWeight.Bold,
                        color = colors.textMuted, letterSpacing = 0.5.sp)
                    Text(dateStr, fontSize = 15.sp, fontWeight = FontWeight.Bold,
                        color = colors.accent, fontFamily = FontFamily.Monospace)
                }
            }
        }

        // Open in browser buttons
        OutlinedButton(
            onClick = { context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) },
            modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(6.dp),
            colors = ButtonDefaults.outlinedButtonColors(contentColor = colors.accent)
        ) {
            Text("Open ARINC ${region.replaceFirstChar { it.uppercase() }} Page ↗",
                fontSize = 13.sp, fontWeight = FontWeight.SemiBold)
        }

        // Disclaimer
        Box(modifier = Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
            .background(colors.surfaceAlt).border(1.dp, colors.border, RoundedCornerShape(8.dp))
            .padding(12.dp)) {
            Text("Frequency information sourced from ARINC (Collins Aerospace). Frequencies change based on propagation conditions. Verify against the official source before use. This application is not affiliated with ARINC or Collins Aerospace.",
                fontSize = 11.sp, color = colors.textMuted, lineHeight = 16.sp)
        }
    }
}

/*
 * --- WEBVIEW APPROACH (commented out for future use) ---
 *
 * To embed the ARINC page directly in the app, replace the body of HFModule
 * with a WebView. Requires: import android.webkit.*
 * import androidx.compose.ui.viewinterop.AndroidView
 *
 * AndroidView(
 *     factory = { ctx ->
 *         WebView(ctx).apply {
 *             settings.javaScriptEnabled = true
 *             settings.domStorageEnabled = true
 *             webViewClient = object : WebViewClient() {
 *                 override fun onPageFinished(view: WebView?, url: String?) { ... }
 *                 override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) { ... }
 *             }
 *             loadUrl(url)
 *         }
 *     },
 *     update = { webView -> webView.loadUrl(url) }
 * )
 */
