package com.example.ops_android.ui.warehouse

import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.FileProvider
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
import com.example.ops_android.data.local.SessionManager
import com.example.ops_android.data.model.Customer
import com.example.ops_android.data.remote.api.FileApi
import com.example.ops_android.data.repository.CustomerRepository
import com.example.ops_android.data.repository.WarehouseRepository
import com.example.ops_android.ui.LocalAppContainer
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
import java.io.File

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

data class ItemFormUiState(
    val name: String = "",
    val serialNumber: String = "",
    val quantity: String = "1",
    val remark: String = "",
    val selectedCustomers: List<Customer> = emptyList(),
    val photos: List<ItemPhoto> = emptyList(),
    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 ItemFormViewModel(
    private val repo: WarehouseRepository,
    private val customerRepo: CustomerRepository,
    private val fileApi: FileApi,
    private val sessionManager: SessionManager,
    private val context: android.content.Context,
    private val containerId: Int,
    private val editId: Int? = null
) : ViewModel() {
    private val _s = MutableStateFlow(ItemFormUiState()); val s: StateFlow<ItemFormUiState> = _s.asStateFlow()
    private var customerSearchJob: Job? = null

    fun onName(v: String) { _s.value = _s.value.copy(name = v) }
    fun onSerial(v: String) { _s.value = _s.value.copy(serialNumber = v) }
    fun onQuantity(v: String) {
        if (v.isEmpty() || v.all { it.isDigit() }) {
            _s.value = _s.value.copy(quantity = v)
        }
    }
    fun onRemark(v: String) { _s.value = _s.value.copy(remark = v) }

    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 = ItemPhoto(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.name.isBlank()) { _s.value = _s.value.copy(errorMessage = "名称不能为空"); return }
        val state = _s.value
        val qty = state.quantity.toIntOrNull() ?: 1
        val data = mutableMapOf<String, Any>(
            "name" to state.name,
            "serial_number" to state.serialNumber,
            "quantity" to qty,
            "remark" to state.remark
        )
        if (containerId > 0) {
            data["container_id"] = containerId
        }
        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.updateItem(data + ("id" to editId)) else repo.addItem(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: WarehouseRepository,
        private val customerRepo: CustomerRepository,
        private val fileApi: FileApi,
        private val sessionManager: SessionManager,
        private val context: android.content.Context,
        private val containerId: Int,
        private val editId: Int? = null
    ) : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(c: Class<T>): T =
            ItemFormViewModel(repo, customerRepo, fileApi, sessionManager, context, containerId, editId) as T
    }
}

private fun createTempImageFile(context: android.content.Context): File {
    val dir = File(context.cacheDir, "photos")
    if (!dir.exists()) dir.mkdirs()
    return File(dir, "capture_${System.currentTimeMillis()}.jpg")
}

@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Composable
fun ItemFormScreen(containerId: Int = 0, editId: Int? = null, onBack: () -> Unit, onSaved: () -> Unit) {
    val app = LocalAppContainer.current
    val context = LocalContext.current
    val vm: ItemFormViewModel = viewModel(
        key = "item_form_$editId",
        factory = ItemFormViewModel.Factory(app.warehouseRepository, app.customerRepository, app.fileApi, app.sessionManager, context, containerId, editId)
    )
    val s by vm.s.collectAsState()
    LaunchedEffect(s.success) { if (s.success) onSaved() }

    var showPhotoDialog by remember { mutableStateOf(false) }
    var cameraFileUri by remember { mutableStateOf<Uri?>(null) }

    val cameraLauncher = rememberLauncherForActivityResult(ActivityResultContracts.TakePicture()) { success ->
        val uri = cameraFileUri
        if (success && uri != null) vm.addPhoto(uri)
    }
    val galleryLauncher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri ->
        uri?.let { vm.addPhoto(it) }
    }

    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text(if (editId != null) "编辑物品" else "添加物品") },
                navigationIcon = { IconButton(onClick = onBack) { Icon(Icons.AutoMirrored.Filled.ArrowBack, null, tint = Color.White) } },
                colors = TopAppBarDefaults.topAppBarColors(containerColor = Color(0xFF667EEA), titleContentColor = Color.White)
            )
        }
    ) { padding ->
        Column(Modifier.fillMaxSize().padding(padding).padding(16.dp).verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(12.dp)) {
            OutlinedTextField(s.name, vm::onName, label = { Text("物品名称 *") }, modifier = Modifier.fillMaxWidth(), singleLine = true)
            OutlinedTextField(s.serialNumber, vm::onSerial, label = { Text("序列号") }, modifier = Modifier.fillMaxWidth(), singleLine = true)
            OutlinedTextField(
                s.quantity, vm::onQuantity, label = { Text("数量") },
                modifier = Modifier.fillMaxWidth(), singleLine = true,
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
            )
            OutlinedTextField(s.remark, vm::onRemark, label = { Text("备注") }, modifier = Modifier.fillMaxWidth(), minLines = 2)

            // ── 关联客户 ──
            Text("关联客户", fontWeight = FontWeight.Bold, fontSize = 15.sp)
            if (s.selectedCustomers.isNotEmpty()) {
                FlowRow(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(4.dp)) {
                    s.selectedCustomers.forEach { c ->
                        InputChip(
                            selected = true, onClick = { vm.removeCustomer(c) },
                            label = { Text(c.name ?: "?", fontSize = 12.sp) },
                            trailingIcon = { Icon(Icons.Default.Close, null, Modifier.size(16.dp)) }
                        )
                    }
                }
            }
            Column {
                OutlinedTextField(s.customerSearchQuery, vm::onCustomerSearchQuery, label = { Text("搜索客户") }, modifier = Modifier.fillMaxWidth(), singleLine = true, leadingIcon = { Icon(Icons.Default.Search, null) })
                if (s.isSearchingCustomers) LinearProgressIndicator(Modifier.fillMaxWidth().padding(vertical = 4.dp))
                s.customerSearchResults.take(5).forEach { c ->
                    Surface(Modifier.fillMaxWidth().clickable { vm.addCustomer(c) }, color = Color(0xFFF5F5F5)) {
                        Row(Modifier.padding(12.dp), verticalAlignment = Alignment.CenterVertically) {
                            Icon(Icons.Default.Person, null, Modifier.size(20.dp), tint = Color(0xFF667EEA))
                            Spacer(Modifier.width(8.dp))
                            Column(Modifier.weight(1f)) {
                                Text(c.name ?: "", fontSize = 14.sp)
                                c.phone?.let { Text(it, fontSize = 12.sp, color = Color.Gray) }
                            }
                            Icon(Icons.Default.Add, null, Modifier.size(18.dp), tint = Color(0xFF4CAF50))
                        }
                    }
                }
            }

            // ── 图片 ──
            Text("照片", fontWeight = FontWeight.Bold, fontSize = 15.sp)
            FlowRow(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
                s.photos.forEach { photo ->
                    Box(Modifier.size(80.dp).clip(RoundedCornerShape(8.dp))) {
                        AsyncImage(model = photo.uri, contentDescription = null, modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Crop)
                        if (photo.isUploading) Box(Modifier.fillMaxSize().background(Color.Black.copy(alpha = 0.4f)), contentAlignment = Alignment.Center) { CircularProgressIndicator(Modifier.size(20.dp), color = Color.White, strokeWidth = 2.dp) }
                        IconButton(onClick = { vm.removePhoto(photo.uri) }, modifier = Modifier.align(Alignment.TopEnd).size(20.dp)) { Icon(Icons.Default.Close, null, Modifier.size(14.dp), tint = Color.White) }
                    }
                }
                IconButton(onClick = { showPhotoDialog = true }, modifier = Modifier.size(80.dp).clip(RoundedCornerShape(8.dp)).background(Color(0xFFF0F0F0))) { Icon(Icons.Default.Add, null, Modifier.size(32.dp), tint = Color.Gray) }
            }

            s.errorMessage?.let { Text(it, color = Color.Red, fontSize = 14.sp) }
            Button(
                onClick = { vm.submit() }, modifier = Modifier.fillMaxWidth().height(48.dp),
                enabled = !s.isSubmitting && s.photos.none { it.isUploading }
            ) {
                if (s.isSubmitting) CircularProgressIndicator(Modifier.size(20.dp), color = Color.White, strokeWidth = 2.dp)
                else Text("提交")
            }
        }
    }

    if (showPhotoDialog) {
        AlertDialog(
            onDismissRequest = { showPhotoDialog = false },
            title = { Text("添加照片") },
            text = {
                Column {
                    TextButton(onClick = {
                        showPhotoDialog = false
                        val file = createTempImageFile(context)
                        val uri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
                        cameraFileUri = uri
                        cameraLauncher.launch(uri)
                    }, modifier = Modifier.fillMaxWidth()) {
                        Icon(Icons.Default.CameraAlt, null, Modifier.size(24.dp))
                        Spacer(Modifier.width(12.dp))
                        Text("拍照", modifier = Modifier.weight(1f))
                    }
                    TextButton(onClick = {
                        showPhotoDialog = false
                        galleryLauncher.launch("image/*")
                    }, modifier = Modifier.fillMaxWidth()) {
                        Icon(Icons.Default.PhotoLibrary, null, Modifier.size(24.dp))
                        Spacer(Modifier.width(12.dp))
                        Text("从相册选择", modifier = Modifier.weight(1f))
                    }
                }
            },
            confirmButton = {}
        )
    }
}
