package eu.gaudian.translator.view.dialogs

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.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
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.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import eu.gaudian.translator.R
import eu.gaudian.translator.model.TagCategory
import eu.gaudian.translator.model.VocabularyCategory
import eu.gaudian.translator.model.VocabularyFilter
import eu.gaudian.translator.ui.theme.ThemePreviews
import eu.gaudian.translator.view.composable.AppButton
import eu.gaudian.translator.view.composable.AppCheckbox
import eu.gaudian.translator.view.composable.AppDropdownMenuItem
import eu.gaudian.translator.view.composable.AppIcons
import eu.gaudian.translator.view.composable.AppOutlinedButton
import eu.gaudian.translator.view.composable.AppOutlinedTextField


/**
 * State class representing the internal state of CategoryDropdown.
 * Used for previews and testing.
 */
data class CategoryDropdownState(
    val expanded: Boolean = false,
    val selectedCategories: List<VocabularyCategory?> = emptyList(),
    val newCategoryName: String = "",
    val categories: List<VocabularyCategory> = emptyList(),
)

/**
 * Stateless dropdown content composable for category selection.
 * This component is fully controlled by its parameters and does not maintain any internal state.
 *
 * @param state The current state of the dropdown
 * @param onExpand Callback when the dropdown should expand/collapse
 * @param onCategorySelected Callback when a category is selected
 * @param onNewCategoryNameChange Callback when the new category name changes
 * @param onAddCategory Callback when a new category should be added
 * @param noneSelectable Whether "None" option is selectable
 * @param multipleSelectable Whether multiple categories can be selected
 * @param onlyLists Whether to show only list/category types
 * @param addCategory Whether to show the "Add Category" option
 * @param modifier Modifier for the composable
 */
@Composable
fun CategoryDropdownContent(
    modifier: Modifier = Modifier,
    state: CategoryDropdownState,
    onExpand: (Boolean) -> Unit,
    onCategorySelected: (List<VocabularyCategory?>) -> Unit,
    onNewCategoryNameChange: (String) -> Unit,
    onAddCategory: (String) -> Unit,
    noneSelectable: Boolean = true,
    multipleSelectable: Boolean = false,
    onlyLists: Boolean = false,
    addCategory: Boolean = false,
) {
    val selectableCategories = if (onlyLists) {
        state.categories.filterIsInstance<TagCategory>()
    } else {
        state.categories
    }

    AppOutlinedButton(
        shape = RoundedCornerShape(8.dp),
        onClick = { onExpand(true) },
        modifier = modifier.fillMaxWidth(),
    ) {
        Row(modifier = Modifier.fillMaxWidth()) {
            Text(
                text = when {
                    state.selectedCategories.isEmpty() -> stringResource(R.string.text_select_category)
                    state.selectedCategories.size == 1 -> state.selectedCategories.first()?.name
                        ?: stringResource(R.string.text_none)
                    else -> stringResource(R.string.text_2d_categories_selected, state.selectedCategories.size)
                },
                modifier = Modifier.weight(1f),
                textAlign = TextAlign.Center
            )
            Icon(
                imageVector = if (state.expanded) AppIcons.ArrowDropUp else AppIcons.ArrowDropDown,
                contentDescription = if (state.expanded) {
                    stringResource(R.string.cd_collapse)
                } else {
                    stringResource(R.string.cd_expand)
                }
            )
        }
    }

    DropdownMenu(
        expanded = state.expanded,
        onDismissRequest = { onExpand(false) },
        modifier = Modifier.fillMaxWidth(),
    ) {
        if (noneSelectable) {
            val noneSelected = state.selectedCategories.contains(null)
            AppDropdownMenuItem(
                text = {
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        if (multipleSelectable) {
                            AppCheckbox(
                                checked = noneSelected,
                                onCheckedChange = { isChecked ->
                                    val newSelection = if (noneSelected) {
                                        state.selectedCategories.filterNotNull()
                                    } else {
                                        state.selectedCategories + listOf(null)
                                    }
                                    onCategorySelected(newSelection)
                                }
                            )
                            Spacer(modifier = Modifier.width(8.dp))
                        }
                        Text(stringResource(R.string.text_none))
                    }
                },
                onClick = {
                    if (multipleSelectable) {
                        val newSelection = if (noneSelected) {
                            state.selectedCategories.filterNotNull()
                        } else {
                            state.selectedCategories + listOf(null)
                        }
                        onCategorySelected(newSelection)
                    } else {
                        onCategorySelected(listOf(null))
                        onExpand(false)
                    }
                }
            )
        }

        selectableCategories.forEach { category ->
            val isSelected = state.selectedCategories.contains(category)
            AppDropdownMenuItem(
                text = {
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        if (multipleSelectable) {
                            AppCheckbox(
                                checked = isSelected,
                                onCheckedChange = { _ ->
                                    val newSelection = if (isSelected) {
                                        state.selectedCategories - category
                                    } else {
                                        state.selectedCategories + category
                                    }
                                    onCategorySelected(newSelection)
                                }
                            )
                            Spacer(modifier = Modifier.width(8.dp))
                        }
                        Text(category.name)
                    }
                },
                onClick = {
                    if (multipleSelectable) {
                        val newSelection = if (category in state.selectedCategories) {
                            state.selectedCategories - category
                        } else {
                            state.selectedCategories + category
                        }
                        onCategorySelected(newSelection)
                    } else {
                        onCategorySelected(listOf(category))
                        onExpand(false)
                    }
                }
            )
        }

        if (addCategory) {
            HorizontalDivider()

            AppDropdownMenuItem(
                text = {
                    Text(stringResource(R.string.label_add_category))
                },
                onClick = {},
                modifier = Modifier.padding(4.dp)
            )

            AppDropdownMenuItem(
                text = {
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        AppOutlinedTextField(
                            value = state.newCategoryName,
                            onValueChange = onNewCategoryNameChange,
                            modifier = Modifier.weight(1f),
                            singleLine = true,
                        )
                        Spacer(modifier = Modifier.width(8.dp))
                        IconButton(
                            onClick = {
                                if (state.newCategoryName.isNotBlank()) {
                                    onAddCategory(state.newCategoryName.trim())
                                }
                            },
                            enabled = state.newCategoryName.isNotBlank()
                        ) {
                            Icon(
                                imageVector = AppIcons.Add,
                                contentDescription = stringResource(R.string.label_add)
                            )
                        }
                    }
                },
                onClick = {}
            )
        }

        if (multipleSelectable) {
            Spacer(modifier = Modifier.height(8.dp))
            AppButton(
                onClick = { onExpand(false) },
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(8.dp)
            ) {
                Text(stringResource(R.string.label_done))
            }
        }
    }
}

/**
 * Stateful wrapper for CategoryDropdown that manages its own state.
 * This is the main composable that should be used in production code.
 *
 * @param initialCategoryId The initial category ID to select
 * @param onCategorySelected Callback when categories are selected
 * @param noneSelectable Whether "None" option is selectable
 * @param multipleSelectable Whether multiple categories can be selected
 * @param onlyLists Whether to show only list/category types
 * @param addCategory Whether to show the "Add Category" option
 * @param modifier Modifier for the composable
 */
@Composable
fun CategoryDropdown(
    initialCategoryId: Int? = null,
    onCategorySelected: (List<VocabularyCategory?>) -> Unit,
    noneSelectable: Boolean? = true,
    multipleSelectable: Boolean = false,
    onlyLists: Boolean = false,
    addCategory: Boolean = false,
    modifier: Modifier = Modifier,
) {
    var expanded by remember { mutableStateOf(false) }
    var selectedCategories by remember {
        mutableStateOf<List<VocabularyCategory?>>(emptyList())
    }
    var newCategoryName by remember { mutableStateOf("") }

    // For production use, this would come from ViewModel
    // For preview, we'll use empty list or pass via state
    val categories by remember { mutableStateOf(emptyList<VocabularyCategory>()) }

    // Find initial category
    val initialCategory = remember(categories, initialCategoryId) {
        categories.find { it.id == initialCategoryId }
    }

    // Initialize selection with initial category if provided
    remember(initialCategory) {
        if (initialCategory != null && selectedCategories.isEmpty()) {
            selectedCategories = listOf(initialCategory)
        }
        true
    }

    CategoryDropdownContent(
        state = CategoryDropdownState(
            expanded = expanded,
            selectedCategories = selectedCategories,
            newCategoryName = newCategoryName,
            categories = categories,
        ),
        onExpand = { isExpanded -> expanded = isExpanded },
        onCategorySelected = { newSelection ->
            selectedCategories = newSelection
            onCategorySelected(newSelection)
        },
        onNewCategoryNameChange = { newCategoryName = it },
        onAddCategory = { name ->
            val newCategory = TagCategory(id = 0, name = name)
            // In production, this would call ViewModel.createCategory(newCategory)
            newCategoryName = ""
            if (!multipleSelectable) {
                expanded = false
            }
        },
        noneSelectable = noneSelectable == true,
        multipleSelectable = multipleSelectable,
        onlyLists = onlyLists,
        addCategory = addCategory,
        modifier = modifier,
    )
}

// ============== PREVIEWS ==============

/**
 * Preview provider for CategoryDropdownState
 */
@Suppress("HardCodedStringLiteral")
class CategoryDropdownStateProvider : PreviewParameterProvider<CategoryDropdownState> {
    override val values = sequenceOf(
        // Collapsed state - nothing selected
        CategoryDropdownState(
            expanded = false,
            selectedCategories = emptyList(),
            categories = listOf(
                TagCategory(1, "Animals"),
                TagCategory(2, "Food"),
                VocabularyFilter(3, "Filters", languages = listOf(1, 2)),
            )
        ),
        // Collapsed state - one category selected
        CategoryDropdownState(
            expanded = false,
            selectedCategories = listOf(TagCategory(1, "Animals")),
            categories = listOf(
                TagCategory(1, "Animals"),
                TagCategory(2, "Food"),
                TagCategory(3, "Travel"),
            )
        ),
        // Collapsed state - multiple categories selected
        CategoryDropdownState(
            expanded = false,
            selectedCategories = listOf(
                TagCategory(1, "Animals"),
                TagCategory(3, "Travel"),
            ),
            categories = listOf(
                TagCategory(1, "Animals"),
                TagCategory(2, "Food"),
                TagCategory(3, "Travel"),
            )
        ),
        // Expanded state - nothing selected
        CategoryDropdownState(
            expanded = true,
            selectedCategories = emptyList(),
            categories = listOf(
                TagCategory(1, "Animals"),
                TagCategory(2, "Food"),
                TagCategory(3, "Travel"),
            )
        ),
        // Expanded state - one selected
        CategoryDropdownState(
            expanded = true,
            selectedCategories = listOf(TagCategory(2, "Food")),
            categories = listOf(
                TagCategory(1, "Animals"),
                TagCategory(2, "Food"),
                TagCategory(3, "Travel"),
            )
        ),
        // With "None" option selected
        CategoryDropdownState(
            expanded = true,
            selectedCategories = listOf(null),
            categories = listOf(
                TagCategory(1, "Animals"),
                TagCategory(2, "Food"),
            )
        ),
        // With add category option
        CategoryDropdownState(
            expanded = true,
            selectedCategories = emptyList(),
            newCategoryName = "New Cat",
            categories = listOf(
                TagCategory(1, "Animals"),
                TagCategory(2, "Food"),
            )
        ),
    )
}

@ThemePreviews
@Preview(showBackground = true)
@Composable
fun CategoryDropdownCollapsedPreview(
    @PreviewParameter(CategoryDropdownStateProvider::class) state: CategoryDropdownState
) {
    Surface(
        modifier = Modifier.padding(16.dp),
        color = MaterialTheme.colorScheme.background
    ) {
        CategoryDropdownContent(
            state = state.copy(expanded = false),
            onExpand = {},
            onCategorySelected = {},
            onNewCategoryNameChange = {},
            onAddCategory = {},
        )
    }
}

@ThemePreviews
@Preview(showBackground = true)
@Composable
fun CategoryDropdownExpandedPreview(
    @PreviewParameter(CategoryDropdownStateProvider::class) state: CategoryDropdownState
) {
    Surface(
        modifier = Modifier.padding(16.dp),
        color = MaterialTheme.colorScheme.background
    ) {
        CategoryDropdownContent(
            state = state.copy(expanded = true),
            onExpand = {},
            onCategorySelected = {},
            onNewCategoryNameChange = {},
            onAddCategory = {},
        )
    }
}

@Suppress("HardCodedStringLiteral")
@ThemePreviews
@Preview(showBackground = true)
@Composable
fun CategoryDropdownMultipleSelectionPreview() {
    val categories = listOf(
        TagCategory(1, "Animals"),
        TagCategory(2, "Food"),
        TagCategory(3, "Travel"),
        TagCategory(4, "Business"),
        TagCategory(5, "Technology"),
    )
    var selectedCategories by remember {
        mutableStateOf<List<VocabularyCategory?>>(listOf(categories[0], categories[2]))
    }

    Surface(
        modifier = Modifier.padding(16.dp),
        color = MaterialTheme.colorScheme.background
    ) {
        CategoryDropdownContent(
            state = CategoryDropdownState(
                expanded = true,
                selectedCategories = selectedCategories,
                categories = categories,
            ),
            onExpand = {},
            onCategorySelected = { selectedCategories = it },
            onNewCategoryNameChange = {},
            onAddCategory = {},
            multipleSelectable = true,
            noneSelectable = true,
        )
    }
}

@Suppress("HardCodedStringLiteral")
@ThemePreviews
@Preview(showBackground = true)
@Composable
fun CategoryDropdownWithAddCategoryPreview() {
    val categories = listOf(
        TagCategory(1, "Animals"),
        TagCategory(2, "Food"),
    )
    var newCategoryName by remember { mutableStateOf("New Category") }

    Surface(
        modifier = Modifier.padding(16.dp),
        color = MaterialTheme.colorScheme.background
    ) {
        CategoryDropdownContent(
            state = CategoryDropdownState(
                expanded = true,
                selectedCategories = emptyList(),
                newCategoryName = newCategoryName,
                categories = categories,
            ),
            onExpand = {},
            onCategorySelected = {},
            onNewCategoryNameChange = { newCategoryName = it },
            onAddCategory = {},
            addCategory = true,
        )
    }
}

@Suppress("HardCodedStringLiteral")
@ThemePreviews
@Preview(showBackground = true)
@Composable
fun CategoryDropdownOnlyListsPreview() {
    val categories = listOf(
        TagCategory(1, "Animals"),
        TagCategory(2, "Food"),
        VocabularyFilter(3, "Language Pair EN-DE", languages = listOf(1, 2)),
        TagCategory(4, "Travel"),
    )

    Surface(
        modifier = Modifier.padding(16.dp),
        color = MaterialTheme.colorScheme.background
    ) {
        CategoryDropdownContent(
            state = CategoryDropdownState(
                expanded = true,
                selectedCategories = emptyList(),
                categories = categories,
            ),
            onExpand = {},
            onCategorySelected = {},
            onNewCategoryNameChange = {},
            onAddCategory = {},
            onlyLists = true,
        )
    }
}

@Suppress("HardCodedStringLiteral")
@ThemePreviews
@Preview(showBackground = true)
@Composable
fun CategoryDropdownNoNoneOptionPreview() {
    val categories = listOf(
        TagCategory(1, "Animals"),
        TagCategory(2, "Food"),
    )

    Surface(
        modifier = Modifier.padding(16.dp),
        color = MaterialTheme.colorScheme.background
    ) {
        CategoryDropdownContent(
            state = CategoryDropdownState(
                expanded = true,
                selectedCategories = emptyList(),
                categories = categories,
            ),
            onExpand = {},
            onCategorySelected = {},
            onNewCategoryNameChange = {},
            onAddCategory = {},
            noneSelectable = false,
        )
    }
}

@ThemePreviews
@Preview(showBackground = true)
@Composable
fun CategoryDropdownEmptyPreview() {
    Surface(
        modifier = Modifier.padding(16.dp),
        color = MaterialTheme.colorScheme.background
    ) {
        CategoryDropdownContent(
            state = CategoryDropdownState(
                expanded = false,
                selectedCategories = emptyList(),
                categories = emptyList(),
            ),
            onExpand = {},
            onCategorySelected = {},
            onNewCategoryNameChange = {},
            onAddCategory = {},
        )
    }
}

@Suppress("HardCodedStringLiteral")
@ThemePreviews
@Preview(showBackground = true)
@Composable
fun CategoryDropdownStatefulPreview() {
    var expanded by remember { mutableStateOf(true) }
    var selectedCategories by remember {
        mutableStateOf<List<VocabularyCategory?>>(listOf(TagCategory(1, "Animals")))
    }

    Surface(
        modifier = Modifier.padding(16.dp),
        color = MaterialTheme.colorScheme.background
    ) {
        CategoryDropdownContent(
            state = CategoryDropdownState(
                expanded = expanded,
                selectedCategories = selectedCategories,
                categories = listOf(
                    TagCategory(1, "Animals"),
                    TagCategory(2, "Food"),
                    TagCategory(3, "Travel"),
                ),
            ),
            onExpand = { expanded = it },
            onCategorySelected = { selectedCategories = it },
            onNewCategoryNameChange = {},
            onAddCategory = {},
            multipleSelectable = true,
            noneSelectable = true,
        )
    }
}

@Suppress("HardCodedStringLiteral")
@ThemePreviews
@Preview(showBackground = true)
@Composable
fun CategoryDropdownFullExpandedPreview() {
    Surface(
        modifier = Modifier.padding(16.dp),
        color = MaterialTheme.colorScheme.background
    ) {
        CategoryDropdownContent(
            state = CategoryDropdownState(
                expanded = true,
                selectedCategories = emptyList(),
                categories = listOf(
                    TagCategory(1, "Animals"),
                    TagCategory(2, "Food"),
                    TagCategory(3, "Travel"),
                    TagCategory(4, "Business"),
                    TagCategory(5, "Technology"),
                    TagCategory(6, "Sports"),
                    TagCategory(7, "Music"),
                    TagCategory(8, "Art"),
                ),
            ),
            onExpand = {},
            onCategorySelected = {},
            onNewCategoryNameChange = {},
            onAddCategory = {},
            addCategory = true,
            multipleSelectable = true,
            noneSelectable = true,
        )
    }
}
