package solutions.tretter.githugandroid

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun PaneWorkspace(
    modifier: Modifier = Modifier,
    paneLayout: PaneLayout,
    diagnosticSkinEnabled: Boolean = false,
    onMovePane: (PaneId, Int) -> Unit,
    onTogglePane: (PaneId) -> Unit,
    levelsContent: @Composable () -> Unit,
    visualContent: @Composable () -> Unit,
    exerciseContent: @Composable () -> Unit,
    terminalContent: @Composable () -> Unit,
) {
    Column(
        modifier = modifier
            .fillMaxWidth()
            .wrapContentHeight(),
        verticalArrangement = Arrangement.spacedBy(0.dp),
    ) {
        paneLayout.order.forEachIndexed { index, paneId ->
            val isCollapsed = paneId in paneLayout.collapsed
            if (isCollapsed) {
                CollapsedPaneCard(
                    paneId = paneId,
                    diagnosticSkinEnabled = diagnosticSkinEnabled,
                    canMoveUp = index > 0,
                    canMoveDown = index < paneLayout.order.lastIndex,
                    onMoveUp = { onMovePane(paneId, -1) },
                    onMoveDown = { onMovePane(paneId, 1) },
                    onToggleCollapse = { onTogglePane(paneId) },
                )
            } else {
                PaneCard(
                    paneId = paneId,
                    diagnosticSkinEnabled = diagnosticSkinEnabled,
                    modifier = Modifier
                        .fillMaxWidth()
                        .wrapContentHeight(),
                    canMoveUp = index > 0,
                    canMoveDown = index < paneLayout.order.lastIndex,
                    onMoveUp = { onMovePane(paneId, -1) },
                    onMoveDown = { onMovePane(paneId, 1) },
                    onToggleCollapse = { onTogglePane(paneId) },
                ) {
                    when (paneId) {
                        PaneId.LEVELS -> levelsContent()
                        PaneId.VISUAL -> visualContent()
                        PaneId.EXERCISE -> exerciseContent()
                        PaneId.TERMINAL -> terminalContent()
                    }
                }
            }
        }
    }
}

@Composable
private fun PaneCard(
    paneId: PaneId,
    diagnosticSkinEnabled: Boolean,
    modifier: Modifier = Modifier,
    canMoveUp: Boolean,
    canMoveDown: Boolean,
    onMoveUp: () -> Unit,
    onMoveDown: () -> Unit,
    onToggleCollapse: () -> Unit,
    content: @Composable () -> Unit,
) {
    Card(
        modifier = modifier,
        colors = CardDefaults.cardColors(
            containerColor = if (diagnosticSkinEnabled) paneDiagnosticBase(paneId) else PanelSecondary,
        ),
        shape = RoundedCornerShape(16.dp),
    ) {
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentHeight()
                .diagnosticPaneBackground(diagnosticSkinEnabled, paneId, paneDiagnosticBase(paneId)),
        ) {
            PaneHeader(
                paneId = paneId,
                diagnosticSkinEnabled = diagnosticSkinEnabled,
                collapsed = false,
                canMoveUp = canMoveUp,
                canMoveDown = canMoveDown,
                onMoveUp = onMoveUp,
                onMoveDown = onMoveDown,
                onToggleCollapse = onToggleCollapse,
            )
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .wrapContentHeight()
                    .diagnosticPaneBackground(diagnosticSkinEnabled, paneId, paneDiagnosticContent(paneId))
                    .padding(horizontal = 12.dp, vertical = 10.dp),
            ) {
                content()
            }
        }
    }
}

@Composable
private fun CollapsedPaneCard(
    paneId: PaneId,
    diagnosticSkinEnabled: Boolean,
    canMoveUp: Boolean,
    canMoveDown: Boolean,
    onMoveUp: () -> Unit,
    onMoveDown: () -> Unit,
    onToggleCollapse: () -> Unit,
) {
    Card(
        modifier = Modifier.fillMaxWidth(),
        colors = CardDefaults.cardColors(
            containerColor = if (diagnosticSkinEnabled) paneDiagnosticBase(paneId) else PanelSecondary,
        ),
        shape = RoundedCornerShape(16.dp),
    ) {
        PaneHeader(
            paneId = paneId,
            diagnosticSkinEnabled = diagnosticSkinEnabled,
            collapsed = true,
            canMoveUp = canMoveUp,
            canMoveDown = canMoveDown,
            onMoveUp = onMoveUp,
            onMoveDown = onMoveDown,
            onToggleCollapse = onToggleCollapse,
        )
    }
}

@Composable
private fun PaneHeader(
    paneId: PaneId,
    diagnosticSkinEnabled: Boolean,
    collapsed: Boolean,
    canMoveUp: Boolean,
    canMoveDown: Boolean,
    onMoveUp: () -> Unit,
    onMoveDown: () -> Unit,
    onToggleCollapse: () -> Unit,
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .background(
                if (diagnosticSkinEnabled) {
                    if (collapsed) paneDiagnosticCollapsed(paneId) else paneDiagnosticHeader(paneId)
                } else if (collapsed) {
                    PanelTertiary
                } else {
                    PanelPrimary
                }
            )
            .diagnosticPanePattern(diagnosticSkinEnabled, paneId)
            .padding(horizontal = 10.dp, vertical = 6.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceBetween,
    ) {
        Text(paneId.title, color = TextPrimary, fontWeight = FontWeight.Bold)
        Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
            HeaderActionButton(label = if (collapsed) "Expand" else "Collapse", onClick = onToggleCollapse)
            HeaderActionButton(label = "↑", enabled = canMoveUp, onClick = onMoveUp)
            HeaderActionButton(label = "↓", enabled = canMoveDown, onClick = onMoveDown)
        }
    }
}

private fun paneDiagnosticBase(paneId: PaneId): Color = when (paneId) {
    PaneId.EXERCISE -> Color(0xFF17345C)
    PaneId.TERMINAL -> Color(0xFF4A1B1B)
    PaneId.VISUAL -> Color(0xFF173F2A)
    PaneId.LEVELS -> Color(0xFF4A3A12)
}

private fun paneDiagnosticContent(paneId: PaneId): Color = when (paneId) {
    PaneId.EXERCISE -> Color(0xFF1C477B)
    PaneId.TERMINAL -> Color(0xFF612424)
    PaneId.VISUAL -> Color(0xFF1C5739)
    PaneId.LEVELS -> Color(0xFF654F16)
}

private fun paneDiagnosticHeader(paneId: PaneId): Color = when (paneId) {
    PaneId.EXERCISE -> Color(0xFF0F2748)
    PaneId.TERMINAL -> Color(0xFF351313)
    PaneId.VISUAL -> Color(0xFF102F20)
    PaneId.LEVELS -> Color(0xFF372B0D)
}

private fun paneDiagnosticCollapsed(paneId: PaneId): Color = paneDiagnosticContent(paneId)

private fun Modifier.diagnosticPaneBackground(enabled: Boolean, paneId: PaneId, color: Color): Modifier {
    return if (enabled) {
        background(color).diagnosticPanePattern(enabled = true, paneId = paneId)
    } else {
        this
    }
}

private fun Modifier.diagnosticPanePattern(enabled: Boolean, paneId: PaneId): Modifier {
    return if (enabled) paneDiagnosticPattern(paneId) else this
}

private fun Modifier.paneDiagnosticPattern(paneId: PaneId): Modifier = drawBehind {
    val stripeColor = when (paneId) {
        PaneId.EXERCISE -> Color(0x6684C5FF)
        PaneId.TERMINAL -> Color(0x66FF9A9A)
        PaneId.VISUAL -> Color(0x667CFFB1)
        PaneId.LEVELS -> Color(0x66FFE082)
    }
    val strokeWidth = 2.dp.toPx()
    val spacing = 34.dp.toPx()
    var start = -size.height
    while (start < size.width) {
        drawLine(
            color = stripeColor,
            start = Offset(start, size.height),
            end = Offset(start + size.height, 0f),
            strokeWidth = strokeWidth,
        )
        start += spacing
    }
}

@Composable
private fun HeaderActionButton(
    label: String,
    enabled: Boolean = true,
    onClick: () -> Unit,
) {
    TextButton(
        onClick = onClick,
        enabled = enabled,
        contentPadding = PaddingValues(horizontal = 6.dp, vertical = 0.dp),
        colors = ButtonDefaults.textButtonColors(
            contentColor = Accent,
            disabledContentColor = TextMuted,
        ),
    ) {
        Text(label, fontSize = 11.sp)
    }
}
