package de.tsschulz.tt_tagebuch.app.ui

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
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.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.Card
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Switch
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import de.tsschulz.tt_tagebuch.app.AppDependencies
import de.tsschulz.tt_tagebuch.app.calendar.CalendarAggregator
import de.tsschulz.tt_tagebuch.app.calendar.CalendarEventAction
import de.tsschulz.tt_tagebuch.app.calendar.CalendarEventType
import de.tsschulz.tt_tagebuch.app.calendar.CalendarUiEvent
import android.util.Log
import de.tsschulz.tt_tagebuch.shared.api.http.ApiException
import de.tsschulz.tt_tagebuch.shared.api.models.ClubCalendarHolidaysEnvelope
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingCancellationUpsertBody
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.supervisorScope
import java.time.LocalDate
import java.time.YearMonth
import java.time.format.DateTimeFormatter
import java.util.Locale

private val monthTitleFmt: DateTimeFormatter = DateTimeFormatter.ofPattern("LLLL yyyy", Locale.GERMAN)
private val wdShort = listOf("Mo", "Di", "Mi", "Do", "Fr", "Sa", "So")

private fun localeForApp(languageCode: String): Locale {
    val tag = languageCode.replace('_', '-')
    return runCatching { Locale.forLanguageTag(tag) }
        .getOrNull()
        ?.takeIf { it.language.isNotBlank() }
        ?: Locale.GERMAN
}

private fun formatAgendaDay(date: LocalDate, locale: Locale): String {
    val fmt = DateTimeFormatter.ofPattern("EEE, dd.MM.", locale)
    return date.format(fmt)
}

private fun formatAgendaEventRange(ev: CalendarUiEvent, locale: Locale): String {
    if (ev.date == ev.endDate) return formatAgendaDay(ev.date, locale)
    return "${formatAgendaDay(ev.date, locale)} – ${formatAgendaDay(ev.endDate, locale)}"
}

private const val CalendarLogTag = "TTCalendar"

/**
 * Fehlende API-Berechtigung (403) ist für den Kalender erwartbar, wenn die Rolle z. B. kein
 * schedule.read hat — dann keine rote „nicht geladen“-Warnung. Andere Fehler erscheinen in Logcat.
 */
private fun recordCalendarSourceFailure(
    result: Result<*>,
    sourceLabel: String,
    warns: MutableList<String>,
) {
    if (result.isSuccess) return
    val err = result.exceptionOrNull() ?: return
    if ((err as? ApiException)?.statusCode == 403) {
        Log.i(
            CalendarLogTag,
            "Kalender-Quelle \"$sourceLabel\": keine Berechtigung (403). ${err.message}",
        )
        return
    }
    Log.w(CalendarLogTag, "Kalender-Quelle \"$sourceLabel\" fehlgeschlagen", err)
    warns.add(sourceLabel)
}

private fun isUnauthorizedCalendarSource(result: Result<*>): Boolean {
    if (result.isSuccess) return false
    return (result.exceptionOrNull() as? ApiException)?.statusCode == 403
}

@Composable
fun CalendarScreen(
    dependencies: AppDependencies,
    onOpenDiaryDate: (Int) -> Unit,
    onOpenDiaryTab: () -> Unit,
    onOpenSchedule: () -> Unit,
    onOpenFriendlyMatches: () -> Unit,
    onOpenTournaments: () -> Unit,
    onOpenOfficialParticipations: () -> Unit,
) {
    val languageCode = LocalLanguageCode.current
    fun tr(key: String, fb: String) = MobileStrings.get(languageCode, key, fb)
    val clubState by dependencies.clubManager.state.collectAsState()
    val clubId = clubState.currentClubId ?: return
    val scope = rememberCoroutineScope()

    var visibleMonthIso by rememberSaveable { mutableStateOf(YearMonth.now().toString()) }
    val yearMonth = remember(visibleMonthIso) {
        runCatching { YearMonth.parse(visibleMonthIso) }.getOrElse { YearMonth.now() }
    }
    val displayedYear = yearMonth.year

    var loading by remember { mutableStateOf(false) }
    var events by remember { mutableStateOf<List<CalendarUiEvent>>(emptyList()) }
    var dataGeneration by remember { mutableIntStateOf(0) }
    val activeTypes = remember { mutableStateMapOf<CalendarEventType, Boolean>() }
    CalendarEventType.entries.forEach { t ->
        if (!activeTypes.containsKey(t)) activeTypes[t] = true
    }
    var sourceWarnings by remember { mutableStateOf<List<String>>(emptyList()) }
    var loadAllSourcesFailed by remember { mutableStateOf(false) }
    var filtersExpanded by rememberSaveable { mutableStateOf(false) }
    var cancellationExpanded by rememberSaveable { mutableStateOf(false) }
    val agendaLocale = remember(languageCode) { localeForApp(languageCode) }

    var cancelStart by remember { mutableStateOf("") }
    var cancelEnd by remember { mutableStateOf("") }
    var cancelReason by remember { mutableStateOf("") }
    var cancelBusy by remember { mutableStateOf(false) }

    LaunchedEffect(clubId, yearMonth, dataGeneration) {
        loading = true
        loadAllSourcesFailed = false
        sourceWarnings = emptyList()
        val warns = mutableListOf<String>()
        supervisorScope {
            val diaryR = async { runCatching { dependencies.diaryManager.listDates(clubId) } }
            val ttR = async { runCatching { dependencies.membersManager.trainingScheduleGroups(clubId) } }
            val canR = async { runCatching { dependencies.trainingCancellationApi.list(clubId, displayedYear) } }
            val tourR = async { runCatching { dependencies.tournamentsApi.listTournaments(clubId) } }
            val matchR = async { runCatching { dependencies.matchesApi.listMatchesForLeagues(clubId) } }
            val friendlyR = async { runCatching { dependencies.matchesApi.listFriendlyMatches(clubId) } }
            val offR = async { runCatching { dependencies.officialTournamentsReadManager.fetchParticipationSummary(clubId) } }
            val holR = async { runCatching { dependencies.calendarHolidayApi.getClubHolidays(clubId, displayedYear) } }

            val dr = diaryR.await()
            val ttr = ttR.await()
            val canr = canR.await()
            val tourr = tourR.await()
            val matchr = matchR.await()
            val friendlyr = friendlyR.await()
            val offr = offR.await()
            val holr = holR.await()

            recordCalendarSourceFailure(dr, tr("mobile.calendarSourceDiary", "Tagebuch"), warns)
            recordCalendarSourceFailure(ttr, tr("mobile.calendarSourceTrainingTimes", "Trainingszeiten"), warns)
            recordCalendarSourceFailure(canr, tr("mobile.calendarSourceCancellations", "Trainingsausfälle"), warns)
            recordCalendarSourceFailure(tourr, tr("mobile.calendarSourceTournaments", "Turniere"), warns)
            recordCalendarSourceFailure(matchr, tr("mobile.calendarSourceMatches", "Punktspiele"), warns)
            recordCalendarSourceFailure(friendlyr, tr("mobile.calendarSourceFriendlyMatches", "Freundschaftsspiele"), warns)
            recordCalendarSourceFailure(offr, tr("mobile.calendarSourceOfficial", "Turnierteilnahmen"), warns)
            recordCalendarSourceFailure(holr, tr("mobile.calendarSourceHolidays", "Ferien/Feiertage"), warns)

            val results = listOf(dr, ttr, canr, tourr, matchr, friendlyr, offr, holr)
            loadAllSourcesFailed =
                results.all { it.isFailure } &&
                    results.any { !isUnauthorizedCalendarSource(it) }

            events = CalendarAggregator.buildAll(
                displayedYear = displayedYear,
                diary = dr.getOrDefault(emptyList()),
                trainingGroups = ttr.getOrDefault(emptyList()),
                cancellations = canr.getOrDefault(emptyList()),
                tournaments = tourr.getOrDefault(emptyList()),
                matches = matchr.getOrDefault(emptyList()),
                friendlyMatches = friendlyr.getOrDefault(emptyList()),
                official = offr.getOrDefault(emptyList()),
                holidays = holr.getOrElse { ClubCalendarHolidaysEnvelope() },
            )
        }
        sourceWarnings = warns.distinct()
        loading = false
    }

    val activeSnapshot = activeTypes.toMap()
    val filtered = remember(events, activeSnapshot) {
        events.filter { activeSnapshot[it.type] != false }
    }
    val visibleMonthEvents = remember(filtered, yearMonth) {
        CalendarAggregator.eventsInMonth(filtered, yearMonth)
    }
    val gridStart = remember(yearMonth) { CalendarAggregator.monthGridStart(yearMonth) }
    val gridCells = remember(gridStart) { CalendarAggregator.monthGridCells(gridStart) }

    fun typeLabel(t: CalendarEventType): String = when (t) {
        CalendarEventType.Training -> tr("mobile.calendarLegendTraining", "Training")
        CalendarEventType.Tournament -> tr("mobile.calendarLegendTournament", "Turnier")
        CalendarEventType.OfficialTournament -> tr("mobile.calendarLegendOfficial", "Teilnahme")
        CalendarEventType.Match -> tr("mobile.calendarLegendMatch", "Punktspiel")
        CalendarEventType.FriendlyMatch -> tr("mobile.calendarLegendFriendlyMatch", "Freundschaftsspiel")
        CalendarEventType.Holiday -> tr("mobile.calendarLegendHoliday", "Feiertag")
        CalendarEventType.SchoolHoliday -> tr("mobile.calendarLegendSchool", "Ferien")
        CalendarEventType.TrainingCancellation -> tr("mobile.calendarLegendCancellation", "Ausfall")
    }

    @Composable
    fun eventColor(t: CalendarEventType) = when (t) {
        CalendarEventType.Training -> MaterialTheme.colors.primary
        CalendarEventType.Tournament -> MaterialTheme.colors.secondary
        CalendarEventType.OfficialTournament -> MaterialTheme.colors.secondaryVariant
        CalendarEventType.Match -> MaterialTheme.colors.primaryVariant
        CalendarEventType.FriendlyMatch -> MaterialTheme.colors.secondary.copy(alpha = 0.9f)
        CalendarEventType.Holiday -> MaterialTheme.colors.error.copy(alpha = 0.75f)
        CalendarEventType.SchoolHoliday -> MaterialTheme.colors.error.copy(alpha = 0.45f)
        CalendarEventType.TrainingCancellation -> MaterialTheme.colors.onSurface.copy(alpha = 0.55f)
    }

    fun onEventClick(e: CalendarUiEvent) {
        when (e.action) {
            CalendarEventAction.OpenDiaryDate -> e.diaryDateId?.let { onOpenDiaryDate(it) }
            CalendarEventAction.OpenDiaryTab -> onOpenDiaryTab()
            CalendarEventAction.OpenSchedule -> {
                if (e.type == CalendarEventType.FriendlyMatch) onOpenFriendlyMatches()
                else onOpenSchedule()
            }
            CalendarEventAction.OpenTournaments -> onOpenTournaments()
            CalendarEventAction.OpenOfficialParticipations -> onOpenOfficialParticipations()
            CalendarEventAction.None -> Unit
        }
    }

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .verticalScroll(rememberScrollState())
            .padding(horizontal = 16.dp, vertical = 12.dp),
    ) {
        Text(tr("mobile.calendarTitle", "Kalender"), style = MaterialTheme.typography.h6)
        Text(
            tr("mobile.calendarSubtitle", "Training, Turniere, Spiele und Feiertage im Monat."),
            style = MaterialTheme.typography.caption,
            color = MaterialTheme.colors.onSurface.copy(alpha = 0.72f),
        )
        Row(
            Modifier.fillMaxWidth().padding(top = 12.dp),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically,
        ) {
            TextButton(onClick = {
                val p = yearMonth.minusMonths(1)
                visibleMonthIso = p.toString()
            }) { Text("‹") }
            TextButton(onClick = {
                visibleMonthIso = YearMonth.now().toString()
            }) { Text(tr("mobile.calendarToday", "Heute")) }
            TextButton(onClick = {
                val n = yearMonth.plusMonths(1)
                visibleMonthIso = n.toString()
            }) { Text("›") }
        }
        val titleRaw = yearMonth.format(monthTitleFmt)
        Text(
            titleRaw.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.GERMAN) else it.toString() },
            style = MaterialTheme.typography.subtitle1,
            fontWeight = FontWeight.SemiBold,
            modifier = Modifier.padding(bottom = 8.dp),
        )
        if (loading) {
            CircularProgressIndicator(modifier = Modifier.padding(vertical = 8.dp))
        }
        if (loadAllSourcesFailed && !loading) {
            Text(
                tr("mobile.calendarAllSourcesFailed", "Kalenderdaten konnten nicht geladen werden."),
                color = MaterialTheme.colors.error,
                style = MaterialTheme.typography.body2,
                fontWeight = FontWeight.Medium,
                modifier = Modifier.padding(bottom = 8.dp),
            )
        }
        if (sourceWarnings.isNotEmpty()) {
            Text(
                sourceWarnings.joinToString(" · ") { "$it ${tr("mobile.calendarSourceFailed", "nicht geladen")}" },
                color = MaterialTheme.colors.error,
                style = MaterialTheme.typography.caption,
                modifier = Modifier.padding(bottom = 8.dp),
            )
        }
        Row(
            modifier = Modifier.fillMaxWidth().padding(top = 4.dp),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Text(tr("mobile.calendarLegend", "Anzeige"), style = MaterialTheme.typography.caption, fontWeight = FontWeight.Medium)
            TextButton(onClick = { filtersExpanded = !filtersExpanded }) {
                Text(
                    if (filtersExpanded) {
                        tr("mobile.calendarHideFilters", "Filter ausblenden ▲")
                    } else {
                        tr("mobile.calendarShowFilters", "Filter anzeigen ▼")
                    },
                    style = MaterialTheme.typography.caption,
                )
            }
        }
        if (filtersExpanded) {
            CalendarEventType.entries.chunked(2).forEach { rowTypes ->
                Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                    rowTypes.forEach { t ->
                        val count = events.count { it.type == t }
                        Row(
                            verticalAlignment = Alignment.CenterVertically,
                            modifier = Modifier.weight(1f).padding(vertical = 2.dp),
                        ) {
                            Switch(
                                checked = activeTypes[t] != false,
                                onCheckedChange = { activeTypes[t] = it },
                            )
                            Text(
                                "${typeLabel(t)} ($count)",
                                style = MaterialTheme.typography.caption,
                                modifier = Modifier.padding(start = 4.dp),
                            )
                        }
                    }
                }
            }
        }
        Row(
            modifier = Modifier.fillMaxWidth().padding(top = 12.dp),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Text(tr("mobile.calendarCancellationTitle", "Training fällt aus"), style = MaterialTheme.typography.subtitle2)
            TextButton(onClick = { cancellationExpanded = !cancellationExpanded }) {
                Text(
                    if (cancellationExpanded) {
                        tr("mobile.calendarHideCancellation", "Bereich ausblenden ▲")
                    } else {
                        tr("mobile.calendarShowCancellation", "Bereich anzeigen ▼")
                    },
                    style = MaterialTheme.typography.caption,
                )
            }
        }
        if (cancellationExpanded) {
            Card(Modifier.fillMaxWidth(), elevation = 1.dp) {
                Column(Modifier.padding(12.dp)) {
                    Text(
                        tr("mobile.calendarCancellationHint", "Blendet regelmäßige Trainingszeiten an den Tagen aus."),
                        style = MaterialTheme.typography.caption,
                        color = MaterialTheme.colors.onSurface.copy(alpha = 0.7f),
                    )
                    LocalizedDatePickerField(
                        value = cancelStart,
                        onValueChange = { cancelStart = it },
                        label = tr("mobile.calendarCancellationStart", "Datum"),
                        modifier = Modifier.fillMaxWidth().padding(top = 8.dp),
                    )
                    LocalizedDatePickerField(
                        value = cancelEnd,
                        onValueChange = { cancelEnd = it },
                        label = tr("mobile.calendarCancellationEnd", "Bis"),
                        modifier = Modifier.fillMaxWidth().padding(top = 4.dp),
                        placeholder = tr("mobile.calendarCancellationEnd", "Bis optional"),
                    )
                    OutlinedTextField(
                        value = cancelReason,
                        onValueChange = { cancelReason = it },
                        label = { Text(tr("mobile.calendarCancellationReason", "Grund")) },
                        modifier = Modifier.fillMaxWidth().padding(top = 4.dp),
                        singleLine = true,
                    )
                    Button(
                        onClick = {
                            if (cancelStart.length < 10) return@Button
                            scope.launch {
                                cancelBusy = true
                                runCatching {
                                    val end = cancelEnd.trim().ifBlank { cancelStart.trim() }
                                    dependencies.trainingCancellationApi.upsert(
                                        clubId,
                                        TrainingCancellationUpsertBody(
                                            startDate = cancelStart.trim().take(10),
                                            endDate = end.take(10),
                                            reason = cancelReason.trim().ifBlank { null },
                                        ),
                                    )
                                    cancelStart = ""
                                    cancelEnd = ""
                                    cancelReason = ""
                                    dataGeneration++
                                }
                                cancelBusy = false
                            }
                        },
                        enabled = !cancelBusy && cancelStart.length >= 10,
                        modifier = Modifier.fillMaxWidth().padding(top = 8.dp).heightIn(min = 48.dp),
                    ) { Text(if (cancelBusy) "…" else tr("mobile.calendarCancellationSave", "Eintragen")) }
                    val monthCancels = events
                        .filter { it.type == CalendarEventType.TrainingCancellation && it.cancellationId != null }
                        .filter { it.date.year == yearMonth.year && it.date.monthValue == yearMonth.monthValue }
                        .sortedBy { it.startsAtSort }
                    if (monthCancels.isNotEmpty()) {
                        Text(tr("mobile.calendarCancellationInMonth", "Ausfälle diesen Monat"), modifier = Modifier.padding(top = 12.dp), fontWeight = FontWeight.Medium)
                        monthCancels.forEach { c ->
                            Row(
                                Modifier.fillMaxWidth().padding(vertical = 4.dp),
                                horizontalArrangement = Arrangement.SpaceBetween,
                                verticalAlignment = Alignment.CenterVertically,
                            ) {
                                Column(Modifier.weight(1f)) {
                                    Text("${formatIsoDateForDisplay(c.dateIso)}–${formatIsoDateForDisplay(c.endDateIso)}", style = MaterialTheme.typography.caption)
                                    Text(c.title, style = MaterialTheme.typography.body2, maxLines = 1, overflow = TextOverflow.Ellipsis)
                                }
                                TextButton(
                                    onClick = {
                                        val id = c.cancellationId ?: return@TextButton
                                        scope.launch {
                                            runCatching {
                                                dependencies.trainingCancellationApi.delete(clubId, id)
                                                dataGeneration++
                                            }
                                        }
                                    },
                                ) { Text(tr("common.delete", "Löschen"), color = MaterialTheme.colors.error) }
                            }
                        }
                    }
                }
            }
        }
        Text(tr("mobile.calendarGridTitle", "Monat"), style = MaterialTheme.typography.subtitle2, modifier = Modifier.padding(top = 16.dp))
        Row(Modifier.fillMaxWidth()) {
            wdShort.forEach { w ->
                Text(w, style = MaterialTheme.typography.caption, modifier = Modifier.weight(1f), fontWeight = FontWeight.Medium)
            }
        }
        gridCells.chunked(7).forEach { week ->
            Row(Modifier.fillMaxWidth().padding(vertical = 2.dp)) {
                week.forEach { day ->
                    val inMonth = day.month == yearMonth.month
                    val today = day == LocalDate.now()
                    val dayEvents = CalendarAggregator.eventsForDay(filtered, day)
                    Column(
                        Modifier
                            .weight(1f)
                            .padding(2.dp)
                            .border(1.dp, MaterialTheme.colors.onSurface.copy(alpha = 0.12f))
                            .background(
                                when {
                                    today -> MaterialTheme.colors.primary.copy(alpha = 0.08f)
                                    !inMonth -> MaterialTheme.colors.onSurface.copy(alpha = 0.04f)
                                    else -> MaterialTheme.colors.surface
                                },
                            )
                            .padding(4.dp)
                            .heightIn(min = 72.dp),
                    ) {
                        Text(
                            "${day.dayOfMonth}",
                            style = MaterialTheme.typography.caption,
                            fontWeight = if (today) FontWeight.Bold else FontWeight.Normal,
                            color = if (inMonth) MaterialTheme.colors.onSurface else MaterialTheme.colors.onSurface.copy(alpha = 0.45f),
                        )
                        dayEvents.take(2).forEach { ev ->
                            Text(
                                buildString {
                                    if (ev.timeLabel.isNotBlank()) append(ev.timeLabel).append(" ")
                                    append(ev.title)
                                },
                                style = MaterialTheme.typography.caption,
                                color = eventColor(ev.type),
                                maxLines = 2,
                                overflow = TextOverflow.Ellipsis,
                                modifier = Modifier
                                    .padding(top = 2.dp)
                                    .clickable { onEventClick(ev) },
                            )
                        }
                        if (dayEvents.size > 2) {
                            Text(
                                "+${dayEvents.size - 2}",
                                style = MaterialTheme.typography.caption,
                                color = MaterialTheme.colors.onSurface.copy(alpha = 0.5f),
                            )
                        }
                    }
                }
            }
        }
        Text(tr("mobile.calendarAgendaTitle", "Termine im Monat"), style = MaterialTheme.typography.subtitle2, modifier = Modifier.padding(top = 16.dp))
        if (visibleMonthEvents.isEmpty()) {
            Text(tr("mobile.calendarAgendaEmpty", "Keine Termine in diesem Monat."), style = MaterialTheme.typography.caption)
        } else {
            visibleMonthEvents.forEach { ev ->
                Card(
                    Modifier
                        .fillMaxWidth()
                        .padding(vertical = 4.dp)
                        .clickable { onEventClick(ev) },
                    elevation = 1.dp,
                ) {
                    Row(
                        Modifier.padding(10.dp),
                        horizontalArrangement = Arrangement.SpaceBetween,
                        verticalAlignment = Alignment.CenterVertically,
                    ) {
                        Column(Modifier.weight(1f)) {
                            val dr = formatAgendaEventRange(ev, agendaLocale)
                            Text(dr, style = MaterialTheme.typography.caption, color = eventColor(ev.type))
                            Text(ev.title, fontWeight = FontWeight.Medium, maxLines = 2, overflow = TextOverflow.Ellipsis)
                            if (ev.subtitle.isNotBlank()) {
                                Text(ev.subtitle, style = MaterialTheme.typography.caption, maxLines = 1, overflow = TextOverflow.Ellipsis)
                            }
                        }
                        if (ev.timeLabel.isNotBlank()) {
                            Text(ev.timeLabel, style = MaterialTheme.typography.caption)
                        }
                    }
                }
            }
        }
        Spacer(Modifier.height(24.dp))
    }
}
