package de.arxsilex.maptools.converter.desktop

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import de.arxsilex.maptools.converter.desktop.generated.resources.Res
import de.arxsilex.maptools.converter.desktop.generated.resources.maptools_logo
import org.jetbrains.compose.resources.painterResource

@Composable
internal fun WorkflowHeader(
    currentStep: WorkflowStep,
    furthestVisitedStep: WorkflowStep,
    onStepSelected: (WorkflowStep) -> Unit,
    onOpenExternalLink: (String) -> Unit,
    language: AppLanguage,
    measurementSystem: MeasurementSystem,
    onLanguageChange: (AppLanguage) -> Unit,
    onMeasurementSystemChange: (MeasurementSystem) -> Unit,
) {
    val strings = LocalAppStrings.current
    var showProgramInfo by remember { mutableStateOf(false) }
    Column(
        modifier = Modifier.fillMaxWidth().height(118.dp).padding(horizontal = 28.dp),
    ) {
        Row(
            modifier = Modifier.fillMaxWidth().height(68.dp),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Image(
                painter = painterResource(Res.drawable.maptools_logo),
                contentDescription = "ArxSilex MapTools",
                contentScale = ContentScale.Fit,
                modifier = Modifier.size(48.dp),
            )
            Spacer(Modifier.width(14.dp))
            Column {
                Text("ArxSilex MapTools", fontWeight = FontWeight.Bold, fontSize = 18.sp)
                Text(
                    strings("chrome.converter_version", AppMetadata.version),
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    fontSize = 12.sp,
                )
            }
            Spacer(Modifier.weight(1f))
            Text(
                strings["chrome.offline"],
                color = MaterialTheme.colorScheme.onSurfaceVariant,
                fontSize = 12.sp,
            )
            Spacer(Modifier.width(12.dp))
            HeaderDropdown(
                label = strings["chrome.language"],
                value = language.nativeName,
                options = AppLanguage.entries,
                optionLabel = AppLanguage::nativeName,
                onSelected = onLanguageChange,
            )
            Spacer(Modifier.width(8.dp))
            HeaderDropdown(
                label = strings["chrome.units"],
                value = strings[if (measurementSystem == MeasurementSystem.METRIC) "units.metric" else "units.imperial"],
                options = MeasurementSystem.entries,
                optionLabel = { option ->
                    strings[if (option == MeasurementSystem.METRIC) "units.metric" else "units.imperial"]
                },
                onSelected = onMeasurementSystemChange,
            )
            Spacer(Modifier.width(8.dp))
            OutlinedButton(onClick = { showProgramInfo = true }) {
                Text(strings["chrome.info"])
            }
        }

        Row(
            modifier = Modifier.fillMaxWidth().height(50.dp),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Text(
                strings["chrome.workflow"],
                modifier = Modifier.width(118.dp),
                color = MaterialTheme.colorScheme.tertiary,
                fontSize = 11.sp,
                fontWeight = FontWeight.Bold,
            )
            WorkflowStep.entries.forEachIndexed { index, step ->
                if (index > 0) {
                    Box(
                        modifier = Modifier.width(28.dp).height(1.dp)
                            .background(MaterialTheme.colorScheme.outlineVariant),
                    )
                }
                HorizontalNavigationStep(
                    number = index + 1,
                    title = strings[step.textKey],
                    active = step == currentStep,
                    complete = step.ordinal < currentStep.ordinal,
                    enabled = step.ordinal <= furthestVisitedStep.ordinal,
                    onClick = { onStepSelected(step) },
                    modifier = Modifier.weight(1f),
                )
            }
        }
    }
    if (showProgramInfo) {
        ProgramInfoDialog(
            onDismiss = { showProgramInfo = false },
            onOpenExternalLink = onOpenExternalLink,
        )
    }
}

@Composable
private fun <T> HeaderDropdown(
    label: String,
    value: String,
    options: List<T>,
    optionLabel: (T) -> String,
    onSelected: (T) -> Unit,
) {
    var expanded by remember { mutableStateOf(false) }
    Box {
        OutlinedButton(onClick = { expanded = true }) {
            Text("$label: $value", maxLines = 1, overflow = TextOverflow.Ellipsis)
        }
        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
            options.forEach { option ->
                DropdownMenuItem(
                    text = { Text(optionLabel(option)) },
                    onClick = {
                        expanded = false
                        onSelected(option)
                    },
                )
            }
        }
    }
}

@Composable
private fun HorizontalNavigationStep(
    number: Int,
    title: String,
    active: Boolean,
    complete: Boolean,
    enabled: Boolean,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
) {
    val color = when {
        active -> MaterialTheme.colorScheme.tertiary
        complete -> MaterialTheme.colorScheme.primary
        else -> MaterialTheme.colorScheme.onSurfaceVariant
    }
    val alpha = if (enabled) 1f else 0.45f
    Row(
        modifier = modifier
            .clickable(enabled = enabled, onClick = onClick)
            .padding(horizontal = 8.dp, vertical = 5.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Box(
            modifier = Modifier.size(30.dp).border(1.dp, color.copy(alpha = alpha), CircleShape),
            contentAlignment = Alignment.Center,
        ) {
            Text(
                if (complete) "✓" else number.toString(),
                color = color.copy(alpha = alpha),
                fontWeight = FontWeight.Bold,
            )
        }
        Spacer(Modifier.width(12.dp))
        Text(
            title,
            color = color.copy(alpha = alpha),
            fontWeight = if (active) FontWeight.SemiBold else FontWeight.Normal,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis,
        )
    }
}
