package dev.castarr.tv.ui

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.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.Canvas
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.tv.material3.Surface
import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.LocalContentColor
import androidx.tv.material3.Text
import dev.castarr.tv.AppState
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin

@Composable
fun CastarrApp(state: AppState) {
    // Back always leads home instead of quitting the app by accident.
    androidx.activity.compose.BackHandler(
        enabled = !state.playerVisible && state.screen != AppState.Screen.LIVE
            && state.screen != AppState.Screen.WELCOME
    ) {
        state.screen = if (state.screen == AppState.Screen.ADVANCED) AppState.Screen.SETTINGS
        else AppState.Screen.LIVE
    }
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(CastarrColors.bg)
    ) {
        when {
            state.screen == AppState.Screen.WELCOME -> WelcomeScreen(state)
            state.appError != AppState.AppError.NONE && !state.playerVisible -> ErrorScreen(state)
            else -> Column(modifier = Modifier.fillMaxSize()) {
                TopBar(state)
                when (state.screen) {
                    AppState.Screen.LIVE -> LiveScreen(state)
                    AppState.Screen.SETTINGS -> SettingsScreen(state)
                    AppState.Screen.ADVANCED -> AdvancedScreen(state)
                    AppState.Screen.WELCOME -> Unit
                }
            }
        }
        if (state.playerVisible) {
            PlayerScreen(state)
        }
        if (state.digitBuffer.isNotEmpty()) {
            DigitBadge(state)
        }
    }
}

/** Big feedback badge while typing a channel number on the remote. */
@Composable
private fun DigitBadge(state: AppState) {
    val target = state.digitBuffer.toIntOrNull()
        ?.let { state.activeChannels().getOrNull(it - 1) }
    Column(
        modifier = Modifier
            .padding(top = 60.dp, end = 48.dp)
            .fillMaxSize()
            .wrapContentSize(Alignment.TopEnd)
            .clip(RoundedCornerShape(14.dp))
            .background(CastarrColors.surface)
            .padding(horizontal = 22.dp, vertical = 14.dp),
        horizontalAlignment = Alignment.End,
    ) {
        Text(
            state.digitBuffer,
            color = CastarrColors.fg,
            fontFamily = AppFont,
            fontSize = 34.sp,
            fontWeight = FontWeight.Medium,
            letterSpacing = 2.sp,
        )
        Text(
            target?.name ?: "kein Sender",
            color = if (target != null) CastarrColors.muted else CastarrColors.faint,
            fontFamily = AppFont,
            fontSize = 13.sp,
        )
    }
}

@Composable
private fun TopBar(state: AppState) {
    Row(
        modifier = Modifier.padding(horizontal = 40.dp, vertical = 18.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Text(
            "CASTARR",
            color = CastarrColors.fg,
            fontFamily = SpaceGrotesk,
            fontSize = 15.sp,
            fontWeight = FontWeight.Medium,
            letterSpacing = 4.sp,
        )
        Spacer(Modifier.weight(1f))
        state.connectedRemote?.let { name ->
            Row(verticalAlignment = Alignment.CenterVertically) {
                Box(
                    Modifier
                        .size(7.dp)
                        .clip(CircleShape)
                        .background(CastarrColors.accent)
                )
                Spacer(Modifier.width(8.dp))
                Text(name, color = CastarrColors.muted, fontFamily = AppFont, fontSize = 13.sp)
            }
            Spacer(Modifier.width(18.dp))
        }
        GearButton {
            state.screen = if (state.screen == AppState.Screen.LIVE) AppState.Screen.SETTINGS
            else AppState.Screen.LIVE
        }
    }
}

/** Round settings button with a drawn gear (glyphs render as emoji). */
@Composable
private fun GearButton(onClick: () -> Unit) {
    Surface(
        onClick = onClick,
        modifier = Modifier.semantics { contentDescription = "Einstellungen" },
        shape = ClickableSurfaceDefaults.shape(CircleShape),
        colors = ClickableSurfaceDefaults.colors(
            containerColor = CastarrColors.surface,
            contentColor = CastarrColors.muted,
            focusedContainerColor = CastarrColors.accent,
            focusedContentColor = CastarrColors.onAccent,
        ),
    ) {
        val color = LocalContentColor.current
        Box(Modifier.size(40.dp), contentAlignment = Alignment.Center) {
            Canvas(Modifier.size(18.dp)) {
                val center = Offset(size.width / 2f, size.height / 2f)
                // Thick ring with a hole plus stubby teeth — thin lines
                // read as a sun, not a gear.
                val ringWidth = size.minDimension * 0.20f
                drawCircle(
                    color,
                    radius = size.minDimension * 0.27f,
                    center = center,
                    style = Stroke(ringWidth),
                )
                val toothStart = size.minDimension * 0.34f
                val toothEnd = size.minDimension * 0.50f
                for (i in 0 until 8) {
                    val angle = (i + 0.5) * (PI / 4)
                    val dx = cos(angle).toFloat()
                    val dy = sin(angle).toFloat()
                    drawLine(
                        color,
                        start = center + Offset(dx * toothStart, dy * toothStart),
                        end = center + Offset(dx * toothEnd, dy * toothEnd),
                        strokeWidth = size.minDimension * 0.17f,
                        cap = StrokeCap.Butt,
                    )
                }
            }
        }
    }
}
