package ru.fincode.tsudesk.feature.schedule.presentation.screen

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.horizontalScroll
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.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
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.statusBars
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.KeyboardArrowDown
import androidx.compose.material.icons.filled.KeyboardArrowUp
import androidx.compose.material3.AssistChip
import androidx.compose.material3.AssistChipDefaults
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.Surface
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.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ru.fincode.tsudesk.core.common.model.DataResult
import ru.fincode.tsudesk.core.ui.theme.TSUDeskThemeExt
import ru.fincode.tsudesk.feature.schedule.presentation.util.dowRuShort
import ru.fincode.tsudesk.feature.schedule.presentation.util.todayString

@Composable
fun ScheduleScreen(
    state: ScheduleUiState,
    onIntent: (ScheduleIntent) -> Unit,
    modifier: Modifier = Modifier
) {
    Column(modifier.fillMaxSize()) {
        ScheduleHeader(state, onIntent)

        when (state.viewMode) {
            ScheduleViewMode.DAY -> DayPicker(state, onIntent)
            ScheduleViewMode.WEEK -> WeekHeaderStub(state)
        }

        ScheduleContent(
            state = state,
            onIntent = onIntent,
            modifier = Modifier.weight(1f)
        )
    }
}

@Composable
private fun ScheduleHeader(
    state: ScheduleUiState,
    onIntent: (ScheduleIntent) -> Unit
) {
    val shape = RoundedCornerShape(bottomStart = 20.dp, bottomEnd = 20.dp)
    val brand = TSUDeskThemeExt.colors

    val headerBrush = Brush.linearGradient(
        listOf(
            brand.brand,
            brand.brand.copy(alpha = 0.75f)
        )
    )

    Box(
        Modifier
            .fillMaxWidth()
            .clip(shape)
            .background(headerBrush)
    ) {
        Column(
            Modifier
                // inset только для содержимого, фон остаётся до верха
                .windowInsetsPadding(WindowInsets.statusBars)
                .padding(start = 16.dp, end = 16.dp, bottom = 14.dp)
        ) {
            Row(verticalAlignment = Alignment.CenterVertically) {
                Column(Modifier.weight(1f)) {
                    Text(
                        text = "Расписание",
                        color = brand.onBrand,
                        fontSize = 20.sp,
                        fontWeight = FontWeight.Bold
                    )
                    Text(
                        text = "ТулГУ • Осенний семестр",
                        color = brand.onBrand.copy(alpha = 0.8f),
                        fontSize = 11.sp,
                        fontWeight = FontWeight.Medium
                    )
                }

                ModeToggle(
                    mode = state.viewMode,
                    onMode = { onIntent(ScheduleIntent.SetViewMode(it)) }
                )
            }

            Spacer(Modifier.height(12.dp))

            GroupSelector(
                groupInput = state.groupInput,
                recentGroups = state.recentGroups,
                expanded = state.isGroupMenuExpanded,
                isLoading = state.isLoading,
                onExpanded = { onIntent(ScheduleIntent.SetGroupMenuExpanded(it)) },
                onValueChange = { onIntent(ScheduleIntent.ChangeGroupInput(it)) },
                onSelectRecent = { group ->
                    onIntent(ScheduleIntent.SelectRecentGroup(group))
                    onIntent(ScheduleIntent.ApplyGroup)
                },
                onRemoveRecent = { onIntent(ScheduleIntent.RemoveRecentGroup(it)) },
                onApply = { onIntent(ScheduleIntent.ApplyGroup) },
                modifier = Modifier.fillMaxWidth()
            )
        }
    }
}

@Composable
private fun ModeToggle(
    mode: ScheduleViewMode,
    onMode: (ScheduleViewMode) -> Unit
) {
    val containerShape = RoundedCornerShape(12.dp)
    Row(
        Modifier
            .background(MaterialTheme.colorScheme.onError.copy(alpha = 0.18f), containerShape)
            .padding(4.dp)
    ) {
        SegButton(
            text = "День",
            selected = mode == ScheduleViewMode.DAY,
            onClick = { onMode(ScheduleViewMode.DAY) }
        )
        SegButton(
            text = "Неделя",
            selected = mode == ScheduleViewMode.WEEK,
            onClick = { onMode(ScheduleViewMode.WEEK) }
        )
    }
}

@Composable
private fun SegButton(
    text: String,
    selected: Boolean,
    onClick: () -> Unit
) {
    TextButton(
        onClick = onClick,
        shape = RoundedCornerShape(10.dp),
        contentPadding = PaddingValues(horizontal = 12.dp, vertical = 6.dp),
        colors = ButtonDefaults.textButtonColors(
            containerColor = if (selected) MaterialTheme.colorScheme.onError else MaterialTheme.colorScheme.onError.copy(
                alpha = 0f
            ),
            contentColor = if (selected) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.onError.copy(
                alpha = 0.85f
            )
        )
    ) {
        Text(text = text, fontSize = 11.sp, fontWeight = FontWeight.Bold)
    }
}

@Composable
private fun GroupSelector(
    groupInput: String,
    recentGroups: List<String>,
    expanded: Boolean,
    isLoading: Boolean,
    onExpanded: (Boolean) -> Unit,
    onValueChange: (String) -> Unit,
    onSelectRecent: (String) -> Unit,
    onRemoveRecent: (String) -> Unit,
    onApply: () -> Unit,
    modifier: Modifier = Modifier
) {
    val keyboard = LocalSoftwareKeyboardController.current

    Column(modifier) {
        OutlinedTextField(
            value = groupInput,
            onValueChange = onValueChange,
            modifier = Modifier.fillMaxWidth(),
            singleLine = true,
            enabled = true,
            label = { Text("Группа") },
            keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
            keyboardActions = KeyboardActions(
                onDone = {
                    keyboard?.hide()
                    onExpanded(false)
                    if (groupInput.isNotBlank()) onApply()
                }
            ),
            trailingIcon = {
                IconButton(onClick = { onExpanded(!expanded) }) {
                    Icon(
                        imageVector = if (expanded) Icons.Filled.KeyboardArrowUp else Icons.Filled.KeyboardArrowDown,
                        contentDescription = if (expanded) "Свернуть список" else "Развернуть список",
                        tint = MaterialTheme.colorScheme.onError
                    )
                }
            },
            colors = OutlinedTextFieldDefaults.colors(
                focusedBorderColor = MaterialTheme.colorScheme.onError.copy(alpha = 0.35f),
                unfocusedBorderColor = MaterialTheme.colorScheme.onError.copy(alpha = 0.25f),
                focusedLabelColor = MaterialTheme.colorScheme.onError.copy(alpha = 0.85f),
                unfocusedLabelColor = MaterialTheme.colorScheme.onError.copy(alpha = 0.7f),
                focusedTextColor = MaterialTheme.colorScheme.onError,
                unfocusedTextColor = MaterialTheme.colorScheme.onError,
                cursorColor = MaterialTheme.colorScheme.onError
            )
        )

        // ✅ Меню РЕАЛЬНО под полем, не перекрывает, фокус в поле работает
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { onExpanded(false) },
            modifier = Modifier.fillMaxWidth()
        ) {
            if (recentGroups.isEmpty()) {
                DropdownMenuItem(
                    text = { Text("Нет сохранённых групп") },
                    onClick = { onExpanded(false) },
                    enabled = false
                )
            } else {
                recentGroups.forEach { num ->
                    DropdownMenuItem(
                        onClick = {
                            onSelectRecent(num)
                            onExpanded(false)
                        },
                        text = {
                            Text(
                                text = num,
                                maxLines = 1,
                                overflow = TextOverflow.Ellipsis
                            )
                        },
                        // ✅ trailingIcon — крестик НЕ вызывает onClick элемента меню
                        trailingIcon = {
                            IconButton(
                                onClick = { onRemoveRecent(num) }
                            ) {
                                Icon(
                                    imageVector = Icons.Filled.Close,
                                    contentDescription = "Удалить"
                                )
                            }
                        }
                    )
                }
            }
        }

        Spacer(Modifier.height(8.dp))

        Button(
            onClick = {
                keyboard?.hide()
                onExpanded(false)
                onApply()
            },
            enabled = !isLoading,
            modifier = Modifier.fillMaxWidth(),
            colors = ButtonDefaults.buttonColors(
                containerColor = MaterialTheme.colorScheme.onError,
                contentColor = MaterialTheme.colorScheme.error,
                disabledContainerColor = MaterialTheme.colorScheme.onError.copy(alpha = 0.6f),
                disabledContentColor = MaterialTheme.colorScheme.error.copy(alpha = 0.6f),
            ),
            shape = RoundedCornerShape(12.dp),
            contentPadding = PaddingValues(vertical = 12.dp)
        ) {
            if (isLoading) {
                CircularProgressIndicator(
                    strokeWidth = 2.dp,
                    modifier = Modifier.size(18.dp),
                    color = MaterialTheme.colorScheme.error
                )
                Spacer(Modifier.width(10.dp))
                Text("Загрузка…", fontWeight = FontWeight.Bold)
            } else {
                Text("Показать", fontWeight = FontWeight.Bold)
            }
        }
    }
}

@Composable
private fun DayPicker(
    state: ScheduleUiState,
    onIntent: (ScheduleIntent) -> Unit
) {
    val scroll = rememberScrollState()
    Row(
        Modifier
            .fillMaxWidth()
            .padding(vertical = 12.dp)
            .horizontalScroll(scroll)
            .padding(horizontal = 16.dp),
        horizontalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        state.dayStrip.forEach { date ->
            DayChip(
                date = date,
                selected = date == state.selectedDate,
                onClick = { onIntent(ScheduleIntent.SelectDate(date)) }
            )
        }
    }
}

@Composable
private fun DayChip(
    date: String,
    selected: Boolean,
    onClick: () -> Unit
) {
    val shape = RoundedCornerShape(14.dp)
    val bg = if (selected) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.surface
    val fg =
        if (selected) MaterialTheme.colorScheme.onError else MaterialTheme.colorScheme.onSurface
    val border =
        if (selected) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.outline.copy(
            alpha = 0.3f
        )

    val dayNum = date.take(2)
    val dow = dowRuShort(date)

    Surface(
        onClick = onClick,
        shape = shape,
        color = bg,
        tonalElevation = if (selected) 2.dp else 0.dp,
        modifier = Modifier
            .size(width = 64.dp, height = 80.dp)
            .border(1.dp, border, shape)
    ) {
        Column(
            Modifier
                .fillMaxSize()
                .padding(vertical = 10.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Text(
                dow,
                fontSize = 10.sp,
                fontWeight = FontWeight.Bold,
                color = fg.copy(alpha = 0.85f)
            )
            Text(dayNum, fontSize = 22.sp, fontWeight = FontWeight.Bold, color = fg)
            if (selected) {
                Spacer(Modifier.height(4.dp))
                Box(
                    Modifier
                        .size(6.dp)
                        .clip(RoundedCornerShape(999.dp))
                        .background(fg)
                )
            }
        }
    }
}

@Composable
private fun WeekHeaderStub(state: ScheduleUiState) {
    val start = state.dayStrip.firstOrNull()
    val end = state.dayStrip.lastOrNull()

    Row(
        Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 12.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text(
            text = when {
                start != null && end != null -> "Неделя: $start — $end"
                else -> "Неделя"
            },
            style = MaterialTheme.typography.labelLarge,
            color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f),
            fontWeight = FontWeight.Bold
        )
    }
}

@Composable
private fun ScheduleContent(
    state: ScheduleUiState,
    onIntent: (ScheduleIntent) -> Unit,
    modifier: Modifier = Modifier
) {
    LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .then(modifier)
            .padding(horizontal = 16.dp),
        contentPadding = PaddingValues(bottom = 24.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        // ✅ неблокирующий индикатор обновления (если уже есть данные)
        if (state.isLoading && state.raw != null) {
            item {
                LinearProgressIndicator(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(top = 8.dp)
                )
            }
        }

        if (state.error != null) {
            item {
                Spacer(Modifier.height(12.dp))
                ErrorBlock(message = state.error, onRetry = { onIntent(ScheduleIntent.Retry) })
            }
            return@LazyColumn
        }

        if (state.isLoading && state.raw == null) {
            item {
                Spacer(Modifier.height(16.dp))
                LinearProgressIndicator(Modifier.fillMaxWidth())
            }
            return@LazyColumn
        }

        when (state.viewMode) {
            ScheduleViewMode.DAY -> {
                item {
                    Text(
                        text = dayTitle(state.selectedDate),
                        color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.65f),
                        fontSize = 12.sp,
                        fontWeight = FontWeight.Bold
                    )
                }

                if (state.dayLessons.isEmpty()) {
                    item { EmptyBlock("На выбранный день пар нет.") }
                } else {
                    items(items = state.dayLessons, key = { it.id }) { lesson ->
                        LessonCard(lesson)
                    }
                }
            }

            ScheduleViewMode.WEEK -> {
                state.weekGrouped.forEach { day ->
                    item {
                        Text(
                            text = day.title,
                            color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.65f),
                            fontSize = 12.sp,
                            fontWeight = FontWeight.Bold
                        )
                    }

                    if (day.lessons.isEmpty()) {
                        item { EmptyInline("Нет занятий") }
                    } else {
                        items(items = day.lessons, key = { it.id }) { lesson ->
                            LessonCard(lesson)
                        }
                    }
                }
            }
        }

        val refreshed = (state.raw as? DataResult.Data)?.refreshedFromNetwork
        if (refreshed != null) {
            item {
                Text(
                    text = if (refreshed) "Источник: NETWORK" else "Источник: CACHE",
                    color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.5f),
                    fontSize = 12.sp
                )
            }
        }
    }
}

@Composable
private fun LessonCard(lesson: UiLesson) {
    val shape = RoundedCornerShape(16.dp)
    val borderColor =
        if (lesson.isNow) MaterialTheme.colorScheme.error
        else MaterialTheme.colorScheme.outline.copy(alpha = 0.2f)
    val borderWidth = if (lesson.isNow) 2.dp else 1.dp

    Surface(
        shape = shape,
        tonalElevation = if (lesson.isNow) 2.dp else 0.dp,
        modifier = Modifier
            .fillMaxWidth()
            .border(borderWidth, borderColor, shape)
    ) {
        Column(Modifier.padding(14.dp)) {
            Row(
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier.fillMaxWidth()
            ) {
                Text(
                    text = lesson.time,
                    fontWeight = if (lesson.isNow) FontWeight.Bold else FontWeight.SemiBold,
                    color = if (lesson.isNow) MaterialTheme.colorScheme.error
                    else MaterialTheme.colorScheme.onSurface.copy(alpha = 0.75f)
                )

                if (lesson.isNow) {
                    Spacer(Modifier.width(8.dp))
                    AssistChip(
                        onClick = {},
                        label = { Text("СЕЙЧАС", fontWeight = FontWeight.Black) },
                        colors = AssistChipDefaults.assistChipColors(
                            containerColor = MaterialTheme.colorScheme.error.copy(alpha = 0.12f),
                            labelColor = MaterialTheme.colorScheme.error
                        )
                    )
                }

                Spacer(Modifier.weight(1f))
                LessonBadge(text = lesson.badgeText, kind = lesson.badgeKind)
            }

            Spacer(Modifier.height(8.dp))

            Text(
                text = lesson.title,
                fontSize = 16.sp,
                fontWeight = FontWeight.Bold,
                maxLines = 2,
                overflow = TextOverflow.Ellipsis
            )

            Spacer(Modifier.height(10.dp))

            Row(Modifier.fillMaxWidth()) {
                Text(
                    text = lesson.teacher,
                    modifier = Modifier.weight(1f),
                    color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f),
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
                Text(
                    text = lesson.room,
                    color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f),
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
            }
        }
    }
}

@Composable
private fun LessonBadge(text: String, kind: BadgeKind) {
    val brand = TSUDeskThemeExt.colors
    val (bg, fg) = when (kind) {
        BadgeKind.INFO -> MaterialTheme.colorScheme.primary.copy(alpha = 0.12f) to MaterialTheme.colorScheme.primary
        BadgeKind.PRIMARY -> brand.brandSoft to brand.brand
        BadgeKind.LAB -> MaterialTheme.colorScheme.tertiary.copy(alpha = 0.12f) to MaterialTheme.colorScheme.tertiary
        BadgeKind.MUTED -> MaterialTheme.colorScheme.surfaceVariant to MaterialTheme.colorScheme.onSurfaceVariant
    }

    Surface(color = bg, contentColor = fg, shape = RoundedCornerShape(8.dp)) {
        Text(
            text = text,
            modifier = Modifier.padding(horizontal = 10.dp, vertical = 4.dp),
            fontSize = 10.sp,
            fontWeight = FontWeight.Bold,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis
        )
    }
}

@Composable
private fun ErrorBlock(message: String, onRetry: () -> Unit) {
    Surface(
        shape = RoundedCornerShape(16.dp),
        color = MaterialTheme.colorScheme.errorContainer,
        contentColor = MaterialTheme.colorScheme.onErrorContainer,
        modifier = Modifier.fillMaxWidth()
    ) {
        Column(Modifier.padding(14.dp)) {
            Text("Ошибка", fontWeight = FontWeight.Bold)
            Spacer(Modifier.height(6.dp))
            Text(message)
            Spacer(Modifier.height(10.dp))
            Button(onClick = onRetry) { Text("Повторить") }
        }
    }
}

@Composable
private fun EmptyBlock(text: String) {
    Surface(
        shape = RoundedCornerShape(16.dp),
        color = MaterialTheme.colorScheme.surfaceVariant,
        modifier = Modifier.fillMaxWidth()
    ) {
        Text(
            text = text,
            modifier = Modifier.padding(14.dp),
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )
    }
}

@Composable
private fun EmptyInline(text: String) {
    Text(
        text = text,
        color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.55f),
        fontSize = 12.sp,
        modifier = Modifier.padding(bottom = 8.dp)
    )
}

private fun dayTitle(date: String): String {
    val prefix = if (date == todayString()) "Сегодня" else "День"
    return "$prefix, $date"
}