package ru.forbion.f7cloud.feature.calendar

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
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.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.rememberModalBottomSheetState
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.text.font.FontWeight
import androidx.compose.ui.unit.dp
import ru.forbion.f7cloud.core.designsystem.F7Colors
import ru.forbion.f7cloud.core.designsystem.F7OutlinedField
import ru.forbion.f7cloud.core.designsystem.F7PrimaryButton
import ru.forbion.f7cloud.core.designsystem.F7SecondaryButton
import ru.forbion.f7cloud.core.designsystem.F7TextButton
import java.time.YearMonth

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CalendarYearView(
    year: Int,
    selectedDay: java.time.LocalDate,
    events: List<CalendarEventItem>,
    onSelectMonth: (YearMonth) -> Unit,
    modifier: Modifier = Modifier,
) {
    val months = CalendarRepository.yearMonths(year)
    Column(
        modifier = modifier
            .fillMaxWidth()
            .verticalScroll(rememberScrollState()),
        verticalArrangement = Arrangement.spacedBy(8.dp),
    ) {
        months.chunked(3).forEach { row ->
            Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) {
                row.forEach { month ->
                    val count = events.count { event ->
                        val day = java.time.Instant.ofEpochMilli(event.startEpochMilli)
                            .atZone(java.time.ZoneId.systemDefault()).toLocalDate()
                        day.year == month.year && day.month == month.month
                    }
                    Column(
                        modifier = Modifier
                            .weight(1f)
                            .clip(RoundedCornerShape(10.dp))
                            .background(if (month == YearMonth.from(selectedDay)) F7Colors.PrimaryLight else F7Colors.Surface)
                            .clickable { onSelectMonth(month) }
                            .padding(10.dp),
                    ) {
                        Text(month.month.getDisplayName(java.time.format.TextStyle.FULL_STANDALONE, java.util.Locale.forLanguageTag("ru")), style = MaterialTheme.typography.labelLarge, fontWeight = FontWeight.SemiBold)
                        Text("$count событ.", style = MaterialTheme.typography.labelSmall, color = F7Colors.TextSecondary)
                    }
                }
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CalendarTrashSheet(
    items: List<CalendarTrashItem>,
    onDismiss: () -> Unit,
    onRestore: (CalendarTrashItem) -> Unit,
    onPurge: (CalendarTrashItem) -> Unit,
) {
    val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
    ModalBottomSheet(onDismissRequest = onDismiss, sheetState = sheetState, containerColor = F7Colors.Surface) {
        Column(Modifier.padding(horizontal = 16.dp).padding(bottom = 24.dp)) {
            Text("Корзина", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
            if (items.isEmpty()) Text("Корзина пуста", color = F7Colors.TextSecondary, modifier = Modifier.padding(top = 12.dp))
            items.forEach { item ->
                Column(Modifier.fillMaxWidth().padding(vertical = 8.dp)) {
                    Text(item.summary, fontWeight = FontWeight.SemiBold)
                    Text(item.calendarUri, style = MaterialTheme.typography.labelSmall, color = F7Colors.TextMuted)
                    Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.padding(top = 6.dp)) {
                        F7TextButton(text = "Восстановить", onClick = { onRestore(item) })
                        F7TextButton(text = "Удалить навсегда", onClick = { onPurge(item) })
                    }
                }
                HorizontalDivider(color = F7Colors.Border)
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CalendarTasksSheet(
    tasks: List<CalendarTaskItem>,
    onDismiss: () -> Unit,
) {
    val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
    ModalBottomSheet(onDismissRequest = onDismiss, sheetState = sheetState, containerColor = F7Colors.Surface) {
        Column(Modifier.padding(horizontal = 16.dp).padding(bottom = 24.dp)) {
            Text("Незапланированные задачи", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
            if (tasks.isEmpty()) Text("Нет задач без срока", color = F7Colors.TextSecondary, modifier = Modifier.padding(top = 12.dp))
            tasks.forEach { task ->
                Column(Modifier.padding(vertical = 8.dp)) {
                    Text(task.summary, fontWeight = FontWeight.Medium)
                    Text(task.calendarName, style = MaterialTheme.typography.labelSmall, color = F7Colors.TextMuted)
                }
                HorizontalDivider(color = F7Colors.Border)
            }
        }
    }
}

@Composable
fun CalendarCreateBookDialog(
    draft: CalendarCreateBookDraft,
    saving: Boolean,
    onDismiss: () -> Unit,
    onDraftChange: (CalendarCreateBookDraft) -> Unit,
    onSave: () -> Unit,
) {
    AlertDialog(
        onDismissRequest = { if (!saving) onDismiss() },
        title = { Text("Добавить календарь") },
        text = {
            Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
                CreateBookMode.entries.forEach { mode ->
                    Row(Modifier.fillMaxWidth().clickable { onDraftChange(draft.copy(mode = mode)) }, verticalAlignment = Alignment.CenterVertically) {
                        RadioButton(selected = draft.mode == mode, onClick = { onDraftChange(draft.copy(mode = mode)) })
                        Text(
                            when (mode) {
                                CreateBookMode.NEW -> "Новый календарь"
                                CreateBookMode.WITH_TASKS -> "Календарь со списком задач"
                                CreateBookMode.SUBSCRIBE -> "Подписка по ссылке"
                            },
                            modifier = Modifier.padding(start = 4.dp),
                        )
                    }
                }
                F7OutlinedField(value = draft.name, onValueChange = { onDraftChange(draft.copy(name = it)) }, label = "Название")
                if (draft.mode == CreateBookMode.SUBSCRIBE) {
                    F7OutlinedField(value = draft.subscriptionUrl, onValueChange = { onDraftChange(draft.copy(subscriptionUrl = it)) }, label = "URL подписки (WebCal)")
                }
            }
        },
        confirmButton = { F7PrimaryButton(text = if (saving) "Сохранение…" else "Создать", onClick = onSave, enabled = !saving) },
        dismissButton = { TextButton(onClick = onDismiss) { Text("Отмена") } },
    )
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CalendarAppSettingsSheet(
    settings: CalendarUserSettings,
    onDismiss: () -> Unit,
    onChange: (CalendarUserSettings) -> Unit,
    onImportClick: () -> Unit,
) {
    val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
    ModalBottomSheet(onDismissRequest = onDismiss, sheetState = sheetState, containerColor = F7Colors.Surface) {
        Column(Modifier.padding(16.dp).verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(10.dp)) {
            Text("Параметры календаря", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
            SettingsSwitch("Показывать выходные", settings.showWeekends) { onChange(settings.copy(showWeekends = it)) }
            SettingsSwitch("Номера недель", settings.showWeekNumbers) { onChange(settings.copy(showWeekNumbers = it)) }
            SettingsSwitch("Показывать задачи", settings.showTasks) { onChange(settings.copy(showTasks = it)) }
            SettingsSwitch("Боковая панель задач", settings.tasksSidebar) { onChange(settings.copy(tasksSidebar = it)) }
            F7OutlinedField(
                value = settings.defaultReminderMinutes.toString(),
                onValueChange = { v -> v.toIntOrNull()?.let { onChange(settings.copy(defaultReminderMinutes = it)) } },
                label = "Напоминание по умолчанию (мин)",
            )
            F7SecondaryButton(text = "Импорт .ics", onClick = onImportClick)
        }
    }
}

@Composable
private fun SettingsSwitch(label: String, checked: Boolean, onChecked: (Boolean) -> Unit) {
    Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
        Text(label)
        Switch(checked = checked, onCheckedChange = onChecked)
    }
}

@Composable
fun CalendarFullEventEditorDialog(
    state: CalendarUiState,
    onDismiss: () -> Unit,
    onDraftChange: (CalendarEventDraft) -> Unit,
    onSave: () -> Unit,
    onDelete: () -> Unit,
    onSearchAttendees: (String) -> Unit,
    onAddAttendee: (CalendarAttendeeSuggestion) -> Unit,
    onRemoveAttendee: (String) -> Unit,
    onSearchLocations: (String) -> Unit,
    onApplyLocation: (CalendarLocationSuggestion) -> Unit,
) {
    val draft = state.eventDraft
    val isEdit = state.editorMode == CalendarEditorMode.EDIT
    AlertDialog(
        onDismissRequest = { if (!state.saving && !state.deleting) onDismiss() },
        title = { Text(if (isEdit) "Редактировать событие" else "Создать событие") },
        text = {
            Column(Modifier.fillMaxWidth().heightIn(max = 520.dp).verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(8.dp)) {
                F7OutlinedField(value = draft.title, onValueChange = { onDraftChange(draft.copy(title = it)) }, label = "Название")
                Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
                    Text("Весь день"); Switch(checked = draft.allDay, onCheckedChange = { onDraftChange(draft.copy(allDay = it)) })
                }
                if (!draft.allDay) {
                    F7OutlinedField(value = draft.startTime, onValueChange = { onDraftChange(draft.copy(startTime = it)) }, label = "Начало")
                    F7OutlinedField(value = draft.endTime, onValueChange = { onDraftChange(draft.copy(endTime = it)) }, label = "Окончание")
                }
                Text("Повторение", style = MaterialTheme.typography.labelMedium)
                RecurrencePreset.entries.forEach { preset ->
                    Row(Modifier.clickable { onDraftChange(draft.copy(recurrence = preset, customRrule = "")) }, verticalAlignment = Alignment.CenterVertically) {
                        RadioButton(selected = draft.recurrence == preset, onClick = { onDraftChange(draft.copy(recurrence = preset)) })
                        Text(preset.label, modifier = Modifier.padding(start = 4.dp))
                    }
                }
                F7OutlinedField(value = draft.location, onValueChange = { onSearchLocations(it) }, label = "Место")
                state.locationSuggestions.take(4).forEach { s ->
                    Text(s.address.ifBlank { s.name }, modifier = Modifier.clickable { onApplyLocation(s) }.padding(start = 8.dp), color = F7Colors.Primary)
                }
                Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
                    Text("Комната Talk"); Switch(checked = draft.addTalkRoom, onCheckedChange = { onDraftChange(draft.copy(addTalkRoom = it)) })
                }
                F7OutlinedField(value = draft.description, onValueChange = { onDraftChange(draft.copy(description = it)) }, label = "Описание")
                F7OutlinedField(value = draft.categories, onValueChange = { onDraftChange(draft.copy(categories = it)) }, label = "Категории")
                F7OutlinedField(value = draft.reminderMinutes.toString(), onValueChange = { v -> v.toIntOrNull()?.let { onDraftChange(draft.copy(reminderMinutes = it)) } }, label = "Напоминание (мин)")
                Text("Статус", style = MaterialTheme.typography.labelMedium)
                EventStatus.entries.forEach { st ->
                    Row(Modifier.clickable { onDraftChange(draft.copy(status = st)) }, verticalAlignment = Alignment.CenterVertically) {
                        RadioButton(selected = draft.status == st, onClick = { onDraftChange(draft.copy(status = st)) })
                        Text(st.label, modifier = Modifier.padding(start = 4.dp))
                    }
                }
                Text("Видимость", style = MaterialTheme.typography.labelMedium)
                EventClassification.entries.forEach { cl ->
                    Row(Modifier.clickable { onDraftChange(draft.copy(classification = cl)) }, verticalAlignment = Alignment.CenterVertically) {
                        RadioButton(selected = draft.classification == cl, onClick = { onDraftChange(draft.copy(classification = cl)) })
                        Text(cl.label, modifier = Modifier.padding(start = 4.dp))
                    }
                }
                Text("Участники", style = MaterialTheme.typography.labelMedium)
                F7OutlinedField(value = draft.attendeeQuery, onValueChange = onSearchAttendees, label = "Поиск участника")
                state.attendeeSuggestions.take(5).forEach { s ->
                    Text("${s.name} · ${s.email}", modifier = Modifier.clickable { onAddAttendee(s) }.padding(start = 8.dp), color = F7Colors.Primary)
                }
                draft.attendees.forEach { a ->
                    Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
                        Text("${a.displayName.ifBlank { a.email }}")
                        F7TextButton(text = "✕", onClick = { onRemoveAttendee(a.email) })
                    }
                }
                if (state.calendars.isNotEmpty()) {
                    Text("Календарь", style = MaterialTheme.typography.labelMedium)
                    state.calendars.filter { it.visible }.forEach { cal ->
                        Row(Modifier.clickable { onDraftChange(draft.copy(calendarHref = cal.href)) }, verticalAlignment = Alignment.CenterVertically) {
                            RadioButton(selected = draft.calendarHref == cal.href, onClick = { onDraftChange(draft.copy(calendarHref = cal.href)) })
                            Text(cal.displayName, modifier = Modifier.padding(start = 4.dp))
                        }
                    }
                }
            }
        },
        confirmButton = { F7PrimaryButton(text = if (state.saving) "Сохранение…" else "Сохранить", onClick = onSave, enabled = !state.saving) },
        dismissButton = {
            Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                if (isEdit) TextButton(onClick = onDelete, enabled = !state.deleting) { Text(if (state.deleting) "Удаление…" else "Удалить", color = F7Colors.Error) }
                TextButton(onClick = onDismiss) { Text("Отмена") }
            }
        },
    )
}
