package dev.kaizen.app.chat

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.isSystemInDarkTheme
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.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.AlertDialog
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import dev.kaizen.app.net.ConversationSummary
import dev.kaizen.app.ui.effect.GlassSurface
import dev.kaizen.app.ui.effect.KaizenShadows
import dev.kaizen.app.ui.effect.kaizenShadow
import dev.kaizen.app.ui.effect.innerTopHighlight
import dev.kaizen.app.ui.shape.KaizenShapes
import dev.kaizen.app.R
import dev.kaizen.app.ui.theme.KaizenSemanticColors
import dev.kaizen.app.ui.theme.LocalKaizenAccent
import androidx.compose.ui.res.stringResource
import java.time.Instant
import java.time.LocalDate
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.Locale
import dev.kaizen.app.ui.icon.KaizenIcons

private data class DateLabels(val today: String, val yesterday: String, val earlier: String, val pinned: String)

private fun dateLabel(updatedAt: String?, labels: DateLabels): String {
    val instant = runCatching { Instant.parse(updatedAt) }.getOrNull() ?: return labels.earlier
    val date = instant.atZone(ZoneId.systemDefault()).toLocalDate()
    val today = LocalDate.now()
    return when (date) {
        today -> labels.today
        today.minusDays(1) -> labels.yesterday
        else -> date.format(DateTimeFormatter.ofPattern("dd. MMM yyyy", Locale.getDefault())).uppercase()
    }
}

private fun groupConversations(conversations: List<ConversationSummary>, labels: DateLabels): Map<String, List<ConversationSummary>> {
    val groups = LinkedHashMap<String, MutableList<ConversationSummary>>()
    conversations.filter { it.pinned }.takeIf { it.isNotEmpty() }?.let { groups[labels.pinned] = it.toMutableList() }
    conversations.filterNot { it.pinned }.forEach {
        groups.getOrPut(dateLabel(it.updatedAt, labels)) { mutableListOf() }.add(it)
    }
    return groups
}

sealed interface SidebarAction {
    data class Rename(val id: String, val newTitle: String) : SidebarAction
    data class Delete(val id: String) : SidebarAction
    data class TogglePin(val id: String, val pinned: Boolean) : SidebarAction
    data class ToggleLock(val id: String, val locked: Boolean) : SidebarAction
    data class GenerateTitle(val id: String) : SidebarAction
    data class Duplicate(val id: String) : SidebarAction
}

@Composable
fun KaizenSidebar(
    userName: String,
    conversations: List<ConversationSummary>,
    currentId: String?,
    onClose: () -> Unit,
    onNewChat: () -> Unit,
    onSelectConversation: (ConversationSummary) -> Unit,
    onOpenSettings: () -> Unit,
    onLogout: () -> Unit,
    onAction: (SidebarAction) -> Unit = {},
    modifier: Modifier = Modifier
) {
    val cs = MaterialTheme.colorScheme
    val isDark = isSystemInDarkTheme()
    val accent = LocalKaizenAccent.current

    var deleteTarget by remember { mutableStateOf<ConversationSummary?>(null) }
    var renameTarget by remember { mutableStateOf<ConversationSummary?>(null) }
    var renameText by remember { mutableStateOf("") }
    var searchQuery by remember { mutableStateOf("") }

    GlassSurface(
        modifier = modifier
            .fillMaxHeight()
            .statusBarsPadding()
            .width(300.dp)
            .padding(start = 12.dp, top = 8.dp, end = 4.dp, bottom = 12.dp),
        shape = KaizenShapes.lg,
        tintAlpha = if (isDark) 0.80f else 0.86f,
        shadowStack = KaizenShadows.level3,
        cornerRadius = 24.dp,
    ) {
        Column(
            Modifier
                .fillMaxSize()
                .padding(16.dp)
        ) {
            // ── Header ──
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(
                    stringResource(R.string.sidebar_brand),
                    color = cs.onBackground,
                    fontSize = 20.sp,
                    fontWeight = FontWeight.Bold,
                )
                Box(
                    modifier = Modifier
                        .size(34.dp)
                        .clip(KaizenShapes.circle)
                        .background(if (isDark) Color(0x1AFFFFFF) else Color(0x0A000000))
                        .clickable { onNewChat() },
                    contentAlignment = Alignment.Center
                ) {
                    Icon(KaizenIcons.Pencil, stringResource(R.string.chat_new), tint = cs.onBackground, modifier = Modifier.size(17.dp))
                }
            }

            Spacer(Modifier.height(14.dp))

            // ── Search (functional) ──
            val searchBorder = remember(isDark) {
                if (isDark) Brush.verticalGradient(
                    listOf(Color.White.copy(alpha = 0.10f), Color.White.copy(alpha = 0.03f))
                ) else Brush.verticalGradient(
                    listOf(Color.White.copy(alpha = 0.50f), Color.Black.copy(alpha = 0.04f))
                )
            }
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .clip(KaizenShapes.pill)
                    .border(0.8.dp, searchBorder, KaizenShapes.pill)
                    .background(if (isDark) Color(0x12FFFFFF) else Color(0x08000000))
                    .padding(horizontal = 14.dp, vertical = 9.dp),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Icon(KaizenIcons.Search, null, tint = cs.onSurfaceVariant.copy(alpha = 0.40f), modifier = Modifier.size(15.dp))
                Spacer(Modifier.width(8.dp))
                BasicTextField(
                    value = searchQuery,
                    onValueChange = { searchQuery = it },
                    singleLine = true,
                    textStyle = TextStyle(
                        color = cs.onBackground,
                        fontSize = 13.sp,
                    ),
                    cursorBrush = SolidColor(cs.onSurfaceVariant),
                    decorationBox = { innerTextField ->
                        Box {
                            if (searchQuery.isEmpty()) {
                                Text(
                                    stringResource(R.string.chat_search),
                                    color = cs.onSurfaceVariant.copy(alpha = 0.40f),
                                    fontSize = 13.sp,
                                )
                            }
                            innerTextField()
                        }
                    },
                    modifier = Modifier.weight(1f),
                )
                if (searchQuery.isNotEmpty()) {
                    Icon(
                        KaizenIcons.X,
                        null,
                        tint = cs.onSurfaceVariant.copy(alpha = 0.40f),
                        modifier = Modifier
                            .size(14.dp)
                            .clickable { searchQuery = "" },
                    )
                }
            }

            Spacer(Modifier.height(18.dp))

            // ── Conversation list ──
            val filteredConversations = remember(conversations, searchQuery) {
                if (searchQuery.isBlank()) conversations
                else conversations.filter {
                    if (it.locked) false
                    else it.title.contains(searchQuery, ignoreCase = true)
                }
            }

            Box(Modifier.weight(1f).fillMaxWidth()) {
                if (filteredConversations.isEmpty()) {
                    Text(
                        stringResource(R.string.chat_no_conversations),
                        color = cs.onSurfaceVariant.copy(alpha = 0.4f),
                        fontSize = 13.sp,
                        modifier = Modifier.padding(start = 8.dp, top = 8.dp)
                    )
                } else {
                    val labels = DateLabels(
                        today = stringResource(R.string.sidebar_today),
                        yesterday = stringResource(R.string.sidebar_yesterday),
                        earlier = stringResource(R.string.sidebar_earlier),
                        pinned = stringResource(R.string.sidebar_pinned),
                    )
                    val grouped = remember(filteredConversations, labels) { groupConversations(filteredConversations, labels) }
                    LazyColumn(
                        modifier = Modifier.fillMaxSize(),
                        verticalArrangement = Arrangement.spacedBy(4.dp)
                    ) {
                        grouped.forEach { (dateGroup, items) ->
                            item(key = "header_$dateGroup") {
                                Text(
                                    dateGroup,
                                    color = cs.onSurfaceVariant.copy(alpha = 0.35f),
                                    fontSize = 10.sp,
                                    fontWeight = FontWeight.Bold,
                                    letterSpacing = 1.sp,
                                    modifier = Modifier.padding(start = 8.dp, top = 14.dp, bottom = 6.dp)
                                )
                            }
                            items(items, key = { it.id }) { item ->
                                HistoryItemRow(
                                    item = item,
                                    selected = item.id == currentId,
                                    onClick = { onSelectConversation(item) },
                                    onRename = {
                                        renameTarget = item
                                        renameText = item.title
                                    },
                                    onDelete = { deleteTarget = item },
                                    onTogglePin = { onAction(SidebarAction.TogglePin(item.id, !item.pinned)) },
                                    onToggleLock = { onAction(SidebarAction.ToggleLock(item.id, !item.locked)) },
                                    onGenerateTitle = { onAction(SidebarAction.GenerateTitle(item.id)) },
                                    onDuplicate = { onAction(SidebarAction.Duplicate(item.id)) },
                                )
                            }
                        }
                    }
                }
            }

            // ── User row (flat, no card) ──
            Box(
                Modifier.fillMaxWidth().height(0.5.dp).padding(horizontal = 12.dp)
                    .background(cs.onSurfaceVariant.copy(alpha = 0.08f))
            )
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .clickable { onOpenSettings() }
                    .padding(horizontal = 16.dp, vertical = 14.dp),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Box(
                    modifier = Modifier
                        .size(34.dp)
                        .clip(KaizenShapes.circle)
                        .background(
                            Brush.radialGradient(
                                listOf(accent.primary.copy(alpha = 0.9f), accent.primaryDeep.copy(alpha = 0.75f))
                            )
                        ),
                    contentAlignment = Alignment.Center
                ) {
                    Text(
                        userName.firstOrNull()?.toString()?.uppercase() ?: "A",
                        color = Color.White, fontSize = 14.sp, fontWeight = FontWeight.W600
                    )
                }
                Spacer(Modifier.width(10.dp))
                Text(
                    userName,
                    color = cs.onBackground,
                    fontSize = 14.sp,
                    fontWeight = FontWeight.W400,
                    modifier = Modifier.weight(1f),
                )
                Box(
                    modifier = Modifier
                        .size(30.dp)
                        .clip(KaizenShapes.circle)
                        .clickable { onOpenSettings() },
                    contentAlignment = Alignment.Center,
                ) {
                    Icon(
                        KaizenIcons.Settings,
                        stringResource(R.string.sidebar_settings),
                        tint = cs.onSurfaceVariant.copy(alpha = 0.45f),
                        modifier = Modifier.size(16.dp),
                    )
                }
                Spacer(Modifier.width(4.dp))
                Box(
                    modifier = Modifier
                        .size(30.dp)
                        .clip(KaizenShapes.circle)
                        .clickable { onLogout() },
                    contentAlignment = Alignment.Center,
                ) {
                    Icon(
                        KaizenIcons.LogOut,
                        stringResource(R.string.sidebar_logout),
                        tint = cs.onSurfaceVariant.copy(alpha = 0.45f),
                        modifier = Modifier.size(16.dp),
                    )
                }
            }
        }
    }

    // Delete confirmation dialog
    deleteTarget?.let { target ->
        AlertDialog(
            onDismissRequest = { deleteTarget = null },
            title = { Text(stringResource(R.string.sidebar_delete)) },
            text = { Text(stringResource(R.string.sidebar_delete_confirm)) },
            confirmButton = {
                TextButton(onClick = {
                    onAction(SidebarAction.Delete(target.id))
                    deleteTarget = null
                }) {
                    Text(stringResource(R.string.sidebar_confirm), color = KaizenSemanticColors.error)
                }
            },
            dismissButton = {
                TextButton(onClick = { deleteTarget = null }) {
                    Text(stringResource(R.string.sidebar_cancel))
                }
            },
        )
    }

    // Rename dialog
    renameTarget?.let { target ->
        val focusManager = LocalFocusManager.current
        AlertDialog(
            onDismissRequest = { renameTarget = null },
            title = { Text(stringResource(R.string.sidebar_rename_title)) },
            text = {
                BasicTextField(
                    value = renameText,
                    onValueChange = { renameText = it },
                    singleLine = true,
                    textStyle = TextStyle(
                        color = cs.onBackground,
                        fontSize = 15.sp,
                    ),
                    cursorBrush = SolidColor(cs.onBackground),
                    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
                    keyboardActions = KeyboardActions(onDone = {
                        focusManager.clearFocus()
                        if (renameText.isNotBlank()) {
                            onAction(SidebarAction.Rename(target.id, renameText.trim()))
                        }
                        renameTarget = null
                    }),
                    modifier = Modifier
                        .fillMaxWidth()
                        .clip(KaizenShapes.sm)
                        .background(if (isDark) Color(0x12FFFFFF) else Color(0x08000000))
                        .padding(horizontal = 14.dp, vertical = 12.dp),
                )
            },
            confirmButton = {
                TextButton(onClick = {
                    if (renameText.isNotBlank()) {
                        onAction(SidebarAction.Rename(target.id, renameText.trim()))
                    }
                    renameTarget = null
                }) {
                    Text(stringResource(R.string.sidebar_save))
                }
            },
            dismissButton = {
                TextButton(onClick = { renameTarget = null }) {
                    Text(stringResource(R.string.sidebar_cancel))
                }
            },
        )
    }
}

@Composable
private fun HistoryItemRow(
    item: ConversationSummary,
    selected: Boolean,
    onClick: () -> Unit,
    onRename: () -> Unit,
    onDelete: () -> Unit,
    onTogglePin: () -> Unit,
    onToggleLock: () -> Unit,
    onGenerateTitle: () -> Unit,
    onDuplicate: () -> Unit,
) {
    val cs = MaterialTheme.colorScheme
    val isDark = isSystemInDarkTheme()
    val accent = LocalKaizenAccent.current

    var showMenu by remember { mutableStateOf(false) }

    val activeBorder = remember(isDark, accent) {
        if (isDark) Brush.verticalGradient(
            listOf(accent.primary.copy(alpha = 0.25f), accent.primary.copy(alpha = 0.06f))
        ) else Brush.verticalGradient(
            listOf(accent.primary.copy(alpha = 0.20f), accent.primary.copy(alpha = 0.05f))
        )
    }
    val inactiveBorder = remember(isDark) {
        if (isDark) Brush.verticalGradient(
            listOf(Color.White.copy(alpha = 0.07f), Color.White.copy(alpha = 0.02f))
        ) else Brush.verticalGradient(
            listOf(Color.White.copy(alpha = 0.35f), Color.Black.copy(alpha = 0.03f))
        )
    }

    Box(modifier = Modifier.padding(horizontal = 2.dp)) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .clip(KaizenShapes.md)
                .then(
                    if (selected) {
                        Modifier
                            .kaizenShadow(stack = KaizenShadows.level1, cornerRadius = 16.dp)
                            .background(accent.primary.copy(alpha = if (isDark) 0.12f else 0.08f))
                            .border(0.8.dp, activeBorder, KaizenShapes.md)
                    } else {
                        Modifier
                            .background(if (isDark) Color(0x08FFFFFF) else Color(0x05000000))
                            .border(0.5.dp, inactiveBorder, KaizenShapes.md)
                    }
                )
                .clickable { onClick() }
                .padding(start = 12.dp, end = 4.dp, top = 10.dp, bottom = 10.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            if (item.pinned) {
                Icon(KaizenIcons.Star, null, tint = accent.primary.copy(alpha = 0.7f), modifier = Modifier.size(13.dp))
                Spacer(Modifier.width(6.dp))
            }
            Text(
                text = if (item.locked) stringResource(R.string.chat_locked) else item.title,
                color = if (item.locked) cs.onSurfaceVariant.copy(alpha = 0.45f) else cs.onBackground.copy(alpha = if (selected) 0.95f else 0.80f),
                fontSize = 13.sp,
                fontWeight = if (selected) FontWeight.SemiBold else FontWeight.Normal,
                fontStyle = if (item.locked) FontStyle.Italic else FontStyle.Normal,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis,
                modifier = Modifier.weight(1f),
            )
            if (item.locked) {
                Icon(KaizenIcons.Lock, null, tint = accent.primary.copy(alpha = 0.5f), modifier = Modifier.size(13.dp))
                Spacer(Modifier.width(2.dp))
            }
            Box(
                modifier = Modifier
                    .size(28.dp)
                    .clip(KaizenShapes.circle)
                    .clickable { showMenu = true },
                contentAlignment = Alignment.Center,
            ) {
                Icon(
                    KaizenIcons.MoreVertical,
                    stringResource(R.string.sidebar_more),
                    tint = cs.onSurfaceVariant.copy(alpha = 0.30f),
                    modifier = Modifier.size(15.dp),
                )
            }
        }

        androidx.compose.material3.DropdownMenu(
            expanded = showMenu,
            onDismissRequest = { showMenu = false },
            containerColor = if (isDark) KaizenSemanticColors.dropdownDark else KaizenSemanticColors.dropdownLight,
            shadowElevation = 16.dp,
            shape = KaizenShapes.md,
        ) {
            if (!item.locked) {
                MenuRow(KaizenIcons.Pencil, stringResource(R.string.sidebar_rename), cs.onBackground) { showMenu = false; onRename() }
            }
            if (!item.titleGenerated && !item.locked) {
                MenuRow(KaizenIcons.Sparkles, stringResource(R.string.sidebar_generate_title), cs.onBackground) { showMenu = false; onGenerateTitle() }
            }
            MenuRow(KaizenIcons.Pin, stringResource(if (item.pinned) R.string.sidebar_unpin else R.string.sidebar_pin), cs.onBackground) { showMenu = false; onTogglePin() }
            if (!item.locked) {
                MenuRow(KaizenIcons.Copy, stringResource(R.string.sidebar_duplicate), cs.onBackground) { showMenu = false; onDuplicate() }
            }
            MenuRow(
                if (item.locked) KaizenIcons.LockOpen else KaizenIcons.Lock,
                stringResource(if (item.locked) R.string.sidebar_unlock else R.string.sidebar_lock),
                cs.onBackground,
            ) { showMenu = false; onToggleLock() }
            // Separator
            Box(
                Modifier
                    .fillMaxWidth()
                    .padding(horizontal = 16.dp, vertical = 4.dp)
                    .height(0.5.dp)
                    .background(if (isDark) Color.White.copy(alpha = 0.08f) else Color.Black.copy(alpha = 0.06f))
            )
            MenuRow(KaizenIcons.Trash, stringResource(R.string.sidebar_delete), KaizenSemanticColors.error) { showMenu = false; onDelete() }
        }
    }
}

@Composable
private fun MenuRow(icon: ImageVector, label: String, tint: Color, onClick: () -> Unit) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .clickable(onClick = onClick)
            .padding(horizontal = 16.dp, vertical = 11.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Icon(icon, null, tint = tint.copy(alpha = 0.6f), modifier = Modifier.size(16.dp))
        Spacer(Modifier.width(12.dp))
        Text(label, color = tint.copy(alpha = 0.9f), fontSize = 13.5.sp, fontWeight = FontWeight.Medium)
    }
}
