package com.example.ops_android.ui.workorder

import android.content.Context
import android.net.Uri
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.example.ops_android.data.local.SessionManager
import com.example.ops_android.data.model.Customer
import com.example.ops_android.data.model.Item
import com.example.ops_android.data.remote.api.FileApi
import com.example.ops_android.data.remote.api.FileUploadResponse
import com.example.ops_android.data.repository.CustomerRepository
import com.example.ops_android.data.repository.WarehouseRepository
import com.example.ops_android.data.repository.WorkOrderRepository
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.toRequestBody

data class UploadedPhoto(
    val uri: Uri,
    val hash: String? = null,
    val isUploading: Boolean = false
)

data class WorkOrderFormUiState(
    val title: String = "",
    val description: String = "",
    val selectedItems: List<Item> = emptyList(),
    val selectedCustomers: List<Customer> = emptyList(),
    val photos: List<UploadedPhoto> = emptyList(),
    val itemSearchQuery: String = "",
    val itemSearchResults: List<Item> = emptyList(),
    val isSearchingItems: Boolean = false,
    val customerSearchQuery: String = "",
    val customerSearchResults: List<Customer> = emptyList(),
    val isSearchingCustomers: Boolean = false,
    val isSubmitting: Boolean = false,
    val errorMessage: String? = null,
    val success: Boolean = false
)

class WorkOrderFormViewModel(
    private val repo: WorkOrderRepository,
    private val warehouseRepo: WarehouseRepository,
    private val customerRepo: CustomerRepository,
    private val fileApi: FileApi,
    private val sessionManager: SessionManager,
    private val context: Context,
    private val editId: Int? = null,
    private val prefillItemId: Int? = null
) : ViewModel() {
    private val _s = MutableStateFlow(WorkOrderFormUiState())
    val s: StateFlow<WorkOrderFormUiState> = _s.asStateFlow()

    private var itemSearchJob: Job? = null
    private var customerSearchJob: Job? = null

    init {
        prefillItemId?.let { itemId ->
            viewModelScope.launch {
                val result = warehouseRepo.getItem(itemId)
                result.fold(
                    onSuccess = { resp ->
                        val item = resp.item
                        if (item != null) {
                            _s.value = _s.value.copy(
                                title = item.name ?: "",
                                description = listOfNotNull(item.serial_number, item.remark).joinToString("\n"),
                                selectedItems = listOf(item)
                            )
                        }
                        // Pre-fill linked customers
                        resp.customers?.forEach { cInfo ->
                            val c = Customer(
                                id = cInfo.id,
                                first_name = cInfo.first_name,
                                last_name = cInfo.last_name,
                                phone = cInfo.primary_phone
                            )
                            _s.value = _s.value.copy(selectedCustomers = _s.value.selectedCustomers + c)
                        }
                    },
                    onFailure = { }
                )
            }
        }
    }

    fun onTitle(v: String) { _s.value = _s.value.copy(title = v) }
    fun onDesc(v: String) { _s.value = _s.value.copy(description = v) }

    fun onItemSearchQuery(v: String) {
        _s.value = _s.value.copy(itemSearchQuery = v)
        itemSearchJob?.cancel()
        itemSearchJob = viewModelScope.launch {
            delay(300)
            if (v.isBlank()) {
                _s.value = _s.value.copy(itemSearchResults = emptyList(), isSearchingItems = false)
                return@launch
            }
            _s.value = _s.value.copy(isSearchingItems = true)
            warehouseRepo.searchItems(v).fold(
                onSuccess = { _s.value = _s.value.copy(itemSearchResults = it, isSearchingItems = false) },
                onFailure = { _s.value = _s.value.copy(isSearchingItems = false) }
            )
        }
    }

    fun addItem(item: Item) {
        val current = _s.value.selectedItems
        if (current.none { it.id == item.id }) {
            _s.value = _s.value.copy(selectedItems = current + item, itemSearchQuery = "", itemSearchResults = emptyList())
        }
    }

    fun removeItem(item: Item) {
        _s.value = _s.value.copy(selectedItems = _s.value.selectedItems.filter { it.id != item.id })
    }

    fun onCustomerSearchQuery(v: String) {
        _s.value = _s.value.copy(customerSearchQuery = v)
        customerSearchJob?.cancel()
        customerSearchJob = viewModelScope.launch {
            delay(300)
            if (v.isBlank()) {
                _s.value = _s.value.copy(customerSearchResults = emptyList(), isSearchingCustomers = false)
                return@launch
            }
            _s.value = _s.value.copy(isSearchingCustomers = true)
            customerRepo.list(v).fold(
                onSuccess = { _s.value = _s.value.copy(customerSearchResults = it, isSearchingCustomers = false) },
                onFailure = { _s.value = _s.value.copy(isSearchingCustomers = false) }
            )
        }
    }

    fun addCustomer(c: Customer) {
        val current = _s.value.selectedCustomers
        if (current.none { it.id == c.id }) {
            _s.value = _s.value.copy(selectedCustomers = current + c, customerSearchQuery = "", customerSearchResults = emptyList())
        }
    }

    fun removeCustomer(c: Customer) {
        _s.value = _s.value.copy(selectedCustomers = _s.value.selectedCustomers.filter { it.id != c.id })
    }

    fun addPhoto(uri: Uri) {
        val photo = UploadedPhoto(uri = uri, isUploading = true)
        _s.value = _s.value.copy(photos = _s.value.photos + photo)
        viewModelScope.launch {
            val inputStream = context.contentResolver.openInputStream(uri)
            val bytes = inputStream?.readBytes() ?: return@launch
            inputStream.close()
            val mime = context.contentResolver.getType(uri) ?: "image/jpeg"
            val requestBody = bytes.toRequestBody(mime.toMediaTypeOrNull())
            val filePart = MultipartBody.Part.createFormData("file", "photo.jpg", requestBody)
            val cookiePart = sessionManager.cachedCookieValue
                .toRequestBody("text/plain".toMediaTypeOrNull())
            val result = try {
                val response = fileApi.uploadImage(cookiePart, filePart)
                if (response.errCode == 0 && response.data != null) response.data else null
            } catch (e: Exception) { null }
            _s.value = _s.value.copy(photos = _s.value.photos.map {
                if (it.uri == uri) it.copy(hash = result?.hash, isUploading = false)
                else it
            })
        }
    }

    fun removePhoto(uri: Uri) {
        _s.value = _s.value.copy(photos = _s.value.photos.filter { it.uri != uri })
    }

    fun submit() {
        if (_s.value.title.isBlank()) { _s.value = _s.value.copy(errorMessage = "标题不能为空"); return }
        val state = _s.value
        val data = mutableMapOf<String, Any>(
            "title" to state.title,
            "description" to state.description
        )
        if (state.selectedItems.isNotEmpty()) {
            data["item_ids"] = state.selectedItems.map { it.id }
        }
        if (state.selectedCustomers.isNotEmpty()) {
            data["customer_ids"] = state.selectedCustomers.map { it.id }
        }
        val photoHashes = state.photos.mapNotNull { it.hash }
        if (photoHashes.isNotEmpty()) {
            data["photos"] = photoHashes
        }
        viewModelScope.launch {
            _s.value = _s.value.copy(isSubmitting = true, errorMessage = null)
            val r = if (editId != null) repo.update(data + ("id" to editId)) else repo.add(data)
            r.fold(
                onSuccess = { _s.value = _s.value.copy(isSubmitting = false, success = true) },
                onFailure = { _s.value = _s.value.copy(isSubmitting = false, errorMessage = it.message) }
            )
        }
    }

    class Factory(
        private val repo: WorkOrderRepository,
        private val warehouseRepo: WarehouseRepository,
        private val customerRepo: CustomerRepository,
        private val fileApi: FileApi,
        private val sessionManager: SessionManager,
        private val context: Context,
        private val editId: Int? = null,
        private val prefillItemId: Int? = null
    ) : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(c: Class<T>): T =
            WorkOrderFormViewModel(repo, warehouseRepo, customerRepo, fileApi, sessionManager, context, editId, prefillItemId) as T
    }
}
