@file:Suppress("AssignedValueIsNeverRead", "HardCodedStringLiteral")

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.padding
import androidx.compose.foundation.layout.width
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.collectAsState
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.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import eu.gaudian.translator.R
import eu.gaudian.translator.model.TagCategory
import eu.gaudian.translator.model.VocabularyCategory
import eu.gaudian.translator.ui.theme.ThemePreviews
import eu.gaudian.translator.utils.findActivity
import eu.gaudian.translator.view.composable.AppCheckbox
import eu.gaudian.translator.view.composable.AppDropdownContainer
import eu.gaudian.translator.view.composable.AppDropdownMenuItem
import eu.gaudian.translator.view.composable.AppIcons
import eu.gaudian.translator.view.composable.AppOutlinedTextField
import eu.gaudian.translator.view.composable.DropdownHeader
import eu.gaudian.translator.viewmodel.CategoryViewModel


/**
 * 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(),
    val searchQuery: String = "",
)

/**
 * Stateless dropdown content composable for category selection.
 * This component is fully controlled by its parameters and does not maintain any internal state.
 */
@Composable
fun CategoryDropdownContent(
    modifier: Modifier = Modifier,
    state: CategoryDropdownState,
    onExpand: (Boolean) -> Unit,
    onCategorySelected: (List<VocabularyCategory?>) -> Unit,
    onNewCategoryNameChange: (String) -> Unit,
    onAddCategory: (String) -> Unit,
    onSearchQueryChange: (String) -> Unit = {},
    noneSelectable: Boolean = true,
    multipleSelectable: Boolean = false,
    onlyLists: Boolean = false,
    addCategory: Boolean = false,
    enableSearch: Boolean = false,
) {
    val selectableCategories = if (onlyLists) {
        state.categories.filterIsInstance<TagCategory>()
    } else {
        state.categories
    }

    // Filter categories by search query if search is enabled
    val filteredCategories = if (enableSearch && state.searchQuery.isNotBlank()) {
        selectableCategories.filter { category ->
            category.name.contains(state.searchQuery, ignoreCase = true)
        }
    } else {
        selectableCategories
    }

    val buttonText = when {
        state.selectedCategories.isEmpty() -> stringResource(R.string.text_select_category)
        state.selectedCategories.size == 1 -> state.selectedCategories.first()?.name
            ?: stringResource(R.string.label_no_category)
        else -> stringResource(R.string.text_2d_categories_selected, state.selectedCategories.size)
    }

    AppDropdownContainer(
        expanded = state.expanded,
        onDismissRequest = { onExpand(false) },
        onExpandRequest = { onExpand(true) },
        buttonText = buttonText,
        modifier = modifier,
        showSearch = enableSearch,
        searchQuery = state.searchQuery,
        onSearchQueryChange = onSearchQueryChange,
        searchPlaceholder = stringResource(R.string.text_search),
        showDoneButton = multipleSelectable,
        onDoneClick = { onExpand(false) }
    ) {
        if (noneSelectable) {
            val noneSelected = state.selectedCategories.contains(null)
            AppDropdownMenuItem(
                text = {
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        if (multipleSelectable) {
                            AppCheckbox(
                                checked = noneSelected,
                                onCheckedChange = { _ ->
                                    val newSelection = if (noneSelected) {
                                        state.selectedCategories.filterNotNull()
                                    } else {
                                        state.selectedCategories + listOf(null)
                                    }
                                    onCategorySelected(newSelection)
                                }
                            )
                            Spacer(modifier = Modifier.width(8.dp))
                        }
                        Text(
                            text = stringResource(R.string.label_no_category),
                            color = MaterialTheme.colorScheme.onSurface
                        )
                    }
                },
                onClick = {
                    if (multipleSelectable) {
                        val newSelection = if (noneSelected) {
                            state.selectedCategories.filterNotNull()
                        } else {
                            state.selectedCategories + listOf(null)
                        }
                        onCategorySelected(newSelection)
                    } else {
                        onCategorySelected(listOf(null))
                        onExpand(false)
                    }
                }
            )
        }

        filteredCategories.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(
                            text = category.name,
                            color = MaterialTheme.colorScheme.onSurface
                        )
                    }
                },
                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 (enableSearch && state.searchQuery.isNotBlank() && filteredCategories.isEmpty()) {
            AppDropdownMenuItem(
                text = {
                    Text(
                        text = stringResource(R.string.text_no_models_found),
                        color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f),
                        modifier = Modifier.fillMaxWidth()
                    )
                },
                onClick = {},
                enabled = false
            )
        }

        if (addCategory) {
            HorizontalDivider(modifier = Modifier.padding(vertical = 4.dp))

            DropdownHeader(text = stringResource(R.string.label_add_category))

            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(4.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 = {}
            )
        }
    }
}

/**
 * Stateful wrapper for CategoryDropdown that manages its own state.
 */
@Composable
fun CategoryDropdown(
    modifier: Modifier = Modifier,
    initialCategoryId: Int? = null,
    onCategorySelected: (List<VocabularyCategory?>) -> Unit,
    noneSelectable: Boolean? = true,
    multipleSelectable: Boolean = false,
    onlyLists: Boolean = false,
    addCategory: Boolean = false,
    enableSearch: Boolean = false,
) {
    var expanded by remember { mutableStateOf(false) }
    var selectedCategories by remember {
        mutableStateOf<List<VocabularyCategory?>>(emptyList())
    }
    var newCategoryName by remember { mutableStateOf("") }
    var searchQuery by remember { mutableStateOf("") }

    val activity = LocalContext.current.findActivity()
    val categoryViewModel: CategoryViewModel = hiltViewModel(viewModelStoreOwner = activity)
    val categories by categoryViewModel.categories.collectAsState(initial = emptyList())

    val initialCategory = remember(categories, initialCategoryId) {
        categories.find { it.id == initialCategoryId }
    }

    remember(initialCategory) {
        if (initialCategory != null && selectedCategories.isEmpty()) {
            selectedCategories = listOf(initialCategory)
        }
        true
    }

    CategoryDropdownContent(
        state = CategoryDropdownState(
            expanded = expanded,
            selectedCategories = selectedCategories,
            newCategoryName = newCategoryName,
            categories = categories,
            searchQuery = searchQuery,
        ),
        onExpand = { isExpanded -> expanded = isExpanded },
        onCategorySelected = { newSelection ->
            selectedCategories = newSelection
            onCategorySelected(newSelection)
        },
        onNewCategoryNameChange = { newCategoryName = it },
        onAddCategory = { name ->
            val newCategory = TagCategory(id = 0, name = name)
            newCategoryName = ""
            categoryViewModel.createCategory(newCategory)
            //selectedCategories = selectedCategories + newCategory
            if (!multipleSelectable) {
                expanded = false
            }
        },
        onSearchQueryChange = { searchQuery = it },
        noneSelectable = noneSelectable == true,
        multipleSelectable = multipleSelectable,
        onlyLists = onlyLists,
        addCategory = addCategory,
        enableSearch = enableSearch,
        modifier = modifier,
    )
}


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

@ThemePreviews
@Preview(showBackground = true)
@Composable
fun CategoryDropdownExpandedPreview() {
    Surface(modifier = Modifier.padding(16.dp), color = MaterialTheme.colorScheme.background) {
        CategoryDropdownContent(
            state = CategoryDropdownState(
                expanded = true,
                selectedCategories = listOf(TagCategory(1, "Animals")),
                categories = listOf(TagCategory(1, "Animals"), TagCategory(2, "Food"), TagCategory(3, "Travel")),
            ),
            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"))
    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() {
    Surface(modifier = Modifier.padding(16.dp), color = MaterialTheme.colorScheme.background) {
        CategoryDropdownContent(
            state = CategoryDropdownState(
                expanded = true,
                selectedCategories = emptyList(),
                newCategoryName = "New Cat",
                categories = listOf(TagCategory(1, "Animals"), TagCategory(2, "Food")),
            ),
            onExpand = {},
            onCategorySelected = {},
            onNewCategoryNameChange = {},
            onAddCategory = {},
            addCategory = true,
        )
    }
}

@Suppress("HardCodedStringLiteral")
@ThemePreviews
@Preview(showBackground = true)
@Composable
fun CategoryDropdownWithSearchPreview() {
    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, "Technology"),
                    TagCategory(5, "Sports")
                ),
                searchQuery = "",
            ),
            onExpand = {},
            onCategorySelected = {},
            onNewCategoryNameChange = {},
            onAddCategory = {},
            enableSearch = true,
        )
    }
}
