package com.example.ops_android.ui.search

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.example.ops_android.data.model.Container
import com.example.ops_android.data.model.Item
import com.example.ops_android.data.model.PurchaseOrder
import com.example.ops_android.data.model.WorkOrder
import com.example.ops_android.data.repository.CustomerRepository
import com.example.ops_android.data.repository.OrderRepository
import com.example.ops_android.data.repository.WarehouseRepository
import com.example.ops_android.data.repository.WorkOrderRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

enum class SearchCategory(val label: String) {
    ALL("全部"),
    ORDER("订单"),
    WORK_ORDER("工单"),
    ITEM("物品"),
    CONTAINER("容器")
}

data class SearchUiState(
    val query: String = "",
    val category: SearchCategory = SearchCategory.ALL,
    val orders: List<PurchaseOrder> = emptyList(),
    val workOrders: List<WorkOrder> = emptyList(),
    val items: List<Item> = emptyList(),
    val containers: List<Container> = emptyList(),
    val isSearching: Boolean = false,
    val errorMessage: String? = null
)

class SearchViewModel(
    private val orderRepository: OrderRepository,
    private val workOrderRepository: WorkOrderRepository,
    private val warehouseRepository: WarehouseRepository
) : ViewModel() {

    private val _uiState = MutableStateFlow(SearchUiState())
    val uiState: StateFlow<SearchUiState> = _uiState.asStateFlow()

    fun onQueryChange(value: String) {
        _uiState.value = _uiState.value.copy(query = value)
    }

    fun selectCategory(category: SearchCategory) {
        _uiState.value = _uiState.value.copy(category = category)
    }

    fun onBarcodeScanned(barcode: String) {
        _uiState.value = _uiState.value.copy(query = barcode)
        search()
    }

    fun search() {
        val query = _uiState.value.query.trim()
        if (query.isEmpty()) return

        // Parse prefix shortcuts
        val (actualCategory, actualQuery) = parsePrefix(query)
        _uiState.value = _uiState.value.copy(category = actualCategory)

        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isSearching = true, errorMessage = null)

            when (actualCategory) {
                SearchCategory.ALL -> {
                    launch { orderRepository.getOrders(search = actualQuery, entries = 10).fold(
                        onSuccess = { (list, _) -> _uiState.value = _uiState.value.copy(orders = list) },
                        onFailure = { }
                    )}
                    launch { workOrderRepository.list(search = actualQuery, entries = 10).fold(
                        onSuccess = { (list, _) -> _uiState.value = _uiState.value.copy(workOrders = list) },
                        onFailure = { }
                    )}
                    launch { warehouseRepository.listItem().fold(
                        onSuccess = { _uiState.value = _uiState.value.copy(items = it.filter { item -> item.name?.contains(actualQuery, true) == true || item.serial_number?.contains(actualQuery, true) == true || item.barcode?.contains(actualQuery, true) == true }.take(10)) },
                        onFailure = { }
                    )}
                    launch { warehouseRepository.listContainer().fold(
                        onSuccess = { _uiState.value = _uiState.value.copy(containers = it.filter { c -> c.name?.contains(actualQuery, true) == true || c.barcode?.contains(actualQuery, true) == true }.take(10)) },
                        onFailure = { }
                    )}
                }
                SearchCategory.ORDER -> {
                    orderRepository.getOrders(search = actualQuery, entries = 20).fold(
                        onSuccess = { (list, _) -> _uiState.value = _uiState.value.copy(orders = list) },
                        onFailure = { _uiState.value = _uiState.value.copy(errorMessage = it.message) }
                    )
                }
                SearchCategory.WORK_ORDER -> {
                    workOrderRepository.list(search = actualQuery, entries = 20).fold(
                        onSuccess = { (list, _) -> _uiState.value = _uiState.value.copy(workOrders = list) },
                        onFailure = { _uiState.value = _uiState.value.copy(errorMessage = it.message) }
                    )
                }
                SearchCategory.ITEM -> {
                    warehouseRepository.listItem().fold(
                        onSuccess = { items ->
                            _uiState.value = _uiState.value.copy(items = items.filter { it.name?.contains(actualQuery, true) == true || it.serial_number?.contains(actualQuery, true) == true || it.barcode?.contains(actualQuery, true) == true })
                        },
                        onFailure = { _uiState.value = _uiState.value.copy(errorMessage = it.message) }
                    )
                }
                SearchCategory.CONTAINER -> {
                    warehouseRepository.listContainer().fold(
                        onSuccess = { containers ->
                            _uiState.value = _uiState.value.copy(containers = containers.filter { it.name?.contains(actualQuery, true) == true || it.barcode?.contains(actualQuery, true) == true })
                        },
                        onFailure = { _uiState.value = _uiState.value.copy(errorMessage = it.message) }
                    )
                }
            }

            _uiState.value = _uiState.value.copy(isSearching = false)
        }
    }

    fun clearResults() {
        _uiState.value = SearchUiState(query = _uiState.value.query, category = _uiState.value.category)
    }

    private fun parsePrefix(query: String): Pair<SearchCategory, String> {
        val prefixes = mapOf(
            "po:" to SearchCategory.ORDER,
            "wo:" to SearchCategory.WORK_ORDER,
            "item:" to SearchCategory.ITEM,
            "warehouse:" to SearchCategory.CONTAINER
        )
        for ((prefix, category) in prefixes) {
            if (query.startsWith(prefix, ignoreCase = true)) {
                return category to query.removeRange(0, prefix.length).trim()
            }
        }
        return _uiState.value.category to query
    }

    class Factory(
        private val orderRepository: OrderRepository,
        private val workOrderRepository: WorkOrderRepository,
        private val warehouseRepository: WarehouseRepository
    ) : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return SearchViewModel(orderRepository, workOrderRepository, warehouseRepository) as T
        }
    }
}
