package de.tsschulz.timeclock.ui.settings

import android.app.DatePickerDialog
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
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.unit.dp
import androidx.compose.ui.unit.sp
import de.tsschulz.timeclock.data.api.InvitationDto
import de.tsschulz.timeclock.data.api.ProfileDto
import de.tsschulz.timeclock.data.api.StateDto
import de.tsschulz.timeclock.data.api.TimewishDto
import de.tsschulz.timeclock.data.api.WatcherDto
import de.tsschulz.timeclock.ui.components.TcButton
import de.tsschulz.timeclock.ui.components.TcCard
import de.tsschulz.timeclock.ui.components.TcError
import de.tsschulz.timeclock.ui.components.TcLoading
import de.tsschulz.timeclock.ui.components.TcTextField
import de.tsschulz.timeclock.ui.model.ButtonVariant
import de.tsschulz.timeclock.ui.theme.TcColors
import de.tsschulz.timeclock.ui.theme.TcRadius
import de.tsschulz.timeclock.ui.theme.TcSpacing
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.Locale

@Composable
fun ProfileScreen(
    state: SettingsUiState,
    isTablet: Boolean,
    onSave: (String, String?, Int, Double, Int) -> Unit,
    onLinkGoogle: () -> Unit,
) {
    val profile = state.profile
    var fullName by rememberSaveable { mutableStateOf("") }
    var stateId by rememberSaveable { mutableStateOf("") }
    var weekWorkdays by rememberSaveable { mutableStateOf("5") }
    var dailyHours by rememberSaveable { mutableStateOf("8.0") }
    var preferredTitleType by rememberSaveable { mutableStateOf(2) }

    LaunchedEffect(profile) {
        profile?.let {
            fullName = it.fullName
            stateId = it.stateId.orEmpty()
            weekWorkdays = (it.weekWorkdays ?: 5).toString()
            dailyHours = (it.dailyHours ?: 8.0).toString()
            preferredTitleType = it.preferredTitleType ?: 2
        }
    }

    SettingsFrame(state) {
        ResponsiveSettings(isTablet) {
            FormCard("Persönliche Daten") {
                TcTextField("Name", fullName, { fullName = it })
                StateDropdown(
                    states = state.states,
                    selectedId = stateId,
                    selectedName = profile?.stateName,
                    onSelect = { stateId = it.orEmpty() },
                )
                TcTextField("Arbeitstage pro Woche", weekWorkdays, { weekWorkdays = it }, placeholder = "5")
                TcTextField("Stunden pro Tag", dailyHours, { dailyHours = it }, placeholder = "8.0")
                TitleTypeDropdown(preferredTitleType, { preferredTitleType = it })
                FieldLabel("Google-Anmeldung")
                TcButton("Mit Google-Konto verknüpfen", variant = ButtonVariant.Default, onClick = onLinkGoogle)
                TcButton("Speichern", variant = ButtonVariant.Primary, onClick = {
                    onSave(
                        fullName,
                        stateId.ifBlank { null },
                        weekWorkdays.toIntOrNull() ?: 5,
                        dailyHours.toDoubleOrNull() ?: 8.0,
                        preferredTitleType,
                    )
                })
            }
            ProfileDetails(profile)
        }
    }
}

@Composable
fun PasswordScreen(
    state: SettingsUiState,
    onChange: (String, String, String) -> Unit,
) {
    var oldPassword by rememberSaveable { mutableStateOf("") }
    var newPassword by rememberSaveable { mutableStateOf("") }
    var confirmPassword by rememberSaveable { mutableStateOf("") }

    SettingsFrame(state) {
        FormCard("Passwort ändern") {
            TcTextField("Aktuelles Passwort", oldPassword, { oldPassword = it }, isPassword = true)
            TcTextField("Neues Passwort", newPassword, { newPassword = it }, isPassword = true)
            TcTextField("Neues Passwort wiederholen", confirmPassword, { confirmPassword = it }, isPassword = true)
            TcButton("Passwort ändern", variant = ButtonVariant.Primary, onClick = {
                onChange(oldPassword, newPassword, confirmPassword)
                oldPassword = ""
                newPassword = ""
                confirmPassword = ""
            })
        }
    }
}

@Composable
fun TimewishScreen(
    state: SettingsUiState,
    isTablet: Boolean,
    onCreate: (Int, Int, Double?, String, String?) -> Unit,
    onDelete: (String) -> Unit,
) {
    var day by rememberSaveable { mutableStateOf(1) }
    var wishtype by rememberSaveable { mutableStateOf(2) }
    var hours by rememberSaveable { mutableStateOf("8.0") }
    var startDate by rememberSaveable { mutableStateOf(LocalDate.now().toString()) }
    var endDate by rememberSaveable { mutableStateOf("") }

    SettingsFrame(state) {
        ResponsiveSettings(isTablet) {
            FormCard("Zeitwunsch eintragen") {
                WeekdayDropdown(day, { day = it })
                WishtypeDropdown(wishtype) {
                    wishtype = it
                    hours = if (it == 2) "8.0" else "0"
                }
                if (wishtype == 2) {
                    TcTextField("Stunden", hours, { hours = it }, placeholder = "8.0")
                }
                SettingsDateField("Gültig ab", startDate, { startDate = it })
                SettingsDateField("Gültig bis (optional)", endDate, { endDate = it }, allowBlank = true)
                TcButton("Zeitwunsch speichern", variant = ButtonVariant.Primary, onClick = {
                    onCreate(
                        day,
                        wishtype,
                        if (wishtype == 2) hours.toDoubleOrNull() else null,
                        startDate,
                        endDate.ifBlank { null },
                    )
                })
            }
            ListCard("Zeitwünsche", state.timewishes) { item -> TimewishRow(item, onDelete) }
        }
    }
}

@Composable
fun InviteScreen(
    state: SettingsUiState,
    isTablet: Boolean,
    onSend: (String) -> Unit,
) {
    var email by rememberSaveable { mutableStateOf("") }

    SettingsFrame(state) {
        ResponsiveSettings(isTablet) {
            FormCard("Einladen") {
                TcTextField("E-Mail", email, { email = it }, placeholder = "name@example.com")
                TcButton("Einladung senden", variant = ButtonVariant.Primary, onClick = {
                    if (email.isNotBlank()) {
                        onSend(email)
                        email = ""
                    }
                })
            }
            ListCard("Einladungen", state.invites) { item -> InviteRow(item) }
        }
    }
}

@Composable
fun PermissionsScreen(
    state: SettingsUiState,
    isTablet: Boolean,
    onAdd: (String) -> Unit,
    onDelete: (String) -> Unit,
) {
    var email by rememberSaveable { mutableStateOf("") }

    SettingsFrame(state) {
        ResponsiveSettings(isTablet) {
            FormCard("Zugriff hinzufügen") {
                TcTextField("E-Mail", email, { email = it }, placeholder = "name@example.com")
                TcButton("Zugriff speichern", variant = ButtonVariant.Primary, onClick = {
                    if (email.isNotBlank()) {
                        onAdd(email)
                        email = ""
                    }
                })
            }
            ListCard("Aktuelle Zugriffe", state.watchers) { item -> WatcherRow(item, onDelete) }
        }
    }
}

@Composable
private fun TitleTypeDropdown(value: Int, onValueChange: (Int) -> Unit) {
    var expanded by rememberSaveable { mutableStateOf(false) }
    FieldLabel("Anzeige in Seitentitel")
    Box(modifier = Modifier.fillMaxWidth()) {
        TcButton(
            text = titleTypeLabel(value),
            variant = ButtonVariant.Default,
            modifier = Modifier.fillMaxWidth(),
            onClick = { expanded = true },
        )
        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
            (0..7).forEach { type ->
                DropdownMenuItem(
                    text = { Text(titleTypeLabel(type), color = TcColors.Text) },
                    onClick = {
                        onValueChange(type)
                        expanded = false
                    },
                )
            }
        }
    }
}

@Composable
private fun WeekdayDropdown(value: Int, onValueChange: (Int) -> Unit) {
    var expanded by rememberSaveable { mutableStateOf(false) }
    FieldLabel("Wochentag")
    Box(modifier = Modifier.fillMaxWidth()) {
        TcButton(
            text = weekdayLabel(value),
            variant = ButtonVariant.Default,
            modifier = Modifier.fillMaxWidth(),
            onClick = { expanded = true },
        )
        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
            (1..7).forEach { day ->
                DropdownMenuItem(
                    text = { Text(weekdayLabel(day), color = TcColors.Text) },
                    onClick = {
                        onValueChange(day)
                        expanded = false
                    },
                )
            }
        }
    }
}

@Composable
private fun WishtypeDropdown(value: Int, onValueChange: (Int) -> Unit) {
    var expanded by rememberSaveable { mutableStateOf(false) }
    FieldLabel("Typ")
    Box(modifier = Modifier.fillMaxWidth()) {
        TcButton(
            text = wishtypeLabel(value),
            variant = ButtonVariant.Default,
            modifier = Modifier.fillMaxWidth(),
            onClick = { expanded = true },
        )
        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
            (0..2).forEach { type ->
                DropdownMenuItem(
                    text = { Text(wishtypeLabel(type), color = TcColors.Text) },
                    onClick = {
                        onValueChange(type)
                        expanded = false
                    },
                )
            }
        }
    }
}

@Composable
private fun SettingsDateField(
    label: String,
    value: String,
    onValueChange: (String) -> Unit,
    allowBlank: Boolean = false,
) {
    val context = LocalContext.current
    val parsed = runCatching { LocalDate.parse(value) }.getOrDefault(LocalDate.now())
    FieldLabel(label)
    Row(horizontalArrangement = Arrangement.spacedBy(TcSpacing.Sm), verticalAlignment = Alignment.CenterVertically) {
        TcButton(
            text = if (allowBlank && value.isBlank()) "Kein Enddatum" else parsed.toGermanDate(),
            variant = ButtonVariant.Default,
            modifier = Modifier.weight(1f),
            onClick = {
                DatePickerDialog(
                    context,
                    { _, year, month, day ->
                        onValueChange(LocalDate.of(year, month + 1, day).toString())
                    },
                    parsed.year,
                    parsed.monthValue - 1,
                    parsed.dayOfMonth,
                ).show()
            },
        )
        if (allowBlank) {
            TcButton("Leeren", variant = ButtonVariant.Default, onClick = { onValueChange("") })
        }
    }
}

@Composable
private fun StateDropdown(
    states: List<StateDto>,
    selectedId: String,
    selectedName: String?,
    onSelect: (String?) -> Unit,
) {
    var expanded by rememberSaveable { mutableStateOf(false) }
    val selected = states.firstOrNull { it.id == selectedId }
    FieldLabel("Bundesland")
    Box(modifier = Modifier.fillMaxWidth()) {
        TcButton(
            text = selected?.name ?: selectedName?.takeIf { selectedId.isNotBlank() } ?: "Kein Bundesland ausgewählt",
            variant = ButtonVariant.Default,
            modifier = Modifier.fillMaxWidth(),
            onClick = { expanded = true },
        )
        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
            DropdownMenuItem(
                text = { Text("Kein Bundesland ausgewählt", color = TcColors.Text) },
                onClick = {
                    onSelect(null)
                    expanded = false
                },
            )
            states.forEach { state ->
                DropdownMenuItem(
                    text = { Text(state.name, color = TcColors.Text) },
                    onClick = {
                        onSelect(state.id)
                        expanded = false
                    },
                )
            }
        }
    }
}

private fun titleTypeLabel(value: Int): String =
    when (value) {
        0 -> "Restzeit für Tag ohne Korrektur"
        1 -> "Restzeit für Tag, korrigiert nach Wochenarbeitszeit"
        2 -> "Restzeit für Tag, korrigiert nach Gesamtarbeitszeit"
        3 -> "Heute gearbeitete Zeit"
        4 -> "Uhrzeit für Arbeitsende ohne Korrektur"
        5 -> "Uhrzeit für Arbeitsende, korrigiert nach Wochenarbeitszeit"
        6 -> "Uhrzeit für Arbeitsende, korrigiert nach Gesamtarbeitszeit"
        7 -> "Nur App-Name"
        else -> "Restzeit für Tag, korrigiert nach Gesamtarbeitszeit"
    }

private fun weekdayLabel(value: Int): String =
    when (value) {
        1 -> "Montag"
        2 -> "Dienstag"
        3 -> "Mittwoch"
        4 -> "Donnerstag"
        5 -> "Freitag"
        6 -> "Samstag"
        7 -> "Sonntag"
        else -> "Montag"
    }

private fun wishtypeLabel(value: Int): String =
    when (value) {
        0 -> "Kein Wunsch"
        1 -> "Frei"
        2 -> "Arbeit"
        else -> "Arbeit"
    }

private val germanDateFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy", Locale.GERMANY)

private fun LocalDate.toGermanDate(): String = format(germanDateFormatter)

@Composable
private fun SettingsFrame(state: SettingsUiState, content: @Composable () -> Unit) {
    if (state.loading) TcLoading("Lade Daten...")
    state.error?.let { TcError(it) }
    state.success?.let {
        TcCard { Text(it, color = TcColors.Success, fontSize = 14.sp, fontWeight = FontWeight.Medium) }
    }
    content()
}

@Composable
private fun ResponsiveSettings(isTablet: Boolean, content: @Composable ColumnScope.() -> Unit) {
    if (isTablet) {
        Row(horizontalArrangement = Arrangement.spacedBy(TcSpacing.Xl), modifier = Modifier.fillMaxWidth()) {
            Column(modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(TcSpacing.Lg), content = content)
        }
    } else {
        Column(verticalArrangement = Arrangement.spacedBy(TcSpacing.Lg), content = content)
    }
}

@Composable
private fun FormCard(title: String, content: @Composable ColumnScope.() -> Unit) {
    TcCard {
        SectionTitle(title)
        Column(verticalArrangement = Arrangement.spacedBy(TcSpacing.Md), content = content)
    }
}

@Composable
private fun <T> ListCard(title: String, items: List<T>, row: @Composable (T) -> Unit) {
    TcCard {
        SectionTitle(title)
        if (items.isEmpty()) {
            Text("Keine Einträge vorhanden.", color = TcColors.TextMuted, fontSize = 14.sp)
        } else {
            Column(verticalArrangement = Arrangement.spacedBy(TcSpacing.Sm)) {
                items.forEach { item -> row(item) }
            }
        }
    }
}

@Composable
private fun ProfileDetails(profile: ProfileDto?) {
    TcCard {
        SectionTitle("Konto")
        Detail("E-Mail", profile?.email ?: "-")
        Detail("Bundesland", profile?.stateName ?: "-")
        Detail("Wochenarbeitstage", profile?.weekWorkdays?.toString() ?: "-")
        Detail("Tagesstunden", profile?.dailyHours?.toString() ?: "-")
    }
}

@Composable
private fun TimewishRow(item: TimewishDto, onDelete: (String) -> Unit) = DataRow(
    title = item.dayName ?: "Tag ${item.day}",
    details = "${item.wishtypeName ?: "Typ ${item.wishtype}"} - ${item.hours ?: 0.0} h - ${item.startDate ?: "-"} bis ${item.endDate ?: "-"}",
    onDelete = { onDelete(item.id) },
)

@Composable
private fun InviteRow(item: InvitationDto) = DataRow(
    title = item.email,
    details = "${item.status ?: "offen"} - gültig bis ${item.expiresAt ?: "-"}",
)

@Composable
private fun WatcherRow(item: WatcherDto, onDelete: (String) -> Unit) = DataRow(
    title = item.email,
    details = "Seit ${item.createdAt ?: "-"}",
    onDelete = { onDelete(item.id) },
)

@Composable
private fun DataRow(title: String, details: String, onDelete: (() -> Unit)? = null) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .background(TcColors.Background, RoundedCornerShape(TcRadius.Medium))
            .border(1.dp, TcColors.Border, RoundedCornerShape(TcRadius.Medium))
            .padding(TcSpacing.Md),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(TcSpacing.Md),
    ) {
        Column(modifier = Modifier.weight(1f)) {
            Text(title, color = TcColors.Text, fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
            Text(details, color = TcColors.TextMuted, fontSize = 13.sp)
        }
        onDelete?.let { TcButton("Löschen", variant = ButtonVariant.Danger, onClick = it) }
    }
}

@Composable
private fun SectionTitle(title: String) {
    Text(
        text = title,
        color = TcColors.Text,
        fontSize = 18.sp,
        fontWeight = FontWeight.SemiBold,
        modifier = Modifier.padding(bottom = TcSpacing.Sm),
    )
}

@Composable
private fun FieldLabel(label: String) {
    Text(
        text = label,
        color = TcColors.Text,
        fontWeight = FontWeight.Medium,
        fontSize = 14.sp,
    )
}

@Composable
private fun Detail(label: String, value: String) {
    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
        Text(label, color = TcColors.TextMuted, fontSize = 14.sp)
        Text(value, color = TcColors.Text, fontSize = 14.sp, fontWeight = FontWeight.Medium)
    }
}
