package org.zaine.management.ui

import android.content.Context
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
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.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Button
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.Checkbox
import androidx.compose.material3.DatePicker
import androidx.compose.material3.DatePickerDialog
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
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.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.zaine.management.data.api.CalendarEventDto
import org.zaine.management.data.api.TodayStatusDto
import org.zaine.management.data.api.WirdEntryDto
import java.time.Instant
import java.time.LocalDate
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.time.temporal.TemporalAdjusters

@Composable
fun ZManagementRoot(
    darkMode: Boolean,
    onDarkModeChange: (Boolean) -> Unit,
    rootViewModel: RootViewModel = hiltViewModel()
) {
    var route by remember { mutableStateOf(rootViewModel.startRoute) }
    val settings = LocalContext.current.getSharedPreferences("settings", Context.MODE_PRIVATE)
    var morningReminder by rememberSaveable { mutableStateOf(settings.getBoolean("morning_reminder", true)) }
    var eveningReminder by rememberSaveable { mutableStateOf(settings.getBoolean("evening_reminder", true)) }
    var overloadAlerts by rememberSaveable { mutableStateOf(settings.getBoolean("overload_alerts", true)) }
    var privateMode by rememberSaveable { mutableStateOf(settings.getBoolean("private_mode", false)) }
    var compactHistory by rememberSaveable { mutableStateOf(settings.getBoolean("compact_history", false)) }

    AppScaffold(route = route, onRoute = { route = it }) { padding ->
        when (val current = route) {
            AppRoute.Login -> LoginScreen(
                modifier = Modifier.padding(padding),
                onLoggedIn = { route = AppRoute.Today }
            )
            AppRoute.Today -> TodayScreen(
                modifier = Modifier.padding(padding),
                onMorning = { route = AppRoute.Morning },
                onEvening = { route = AppRoute.Evening },
                onCalendar = { route = AppRoute.Calendar },
                onEvent = { route = AppRoute.EventDetails(it) }
            )
            AppRoute.Morning -> MorningScreen(
                modifier = Modifier.padding(padding),
                onDone = { route = AppRoute.Today }
            )
            AppRoute.Evening -> EveningScreen(
                modifier = Modifier.padding(padding),
                onDone = { route = AppRoute.Today }
            )
            AppRoute.Calendar -> CalendarScreen(
                modifier = Modifier.padding(padding),
                onEvent = { route = AppRoute.EventDetails(it) }
            )
            AppRoute.Wird -> WirdScreen(modifier = Modifier.padding(padding))
            AppRoute.History -> HistoryScreen(
                privateMode = privateMode,
                compact = compactHistory,
                modifier = Modifier.padding(padding)
            )
            AppRoute.Settings -> SettingsScreen(
                darkMode = darkMode,
                onDarkModeChange = onDarkModeChange,
                morningReminder = morningReminder,
                onMorningReminderChange = {
                    morningReminder = it
                    settings.edit().putBoolean("morning_reminder", it).apply()
                },
                eveningReminder = eveningReminder,
                onEveningReminderChange = {
                    eveningReminder = it
                    settings.edit().putBoolean("evening_reminder", it).apply()
                },
                overloadAlerts = overloadAlerts,
                onOverloadAlertsChange = {
                    overloadAlerts = it
                    settings.edit().putBoolean("overload_alerts", it).apply()
                },
                privateMode = privateMode,
                onPrivateModeChange = {
                    privateMode = it
                    settings.edit().putBoolean("private_mode", it).apply()
                },
                compactHistory = compactHistory,
                onCompactHistoryChange = {
                    compactHistory = it
                    settings.edit().putBoolean("compact_history", it).apply()
                },
                modifier = Modifier.padding(padding)
            )
            is AppRoute.EventDetails -> EventDetailsScreen(
                eventId = current.id,
                modifier = Modifier.padding(padding),
                onBack = { route = AppRoute.Calendar }
            )
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun AppScaffold(
    route: AppRoute,
    onRoute: (AppRoute) -> Unit,
    content: @Composable (PaddingValues) -> Unit
) {
    Scaffold(
        topBar = {
            CenterAlignedTopAppBar(title = {
                Text(
                    when (route) {
                        AppRoute.Login -> "Sign in"
                        AppRoute.Today -> "Today"
                        AppRoute.Morning -> "Morning"
                        AppRoute.Evening -> "Evening"
                        AppRoute.Calendar -> "Calendar"
                        AppRoute.Wird -> "Wird"
                        AppRoute.History -> "History"
                        AppRoute.Settings -> "Settings"
                        is AppRoute.EventDetails -> "Event"
                    }
                )
            })
        },
        bottomBar = {
            if (route != AppRoute.Login) {
                NavigationBar {
                    NavigationBarItem(
                        selected = route == AppRoute.Today,
                        onClick = { onRoute(AppRoute.Today) },
                        icon = {},
                        label = { Text("Today") }
                    )
                    NavigationBarItem(
                        selected = route == AppRoute.Calendar,
                        onClick = { onRoute(AppRoute.Calendar) },
                        icon = {},
                        label = { Text("Calendar") }
                    )
                    NavigationBarItem(
                        selected = route == AppRoute.Wird,
                        onClick = { onRoute(AppRoute.Wird) },
                        icon = {},
                        label = { Text("Wird") }
                    )
                    NavigationBarItem(
                        selected = route == AppRoute.History,
                        onClick = { onRoute(AppRoute.History) },
                        icon = {},
                        label = { Text("History") }
                    )
                    NavigationBarItem(
                        selected = route == AppRoute.Settings,
                        onClick = { onRoute(AppRoute.Settings) },
                        icon = {},
                        label = { Text("Settings") }
                    )
                }
            }
        },
        content = content
    )
}

@Composable
private fun LoginScreen(
    modifier: Modifier = Modifier,
    onLoggedIn: () -> Unit,
    viewModel: LoginViewModel = hiltViewModel()
) {
    val state by viewModel.state.collectAsStateWithLifecycle()
    LaunchedEffect(state.loggedIn) {
        if (state.loggedIn) onLoggedIn()
    }

    Column(
        modifier = modifier.fillMaxSize().padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        OutlinedTextField(
            value = state.baseUrl,
            onValueChange = viewModel::setBaseUrl,
            label = { Text("Backend URL") },
            modifier = Modifier.fillMaxWidth(),
            singleLine = true
        )
        OutlinedTextField(
            value = state.username,
            onValueChange = viewModel::setUsername,
            label = { Text("Username") },
            modifier = Modifier.fillMaxWidth(),
            singleLine = true
        )
        OutlinedTextField(
            value = state.password,
            onValueChange = viewModel::setPassword,
            label = { Text("Password") },
            modifier = Modifier.fillMaxWidth(),
            singleLine = true,
            visualTransformation = PasswordVisualTransformation()
        )
        if (state.error != null) Text(state.error!!, color = MaterialTheme.colorScheme.error)
        Button(onClick = viewModel::login, enabled = !state.loading, modifier = Modifier.fillMaxWidth()) {
            Text(if (state.loading) "Signing in" else "Sign in")
        }
    }
}

@Composable
private fun TodayScreen(
    modifier: Modifier = Modifier,
    onMorning: () -> Unit,
    onEvening: () -> Unit,
    onCalendar: () -> Unit,
    onEvent: (Long) -> Unit,
    viewModel: TodayViewModel = hiltViewModel()
) {
    val state by viewModel.state.collectAsStateWithLifecycle()
    ScreenState(state.loading, state.error, viewModel::refresh) {
        val data = state.data
        LazyColumn(
            modifier = modifier.fillMaxSize(),
            contentPadding = PaddingValues(16.dp),
            verticalArrangement = Arrangement.spacedBy(12.dp)
        ) {
            item {
                SectionCard("Check-ins") {
                    val status = data?.status
                    Text("Morning: ${if (status?.morningDone == true) "done" else "not done"}")
                    Text("Evening: ${if (status?.eveningDone == true) "done" else "pending"}")
                    Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                        Button(onClick = onMorning, modifier = Modifier.weight(1f)) { Text("Morning") }
                        Button(onClick = onEvening, modifier = Modifier.weight(1f)) { Text("Evening") }
                    }
                }
            }
            item {
                SectionCard("Today") {
                    val status = data?.status
                    Text("Fajr: ${yesNo(status?.fajr)}")
                    Text("Quran: ${yesNo(status?.quran)}")
                    Text("Exercise: ${yesNo(status?.exercise)}")
                    Text("Duties: ${yesNo(status?.duties)}")
                    Text("Zikr: ${yesNo(status?.zikr)}")
                    Text("Salah: ${yesNo(status?.salah)}")
                }
            }
            item {
                SectionCard("Today's events") {
                    if (data?.events.isNullOrEmpty()) {
                        Text("No events today")
                    } else {
                        data.events.forEach { event ->
                            EventRow(event = event, onClick = { onEvent(event.id) })
                        }
                    }
                    TextButton(onClick = onCalendar) { Text("Open calendar") }
                }
            }
        }
    }
}

@Composable
private fun MorningScreen(
    modifier: Modifier = Modifier,
    onDone: () -> Unit,
    viewModel: MorningViewModel = hiltViewModel()
) {
    val state by viewModel.state.collectAsStateWithLifecycle()
    LaunchedEffect(state.saved) { if (state.saved) onDone() }
    LazyColumn(
        modifier = modifier.fillMaxSize(),
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        item {
            OutlinedTextField(
                value = state.sleepHours,
                onValueChange = viewModel::setSleepHours,
                label = { Text("Sleep hours") },
                modifier = Modifier.fillMaxWidth(),
                singleLine = true
            )
        }
        item { CheckRow("Fajr", state.fajr, viewModel::setFajr) }
        item { CheckRow("Quran", state.quran, viewModel::setQuran) }
        item { CheckRow("Exercise", state.exercise, viewModel::setExercise) }
        item { MultiLineField("Note", state.note, viewModel::setNote) }
        item {
            if (state.error != null) Text(state.error!!, color = MaterialTheme.colorScheme.error)
            Button(onClick = viewModel::submit, enabled = !state.loading, modifier = Modifier.fillMaxWidth()) {
                Text(if (state.loading) "Saving" else "Save morning")
            }
        }
    }
}

@Composable
private fun EveningScreen(
    modifier: Modifier = Modifier,
    onDone: () -> Unit,
    viewModel: EveningViewModel = hiltViewModel()
) {
    val state by viewModel.state.collectAsStateWithLifecycle()
    LaunchedEffect(state.saved) { if (state.saved) onDone() }
    LazyColumn(
        modifier = modifier.fillMaxSize(),
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        item { CheckRow("Duties", state.duties, viewModel::setDuties) }
        item { CheckRow("Zikr", state.zikr, viewModel::setZikr) }
        item { CheckRow("Salah", state.salah, viewModel::setSalah) }
        item { MultiLineField("Reflection", state.reflection, viewModel::setReflection) }
        item {
            if (state.error != null) Text(state.error!!, color = MaterialTheme.colorScheme.error)
            Button(onClick = viewModel::submit, enabled = !state.loading, modifier = Modifier.fillMaxWidth()) {
                Text(if (state.loading) "Saving" else "Save evening")
            }
        }
    }
}

@Composable
private fun CalendarScreen(
    modifier: Modifier = Modifier,
    onEvent: (Long) -> Unit,
    viewModel: CalendarViewModel = hiltViewModel()
) {
    val state by viewModel.state.collectAsStateWithLifecycle()
    LazyColumn(
        modifier = modifier.fillMaxSize(),
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        item {
            Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                CalendarModeButton("Day", state.mode == CalendarViewMode.Day) { viewModel.setMode(CalendarViewMode.Day) }
                CalendarModeButton("Week", state.mode == CalendarViewMode.Week) { viewModel.setMode(CalendarViewMode.Week) }
                CalendarModeButton("Month", state.mode == CalendarViewMode.Month) { viewModel.setMode(CalendarViewMode.Month) }
            }
        }
        item {
            Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
                TextButton(onClick = {
                    when (state.mode) {
                        CalendarViewMode.Day -> viewModel.previousDay()
                        CalendarViewMode.Week -> viewModel.previousWeek()
                        CalendarViewMode.Month -> viewModel.previousMonth()
                    }
                }) { Text("Previous") }
                Text(
                    calendarTitle(state),
                    style = MaterialTheme.typography.titleMedium
                )
                TextButton(onClick = {
                    when (state.mode) {
                        CalendarViewMode.Day -> viewModel.nextDay()
                        CalendarViewMode.Week -> viewModel.nextWeek()
                        CalendarViewMode.Month -> viewModel.nextMonth()
                    }
                }) { Text("Next") }
            }
        }
        item {
            ScreenState(state.loading, state.error, viewModel::refresh) {
                Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
                    if (state.events.isEmpty()) Text("No events")
                    state.events.forEach { event -> EventRow(event, onClick = { onEvent(event.id) }) }
                }
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun WirdScreen(
    modifier: Modifier = Modifier,
    viewModel: WirdViewModel = hiltViewModel()
) {
    val state by viewModel.state.collectAsStateWithLifecycle()
    val selectedMeta = dailyWirdTypes.first { it.key == state.wirdType }
    var showDatePicker by remember { mutableStateOf(false) }
    val pickerState = rememberDatePickerState(
        initialSelectedDateMillis = LocalDate.parse(state.date).atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
    )

    if (showDatePicker) {
        DatePickerDialog(
            onDismissRequest = { showDatePicker = false },
            confirmButton = {
                TextButton(
                    onClick = {
                        pickerState.selectedDateMillis?.let { millis ->
                            viewModel.setDate(Instant.ofEpochMilli(millis).atZone(ZoneOffset.UTC).toLocalDate().toString())
                        }
                        showDatePicker = false
                    }
                ) { Text("Set") }
            },
            dismissButton = {
                TextButton(onClick = { showDatePicker = false }) { Text("Cancel") }
            }
        ) {
            DatePicker(state = pickerState)
        }
    }

    LazyColumn(
        modifier = modifier.fillMaxSize(),
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        item {
            Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
                Text(state.date, style = MaterialTheme.typography.titleMedium)
                TextButton(onClick = { showDatePicker = true }) { Text("Pick date") }
            }
        }
        item {
            SectionCard("Daily wird") {
                ScreenState(state.loading, state.error, viewModel::refresh) {
                    Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
                        dailyWirdTypes.forEach { meta ->
                            WirdProgressRow(
                                meta = meta,
                                entries = state.entries,
                                selected = meta.key == state.wirdType,
                                onClick = { viewModel.setWirdType(meta.key) }
                            )
                        }
                    }
                }
            }
        }
        item {
            SectionCard("Log ${selectedMeta.label}") {
                Text("Target: ${selectedMeta.target} ${selectedMeta.unit}")
                if (selectedMeta.kind == WirdValueKind.Rating) {
                    Row(horizontalArrangement = Arrangement.spacedBy(6.dp), modifier = Modifier.fillMaxWidth()) {
                        (1..5).forEach { rating ->
                            CalendarModeButton(
                                label = rating.toString(),
                                selected = state.value == rating.toString(),
                                onClick = { viewModel.setValue(rating.toString()) }
                            )
                        }
                    }
                } else {
                    OutlinedTextField(
                        value = state.value,
                        onValueChange = viewModel::setValue,
                        label = { Text(wirdValueLabel(selectedMeta)) },
                        modifier = Modifier.fillMaxWidth(),
                        singleLine = true,
                        placeholder = { Text("Target: ${selectedMeta.target} ${selectedMeta.unit}") }
                    )
                }
                MultiLineField("Notes", state.notes, viewModel::setNotes)
                if (state.saved) Text("Saved")
                if (state.error != null) Text(state.error!!, color = MaterialTheme.colorScheme.error)
                Button(onClick = viewModel::submit, enabled = !state.loading, modifier = Modifier.fillMaxWidth()) {
                    Text(if (state.loading) "Saving" else "Save wird")
                }
            }
        }
        item {
            SectionCard("Entries for ${state.date}") {
                ScreenState(state.loading, state.error, viewModel::refresh) {
                    if (state.entries.isEmpty()) Text("No entries")
                    state.entries.forEach { WirdRow(it) }
                }
            }
        }
    }
}

@Composable
private fun HistoryScreen(
    privateMode: Boolean,
    compact: Boolean,
    modifier: Modifier = Modifier,
    viewModel: HistoryViewModel = hiltViewModel()
) {
    val state by viewModel.state.collectAsStateWithLifecycle()
    LazyColumn(
        modifier = modifier.fillMaxSize(),
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        item {
            Text(
                "${state.from.format(DateTimeFormatter.ofPattern("d MMM"))} - ${state.to.format(DateTimeFormatter.ofPattern("d MMM yyyy"))}",
                style = MaterialTheme.typography.titleMedium
            )
        }
        item {
            ScreenState(state.loading, state.error, viewModel::refresh) {
                Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
                    SectionCard("Check-ins") {
                        if (state.checkins.isEmpty()) Text("No check-ins")
                        state.checkins.forEach { CheckinHistoryRow(it, compact, privateMode) }
                    }
                    SectionCard("Wird") {
                        if (state.wirdEntries.isEmpty()) Text("No wird entries")
                        state.wirdEntries.forEach { WirdHistoryRow(it, privateMode) }
                    }
                }
            }
        }
    }
}

@Composable
private fun SettingsScreen(
    darkMode: Boolean,
    onDarkModeChange: (Boolean) -> Unit,
    morningReminder: Boolean,
    onMorningReminderChange: (Boolean) -> Unit,
    eveningReminder: Boolean,
    onEveningReminderChange: (Boolean) -> Unit,
    overloadAlerts: Boolean,
    onOverloadAlertsChange: (Boolean) -> Unit,
    privateMode: Boolean,
    onPrivateModeChange: (Boolean) -> Unit,
    compactHistory: Boolean,
    onCompactHistoryChange: (Boolean) -> Unit,
    modifier: Modifier = Modifier
) {
    LazyColumn(
        modifier = modifier.fillMaxSize(),
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        item {
            SectionCard("Appearance") {
                SettingToggleRow("Dark mode", "Use a lower-glare color theme", darkMode, onDarkModeChange)
                SettingToggleRow("Compact history", "Show shorter history rows", compactHistory, onCompactHistoryChange)
            }
        }
        item {
            SectionCard("Reminders") {
                SettingToggleRow("Morning check-in", "Keep the daily start visible", morningReminder, onMorningReminderChange)
                SettingToggleRow("Evening review", "Prompt reflection at the end of the day", eveningReminder, onEveningReminderChange)
                SettingToggleRow("Overload alerts", "Flag packed days and high-stress patterns", overloadAlerts, onOverloadAlertsChange)
            }
        }
        item {
            SectionCard("Privacy") {
                SettingToggleRow("Private mode", "Hide notes and reflections in history", privateMode, onPrivateModeChange)
            }
        }
        item {
            SectionCard("Account") {
                Text("Signed in", style = MaterialTheme.typography.bodyLarge, fontWeight = FontWeight.Medium)
                Text(
                    "Settings are kept on this device.",
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )
            }
        }
    }
}

@Composable
private fun EventDetailsScreen(
    eventId: Long,
    modifier: Modifier = Modifier,
    onBack: () -> Unit,
    viewModel: EventDetailsViewModel = hiltViewModel()
) {
    val state by viewModel.state.collectAsStateWithLifecycle()
    LaunchedEffect(eventId) { viewModel.load(eventId) }
    ScreenState(state.loading, state.error, { viewModel.load(eventId) }) {
        val event = state.event
        Column(
            modifier = modifier.fillMaxSize().padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(12.dp)
        ) {
            TextButton(onClick = onBack) { Text("Back") }
            if (event != null) {
                Text(event.title, style = MaterialTheme.typography.headlineSmall, fontWeight = FontWeight.SemiBold)
                Text("${formatEventTime(event.startsAt)} - ${formatEventTime(event.endsAt)}")
                if (!event.location.isNullOrBlank()) Text(event.location)
                if (!event.description.isNullOrBlank()) Text(event.description)
                Text("Source: ${event.source}", style = MaterialTheme.typography.bodySmall)
            }
        }
    }
}

@Composable
private fun EventRow(event: CalendarEventDto, onClick: () -> Unit) {
    Column(
        modifier = Modifier.fillMaxWidth().clickable(onClick = onClick).padding(vertical = 8.dp)
    ) {
        Text(event.title, style = MaterialTheme.typography.bodyLarge, fontWeight = FontWeight.Medium)
        Spacer(Modifier.height(2.dp))
        Row {
            Text(formatEventTime(event.startsAt), style = MaterialTheme.typography.bodySmall)
            if (!event.location.isNullOrBlank()) {
                Spacer(Modifier.width(8.dp))
                Text(event.location, style = MaterialTheme.typography.bodySmall)
            }
        }
        HorizontalDivider(Modifier.padding(top = 8.dp))
    }
}

@Composable
private fun WirdRow(entry: WirdEntryDto) {
    Column(modifier = Modifier.fillMaxWidth().padding(vertical = 6.dp)) {
        Text("${entry.date}  ${entry.wirdType}: ${entry.value}", fontWeight = FontWeight.Medium)
        if (!entry.notes.isNullOrBlank()) Text(entry.notes, style = MaterialTheme.typography.bodySmall)
        HorizontalDivider(Modifier.padding(top = 6.dp))
    }
}

@Composable
private fun WirdHistoryRow(entry: WirdEntryDto, privateMode: Boolean) {
    val meta = dailyWirdTypes.firstOrNull { it.key == entry.wirdType }
    Column(modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp)) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Column(modifier = Modifier.weight(1f)) {
                Text(
                    meta?.label ?: entry.wirdType,
                    style = MaterialTheme.typography.bodyLarge,
                    fontWeight = FontWeight.Medium
                )
                Text(
                    formatHistoryDate(entry.date),
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )
            }
            Text(
                historyWirdValue(entry, meta),
                style = MaterialTheme.typography.labelLarge,
                color = MaterialTheme.colorScheme.primary
            )
        }
        if (!privateMode && !entry.notes.isNullOrBlank()) {
            Spacer(Modifier.height(4.dp))
            Text(
                entry.notes,
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
        }
        HorizontalDivider(Modifier.padding(top = 10.dp))
    }
}

@Composable
private fun WirdProgressRow(
    meta: WirdTypeMeta,
    entries: List<WirdEntryDto>,
    selected: Boolean,
    onClick: () -> Unit
) {
    val value = wirdTotal(meta, entries)
    val status = if (value >= meta.target) "met" else "target ${meta.target} ${meta.unit}"
    Column(
        modifier = Modifier.fillMaxWidth().clickable(onClick = onClick).padding(vertical = 6.dp)
    ) {
        Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
            Text(
                meta.label,
                style = MaterialTheme.typography.bodyLarge,
                fontWeight = if (selected) FontWeight.SemiBold else FontWeight.Normal
            )
            Text("${formatWirdValue(meta, value)} / ${meta.target} ${meta.unit}")
        }
        Text(status, style = MaterialTheme.typography.bodySmall)
        HorizontalDivider(Modifier.padding(top = 6.dp))
    }
}

@Composable
private fun CheckinHistoryRow(status: TodayStatusDto, compact: Boolean, privateMode: Boolean) {
    val completedCount = listOf(status.morningDone, status.eveningDone).count { it }
    Column(modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp)) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                formatHistoryDate(status.date),
                style = MaterialTheme.typography.bodyLarge,
                fontWeight = FontWeight.Medium
            )
            Text(
                "$completedCount/2 complete",
                style = MaterialTheme.typography.labelLarge,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
        }
        Spacer(Modifier.height(8.dp))
        Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
            StatusPill("Morning", status.morningDone)
            StatusPill("Evening", status.eveningDone)
        }
        if (!compact) {
            Spacer(Modifier.height(8.dp))
            Text(
                "Morning: Fajr ${yesNo(status.fajr)}, Quran ${yesNo(status.quran)}, Exercise ${yesNo(status.exercise)}, Sleep ${status.sleepHours ?: "-"}",
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
            Text(
                "Evening: Duties ${yesNo(status.duties)}, Zikr ${yesNo(status.zikr)}, Salah ${yesNo(status.salah)}",
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
            if (!privateMode && !status.reflection.isNullOrBlank()) {
                Text(
                    status.reflection,
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )
            }
        }
        HorizontalDivider(Modifier.padding(top = 10.dp))
    }
}

@Composable
private fun SettingToggleRow(
    title: String,
    subtitle: String,
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .clickable { onCheckedChange(!checked) }
            .padding(vertical = 4.dp),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Column(modifier = Modifier.weight(1f).padding(end = 12.dp)) {
            Text(title, style = MaterialTheme.typography.bodyLarge, fontWeight = FontWeight.Medium)
            Text(
                subtitle,
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
        }
        Switch(checked = checked, onCheckedChange = onCheckedChange)
    }
}

@Composable
private fun StatusPill(label: String, complete: Boolean) {
    Surface(
        shape = MaterialTheme.shapes.small,
        color = if (complete) {
            MaterialTheme.colorScheme.primaryContainer
        } else {
            MaterialTheme.colorScheme.surfaceVariant
        }
    ) {
        Text(
            "$label ${if (complete) "done" else "open"}",
            modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
            style = MaterialTheme.typography.labelSmall,
            color = if (complete) {
                MaterialTheme.colorScheme.onPrimaryContainer
            } else {
                MaterialTheme.colorScheme.onSurfaceVariant
            }
        )
    }
}

@Composable
private fun CheckRow(label: String, checked: Boolean, onCheckedChange: (Boolean) -> Unit) {
    Row(
        modifier = Modifier.fillMaxWidth().clickable { onCheckedChange(!checked) }.padding(vertical = 6.dp),
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Text(label, style = MaterialTheme.typography.bodyLarge)
        Checkbox(checked = checked, onCheckedChange = onCheckedChange)
    }
}

@Composable
private fun RowScope.CalendarModeButton(label: String, selected: Boolean, onClick: () -> Unit) {
    if (selected) {
        Button(onClick = onClick, modifier = Modifier.weight(1f)) { Text(label) }
    } else {
        TextButton(onClick = onClick, modifier = Modifier.weight(1f)) { Text(label) }
    }
}

private fun calendarTitle(state: CalendarUiState): String =
    when (state.mode) {
        CalendarViewMode.Day -> state.selectedDate.format(DateTimeFormatter.ofPattern("EEE d MMM yyyy"))
        CalendarViewMode.Week -> {
            val start = state.selectedDate.with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY))
            val end = start.plusDays(6)
            "${start.format(DateTimeFormatter.ofPattern("d MMM"))} - ${end.format(DateTimeFormatter.ofPattern("d MMM yyyy"))}"
        }
        CalendarViewMode.Month -> "${state.selectedMonth.month.name.lowercase().replaceFirstChar { it.uppercase() }} ${state.selectedMonth.year}"
    }

private fun yesNo(value: Boolean?): String = if (value == true) "yes" else "no"

private fun formatHistoryDate(value: String): String =
    runCatching {
        LocalDate.parse(value).format(DateTimeFormatter.ofPattern("EEE d MMM"))
    }.getOrDefault(value)

private fun historyWirdValue(entry: WirdEntryDto, meta: WirdTypeMeta?): String {
    val value = if (entry.value % 1.0 == 0.0) {
        entry.value.toInt().toString()
    } else {
        entry.value.toString()
    }
    return when (meta?.kind) {
        WirdValueKind.Rating -> "$value/5"
        null -> value
        else -> "$value ${meta.unit}"
    }
}

private fun wirdValueLabel(meta: WirdTypeMeta): String =
    when (meta.kind) {
        WirdValueKind.Count -> "${meta.label} count"
        WirdValueKind.Juz -> "Juz completed"
        WirdValueKind.Minutes -> "Minutes"
        WirdValueKind.Rating -> "Rating"
    }

private fun wirdTotal(meta: WirdTypeMeta, entries: List<WirdEntryDto>): Int {
    val matching = entries.filter { it.wirdType == meta.key }
    return if (meta.kind == WirdValueKind.Rating) {
        matching.maxByOrNull { it.createdAt ?: "" }?.value?.toInt() ?: 0
    } else {
        matching.sumOf { it.value.toInt() }
    }
}

private fun formatWirdValue(meta: WirdTypeMeta, value: Int): String =
    if (meta.kind == WirdValueKind.Rating) {
        if (value == 0) "not logged" else "$value/5"
    } else {
        value.toString()
    }

private fun formatEventTime(value: String): String =
    runCatching {
        OffsetDateTime.parse(value).format(DateTimeFormatter.ofPattern("EEE d MMM, HH:mm"))
    }.getOrDefault(value)
