Загрузка данных


package com.example.promsnab

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.AssistChip
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Checkbox
import androidx.compose.material3.DividerDefaults
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ElevatedButton
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FilterChip
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Surface
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRow
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
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.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.promsnab.ui.theme.PromSnabTheme
import kotlinx.coroutines.launch
import kotlin.math.max


private enum class Role(val label: String) {
    Storekeeper("Кладовщик"),
    Manager("Менеджер"),
    Administrator("Администратор");

    val canManageProducts: Boolean get() = this == Manager || this == Administrator
    val canDeleteProducts: Boolean get() = this == Administrator
    val canCreateDocuments: Boolean get() = this == Manager || this == Administrator
    val canOperateWarehouse: Boolean get() = this == Storekeeper || this == Administrator
    val canConfirmDocuments: Boolean get() = this == Manager || this == Administrator
    val canSeeAnalytics: Boolean get() = this == Manager || this == Administrator
}

private enum class MainScreen(val label: String, val icon: String) {
    Home("Главная", "⌂"),
    Products("Товары", "▦"),
    Supplies("Приемка", "+"),
    Shipments("Отгрузки", "→"),
    Inventory("Инвент.", "✓"),
    Profile("Профиль", "●")
}

private data class User(
    val id: Int,
    val fullName: String,
    val login: String,
    val password: String,
    val email: String,
    val role: Role
)

private data class Product(
    val id: Int,
    val sku: String,
    val name: String,
    val category: String,
    val supplier: String,
    val unit: String,
    val minStock: Int,
    val currentStock: Int,
    val purchasePrice: Double,
    val sellingPrice: Double,
    val location: String
) {
    val isLowStock: Boolean get() = currentStock <= minStock
}

private data class SupplyItem(
    val productId: Int,
    val plannedQuantity: Int,
    val actualQuantity: Int?,
    val accepted: Boolean
)

private data class Supply(
    val id: Int,
    val documentNumber: String,
    val supplier: String,
    val status: String,
    val notes: String,
    val items: List<SupplyItem>
)

private data class OrderItem(
    val productId: Int,
    val orderedQuantity: Int,
    val pickedQuantity: Int,
    val status: String
)

private data class WarehouseOrder(
    val id: Int,
    val number: String,
    val customerName: String,
    val plannedDate: String,
    val status: String,
    val warehouse: String,
    val assignedTo: Int?,
    val waybillNumber: String,
    val carrier: String,
    val items: List<OrderItem>
)

private data class InventoryItem(
    val productId: Int,
    val expectedQuantity: Int,
    val actualQuantity: Int?
) {
    val difference: Int? get() = actualQuantity?.minus(expectedQuantity)
}

private data class InventorySession(
    val id: Int,
    val number: String,
    val status: String,
    val createdBy: Int,
    val items: List<InventoryItem>
)

private class PromSnabRepository {
    val users = mutableStateListOf(
        User(1, "Иванов Сергей Петрович", "sklad", "Store123", "sklad@promsnab.ru", Role.Storekeeper),
        User(2, "Петрова Анна Игоревна", "manager", "Manager123", "manager@promsnab.ru", Role.Manager),
        User(3, "Сидоров Павел Андреевич", "admin", "Admin1234", "admin@promsnab.ru", Role.Administrator)
    )

    val products = mutableStateListOf(
        Product(1, "BRG-204", "Подшипник 204", "Комплектующие", "ООО МеталлКомплект", "шт", 30, 18, 140.0, 210.0, "A-01-03"),
        Product(2, "BLT-M8", "Болт М8 оцинкованный", "Крепеж", "СнабТрейд", "шт", 500, 1240, 3.2, 5.1, "B-03-11"),
        Product(3, "OIL-10W40", "Масло техническое 10W-40", "Расходники", "ТехноХим", "л", 80, 54, 260.0, 390.0, "C-02-02"),
        Product(4, "GLV-NIT", "Перчатки нитриловые", "Средства защиты", "ПромБезопасность", "уп", 25, 9, 410.0, 590.0, "D-01-08"),
        Product(5, "FLT-AIR", "Фильтр воздушный промышленный", "Комплектующие", "ООО МеталлКомплект", "шт", 15, 42, 980.0, 1450.0, "A-04-01")
    )

    val supplies = mutableStateListOf(
        Supply(
            id = 1,
            documentNumber = "SUP-2026-014",
            supplier = "ООО МеталлКомплект",
            status = "Ожидается",
            notes = "Плановая поставка комплектующих",
            items = listOf(SupplyItem(1, 60, null, false), SupplyItem(5, 20, null, false))
        ),
        Supply(
            id = 2,
            documentNumber = "SUP-2026-011",
            supplier = "СнабТрейд",
            status = "Завершена",
            notes = "Принято без расхождений",
            items = listOf(SupplyItem(2, 900, 900, true))
        )
    )

    val orders = mutableStateListOf(
        WarehouseOrder(
            id = 1,
            number = "ORD-2026-031",
            customerName = "АО СеверСтрой",
            plannedDate = "27.05.2026",
            status = "В сборке",
            warehouse = "Основной склад",
            assignedTo = 1,
            waybillNumber = "",
            carrier = "",
            items = listOf(OrderItem(2, 300, 120, "pending"), OrderItem(4, 8, 0, "pending"))
        ),
        WarehouseOrder(
            id = 2,
            number = "ORD-2026-026",
            customerName = "ООО ТехМонтаж",
            plannedDate = "25.05.2026",
            status = "Готов",
            warehouse = "Основной склад",
            assignedTo = 1,
            waybillNumber = "",
            carrier = "",
            items = listOf(OrderItem(1, 12, 12, "picked"))
        )
    )

    val inventories = mutableStateListOf(
        InventorySession(
            id = 1,
            number = "INV-20260520-001",
            status = "completed",
            createdBy = 1,
            items = listOf(InventoryItem(1, 20, 18), InventoryItem(4, 11, 9))
        )
    )

    fun productName(productId: Int): String = products.firstOrNull { it.id == productId }?.name ?: "Товар #$productId"
    fun productLocation(productId: Int): String = products.firstOrNull { it.id == productId }?.location ?: "-"
    fun warehouseUsers(): List<User> = users.filter { it.role == Role.Storekeeper || it.role == Role.Administrator }

    fun addUser(fullName: String, login: String, password: String, email: String, role: Role): User {
        val user = User((users.maxOfOrNull { it.id } ?: 0) + 1, fullName, login, password, email, role)
        users.add(user)
        return user
    }

    fun upsertProduct(product: Product) {
        val index = products.indexOfFirst { it.id == product.id }
        if (index >= 0) products[index] = product else products.add(product.copy(id = (products.maxOfOrNull { it.id } ?: 0) + 1))
    }

    fun removeProduct(product: Product) {
        products.remove(product)
    }

    fun createSupply(documentNumber: String, supplier: String, productId: Int, quantity: Int) {
        supplies.add(
            Supply(
                id = (supplies.maxOfOrNull { it.id } ?: 0) + 1,
                documentNumber = documentNumber,
                supplier = supplier,
                status = "Ожидается",
                notes = "Создано в мобильном приложении",
                items = listOf(SupplyItem(productId, max(1, quantity), null, false))
            )
        )
    }

    fun acceptSupplyItem(supply: Supply, item: SupplyItem, actual: Int) {
        val newItems = supply.items.map {
            if (it.productId == item.productId) it.copy(actualQuantity = max(0, actual), accepted = true) else it
        }
        updateSupply(supply.copy(status = "В процессе приемки", items = newItems))
    }

    fun finishSupply(supply: Supply) {
        if (supply.items.any { !it.accepted || it.actualQuantity == null }) return
        val hasDiscrepancy = supply.items.any { it.actualQuantity != it.plannedQuantity }
        supply.items.forEach { item ->
            val productIndex = products.indexOfFirst { it.id == item.productId }
            if (productIndex >= 0) {
                val product = products[productIndex]
                products[productIndex] = product.copy(currentStock = product.currentStock + (item.actualQuantity ?: 0))
            }
        }
        updateSupply(supply.copy(status = if (hasDiscrepancy) "Расхождение" else "Завершена"))
    }

    fun createOrder(customer: String, productId: Int, quantity: Int, assignedTo: Int?) {
        orders.add(
            WarehouseOrder(
                id = (orders.maxOfOrNull { it.id } ?: 0) + 1,
                number = "ORD-2026-${(orders.size + 32).toString().padStart(3, '0')}",
                customerName = customer,
                plannedDate = "30.05.2026",
                status = "В сборке",
                warehouse = "Основной склад",
                assignedTo = assignedTo,
                waybillNumber = "",
                carrier = "",
                items = listOf(OrderItem(productId, max(1, quantity), 0, "pending"))
            )
        )
    }

    fun pickOrderItem(order: WarehouseOrder, item: OrderItem, picked: Int): String? {
        val product = products.firstOrNull { it.id == item.productId } ?: return "Товар не найден"
        if (picked > product.currentStock) return "Недостаточно остатка: доступно ${product.currentStock} ${product.unit}"
        val newItems = order.items.map {
            if (it.productId == item.productId) {
                it.copy(pickedQuantity = picked, status = if (picked >= it.orderedQuantity) "picked" else "shortage")
            } else {
                it
            }
        }
        val newStatus = if (newItems.all { it.pickedQuantity >= it.orderedQuantity }) "Готов" else "В сборке"
        updateOrder(order.copy(status = newStatus, items = newItems))
        return null
    }

    fun confirmOrder(order: WarehouseOrder, waybill: String, carrier: String) {
        order.items.forEach { item ->
            val productIndex = products.indexOfFirst { it.id == item.productId }
            if (productIndex >= 0) {
                val product = products[productIndex]
                products[productIndex] = product.copy(currentStock = max(0, product.currentStock - item.pickedQuantity))
            }
        }
        updateOrder(order.copy(status = "Отгружен", waybillNumber = waybill, carrier = carrier))
    }

    fun startInventory(user: User) {
        if (inventories.any { it.status == "active" }) return
        inventories.add(
            InventorySession(
                id = (inventories.maxOfOrNull { it.id } ?: 0) + 1,
                number = "INV-20260525-${(inventories.size + 1).toString().padStart(3, '0')}",
                status = "active",
                createdBy = user.id,
                items = products.map { InventoryItem(it.id, it.currentStock, null) }
            )
        )
    }

    fun countInventoryItem(session: InventorySession, item: InventoryItem, actual: Int) {
        updateInventory(
            session.copy(
                items = session.items.map {
                    if (it.productId == item.productId) it.copy(actualQuantity = max(0, actual)) else it
                }
            )
        )
    }

    fun finishInventory(session: InventorySession, applyCorrections: Boolean) {
        if (session.items.any { it.actualQuantity == null }) return
        if (applyCorrections) {
            session.items.forEach { item ->
                val index = products.indexOfFirst { it.id == item.productId }
                if (index >= 0) products[index] = products[index].copy(currentStock = item.actualQuantity ?: products[index].currentStock)
            }
        }
        updateInventory(session.copy(status = "completed"))
    }

    private fun updateSupply(supply: Supply) {
        val index = supplies.indexOfFirst { it.id == supply.id }
        if (index >= 0) supplies[index] = supply
    }

    private fun updateOrder(order: WarehouseOrder) {
        val index = orders.indexOfFirst { it.id == order.id }
        if (index >= 0) orders[index] = order
    }

    private fun updateInventory(session: InventorySession) {
        val index = inventories.indexOfFirst { it.id == session.id }
        if (index >= 0) inventories[index] = session
    }
}

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            PromSnabTheme {
                PromSnabApp()
            }
        }
    }
}

@Composable
private fun PromSnabApp() {
    val repository = remember { PromSnabRepository() }
    var currentUser by remember { mutableStateOf<User?>(null) }
    var showRegistration by remember { mutableStateOf(false) }
    var loginPrefill by remember { mutableStateOf("") }
    val snackbarHostState = remember { SnackbarHostState() }
    val scope = rememberCoroutineScope()

    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colorScheme.background
    ) {
        if (currentUser == null) {
            if (showRegistration) {
                RegistrationScreen(
                    repository = repository,
                    onCancel = { showRegistration = false },
                    onRegistered = {
                        loginPrefill = it
                        showRegistration = false
                        scope.launch { snackbarHostState.showSnackbar("Пользователь зарегистрирован") }
                    },
                    snackbarHostState = snackbarHostState
                )
            } else {
                LoginScreen(
                    repository = repository,
                    loginPrefill = loginPrefill,
                    snackbarHostState = snackbarHostState,
                    onRegister = { showRegistration = true },
                    onLogin = { currentUser = it }
                )
            }
        } else {
            MainWorkspace(
                user = currentUser!!,
                repository = repository,
                snackbarHostState = snackbarHostState,
                onLogout = { currentUser = null }
            )
        }
    }
}

@Composable
private fun AuthCard(content: @Composable () -> Unit) {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(MaterialTheme.colorScheme.background)
            .padding(20.dp),
        contentAlignment = Alignment.Center
    ) {
        ElevatedCard(
            modifier = Modifier.fillMaxWidth(),
            shape = RoundedCornerShape(8.dp),
            colors = CardDefaults.elevatedCardColors(containerColor = MaterialTheme.colorScheme.surface)
        ) {
            Column(
                modifier = Modifier.padding(20.dp),
                verticalArrangement = Arrangement.spacedBy(12.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                LogoHeader()
                content()
            }
        }
    }
}

@Composable
private fun LogoHeader() {
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Box(
            modifier = Modifier
                .size(58.dp)
                .clip(CircleShape)
                .background(MaterialTheme.colorScheme.primary),
            contentAlignment = Alignment.Center
        ) {
            Text("ПС", color = Color.White, fontWeight = FontWeight.Bold, fontSize = 20.sp)
        }
        Spacer(Modifier.height(8.dp))
        Text("ПромСнаб", style = MaterialTheme.typography.headlineSmall, fontWeight = FontWeight.Bold)
        Text("Мобильное управление складом", color = MaterialTheme.colorScheme.onSurfaceVariant)
    }
}

@Composable
private fun LoginScreen(
    repository: PromSnabRepository,
    loginPrefill: String,
    snackbarHostState: SnackbarHostState,
    onRegister: () -> Unit,
    onLogin: (User) -> Unit
) {
    var login by remember(loginPrefill) { mutableStateOf(loginPrefill) }
    var password by remember { mutableStateOf("") }
    var rememberMe by remember { mutableStateOf(false) }
    var showPassword by remember { mutableStateOf(false) }
    var showRecoveryDialog by remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope()

    Scaffold(snackbarHost = { SnackbarHost(snackbarHostState) }) { padding ->
        Box(Modifier.padding(padding)) {
            AuthCard {
                Text("Вход в систему", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.SemiBold)
                OutlinedTextField(login, { login = it }, modifier = Modifier.fillMaxWidth(), label = { Text("Логин") }, leadingIcon = { Text("@") }, singleLine = true)
                OutlinedTextField(
                    value = password,
                    onValueChange = { password = it },
                    modifier = Modifier.fillMaxWidth(),
                    label = { Text("Пароль") },
                    leadingIcon = { Text("*") },
                    trailingIcon = { TextButton(onClick = { showPassword = !showPassword }) { Text(if (showPassword) "Скрыть" else "Показать") } },
                    visualTransformation = if (showPassword) VisualTransformation.None else PasswordVisualTransformation(),
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
                    singleLine = true
                )
                Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
                    Checkbox(rememberMe, { rememberMe = it })
                    Text("Запомнить меня")
                    Spacer(Modifier.weight(1f))
                    TextButton(onClick = { showRecoveryDialog = true }) { Text("Забыли пароль?") }
                }
                Button(
                    modifier = Modifier.fillMaxWidth(),
                    onClick = {
                        val user = repository.users.firstOrNull { it.login == login.trim() && it.password == password }
                        if (user == null) {
                            scope.launch { snackbarHostState.showSnackbar("Проверьте логин и пароль") }
                        } else {
                            onLogin(user)
                        }
                    },
                    enabled = login.isNotBlank() && password.isNotBlank()
                ) {
                    Text("Войти")
                }
                OutlinedButton(modifier = Modifier.fillMaxWidth(), onClick = onRegister) {
                    Text("Регистрация")
                }
                DemoAccounts()
            }
        }
    }

    if (showRecoveryDialog) {
        PasswordRecoveryDialog(
            onDismiss = { showRecoveryDialog = false },
            onSent = {
                showRecoveryDialog = false
                scope.launch { snackbarHostState.showSnackbar("Инструкция отправлена на email") }
            }
        )
    }
}

@Composable
private fun DemoAccounts() {
    Column(Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(4.dp)) {
        HorizontalDivider()
        Text("Тестовые входы", style = MaterialTheme.typography.labelLarge, color = MaterialTheme.colorScheme.onSurfaceVariant)
        Text("sklad / Store123", style = MaterialTheme.typography.bodySmall)
        Text("manager / Manager123", style = MaterialTheme.typography.bodySmall)
        Text("admin / Admin1234", style = MaterialTheme.typography.bodySmall)
    }
}

@Composable
private fun PasswordRecoveryDialog(onDismiss: () -> Unit, onSent: () -> Unit) {
    var email by remember { mutableStateOf("") }
    AlertDialog(
        onDismissRequest = onDismiss,
        title = { Text("Восстановление пароля") },
        text = {
            OutlinedTextField(
                value = email,
                onValueChange = { email = it },
                label = { Text("Email") },
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email),
                singleLine = true
            )
        },
        confirmButton = { Button(onClick = onSent, enabled = email.isNotBlank()) { Text("Отправить") } },
        dismissButton = { TextButton(onClick = onDismiss) { Text("Отмена") } }
    )
}

@Composable
private fun RegistrationScreen(
    repository: PromSnabRepository,
    onCancel: () -> Unit,
    onRegistered: (String) -> Unit,
    snackbarHostState: SnackbarHostState
) {
    var fullName by remember { mutableStateOf("") }
    var login by remember { mutableStateOf("") }
    var password by remember { mutableStateOf("") }
    var confirmPassword by remember { mutableStateOf("") }
    var email by remember { mutableStateOf("") }
    var role by remember { mutableStateOf(Role.Storekeeper) }
    var showPassword by remember { mutableStateOf(false) }
    var showConfirm by remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope()

    Scaffold(snackbarHost = { SnackbarHost(snackbarHostState) }) { padding ->
        Box(Modifier.padding(padding)) {
            AuthCard {
                Text("Регистрация нового пользователя", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.SemiBold)
                Column(
                    Modifier
                        .fillMaxWidth()
                        .verticalScroll(rememberScrollState()),
                    verticalArrangement = Arrangement.spacedBy(10.dp)
                ) {
                    OutlinedTextField(fullName, { fullName = it }, Modifier.fillMaxWidth(), label = { Text("ФИО") }, singleLine = true)
                    OutlinedTextField(login, { login = it }, Modifier.fillMaxWidth(), label = { Text("Логин") }, singleLine = true)
                    OutlinedTextField(
                        password,
                        { password = it },
                        Modifier.fillMaxWidth(),
                        label = { Text("Пароль") },
                        leadingIcon = { Text("*") },
                        trailingIcon = { TextButton(onClick = { showPassword = !showPassword }) { Text(if (showPassword) "Скрыть" else "Показать") } },
                        visualTransformation = if (showPassword) VisualTransformation.None else PasswordVisualTransformation(),
                        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
                        singleLine = true
                    )
                    OutlinedTextField(
                        confirmPassword,
                        { confirmPassword = it },
                        Modifier.fillMaxWidth(),
                        label = { Text("Подтверждение пароля") },
                        leadingIcon = { Text("*") },
                        trailingIcon = { TextButton(onClick = { showConfirm = !showConfirm }) { Text(if (showConfirm) "Скрыть" else "Показать") } },
                        visualTransformation = if (showConfirm) VisualTransformation.None else PasswordVisualTransformation(),
                        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
                        singleLine = true
                    )
                    OutlinedTextField(email, { email = it }, Modifier.fillMaxWidth(), label = { Text("Email") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email), singleLine = true)
                    RoleSelector(role = role, enabled = true, onRoleSelected = { role = it })
                    Button(
                        modifier = Modifier.fillMaxWidth(),
                        onClick = {
                            val error = validateRegistration(repository, fullName, login, password, confirmPassword, email)
                            if (error != null) {
                                scope.launch { snackbarHostState.showSnackbar(error) }
                            } else {
                                repository.addUser(fullName.trim(), login.trim(), password, email.trim(), role)
                                onRegistered(login.trim())
                            }
                        }
                    ) {
                        Text("Зарегистрироваться")
                    }
                    OutlinedButton(modifier = Modifier.fillMaxWidth(), onClick = onCancel) { Text("Отмена") }
                }
            }
        }
    }
}

private fun validateRegistration(
    repository: PromSnabRepository,
    fullName: String,
    login: String,
    password: String,
    confirmPassword: String,
    email: String
): String? {
    val emailValid = Regex("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$").matches(email.trim())
    val passwordStrong = password.length >= 8 && password.any { it.isDigit() } && password.any { it.isLetter() }
    return when {
        fullName.isBlank() -> "Укажите ФИО"
        login.isBlank() -> "Укажите логин"
        repository.users.any { it.login == login.trim() } -> "Такой логин уже занят"
        !passwordStrong -> "Пароль должен быть не короче 8 символов и содержать буквы и цифры"
        password != confirmPassword -> "Пароли не совпадают"
        !emailValid -> "Проверьте формат email"
        else -> null
    }
}

@Composable
private fun RoleSelector(role: Role, enabled: Boolean, onRoleSelected: (Role) -> Unit) {
    var expanded by remember { mutableStateOf(false) }
    Box {
        OutlinedButton(onClick = { if (enabled) expanded = true }, enabled = enabled, modifier = Modifier.fillMaxWidth()) {
            Text("Должность: ${role.label}")
        }
        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
            Role.values().forEach {
                DropdownMenuItem(text = { Text(it.label) }, onClick = {
                    onRoleSelected(it)
                    expanded = false
                })
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun MainWorkspace(
    user: User,
    repository: PromSnabRepository,
    snackbarHostState: SnackbarHostState,
    onLogout: () -> Unit
) {
    var selectedScreen by remember(user) { mutableStateOf(MainScreen.Home) }
    val availableScreens = remember(user.role) { MainScreen.entries }
    Scaffold(
        snackbarHost = { SnackbarHost(snackbarHostState) },
        topBar = {
            TopAppBar(
                colors = TopAppBarDefaults.topAppBarColors(
                    containerColor = MaterialTheme.colorScheme.primary,
                    titleContentColor = Color.White,
                    actionIconContentColor = Color.White
                ),
                title = {
                    Row(verticalAlignment = Alignment.CenterVertically) {
                        Box(
                            modifier = Modifier
                                .size(36.dp)
                                .clip(CircleShape)
                                .background(Color.White.copy(alpha = 0.16f)),
                            contentAlignment = Alignment.Center
                        ) {
                            Text("ПС", color = Color.White, fontWeight = FontWeight.Bold)
                        }
                        Spacer(Modifier.width(10.dp))
                        Column {
                            Text("ПромСнаб", fontWeight = FontWeight.Bold)
                            Text("${user.fullName} · ${user.role.label}", fontSize = 12.sp, color = Color.White.copy(alpha = 0.86f))
                        }
                    }
                },
                actions = {
                    TextButton(onClick = onLogout) { Text("Выход", color = Color.White) }
                }
            )
        },
        bottomBar = {
            NavigationBar {
                availableScreens.forEach { screen ->
                    NavigationBarItem(
                        selected = selectedScreen == screen,
                        onClick = { selectedScreen = screen },
                        icon = { Text(screen.icon, fontWeight = FontWeight.Bold) },
                        label = {
                            Text(
                                text = screen.label,
                                maxLines = 1,
                                softWrap = false,
                                overflow = TextOverflow.Clip,
                                fontSize = 10.sp
                            )
                        }
                    )
                }
            }
        }
    ) { padding ->
        Box(
            modifier = Modifier
                .padding(padding)
                .fillMaxSize()
        ) {
            when (selectedScreen) {
                MainScreen.Home -> HomeScreen(user, repository)
                MainScreen.Products -> ProductsScreen(user, repository, snackbarHostState)
                MainScreen.Supplies -> SuppliesScreen(user, repository, snackbarHostState)
                MainScreen.Shipments -> ShipmentsScreen(user, repository, snackbarHostState)
                MainScreen.Inventory -> InventoryScreen(user, repository, snackbarHostState)
                MainScreen.Profile -> ProfileScreen(user, onLogout)
            }
        }
    }
}

@Composable
fun NavigationBarItem(selected: Boolean, onClick: () -> Unit, icon: () -> Unit, label: () -> Unit) {
    TODO("Not yet implemented")
}

@Composable
fun NavigationBarItem(selected: Boolean, onClick: () -> Unit, icon: () -> Unit, label: () -> Unit) {
    TODO("Not yet implemented")
}

@Composable
private fun ScreenScaffold(title: String, content: @Composable () -> Unit) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(MaterialTheme.colorScheme.background)
            .padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        Text(title, style = MaterialTheme.typography.headlineSmall, fontWeight = FontWeight.Bold)
        content()
    }
}

@Composable
private fun HomeScreen(user: User, repository: PromSnabRepository) {
    val totalStock = repository.products.sumOf { it.currentStock }
    val stockValue = repository.products.sumOf { it.currentStock * it.purchasePrice }
    val lowStock = repository.products.filter { it.isLowStock }
    ScreenScaffold("Главная") {
        LazyColumn(verticalArrangement = Arrangement.spacedBy(12.dp)) {
            item {
                Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
                    MetricCard("Всего товаров", totalStock.toString(), Color(0xFF27AE60))
                    if (user.role.canSeeAnalytics) {
                        MetricCard("Стоимость запасов", "${stockValue.toInt()} ₽", Color(0xFF3498DB))
                    }
                    MetricCard("Низкий остаток", lowStock.size.toString(), Color(0xFFE74C3C))
                }
            }
            if (user.role.canSeeAnalytics) {
                item {
                    ElevatedCard(modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(8.dp)) {
                        Column(Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
                            Text("Движение товаров", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)
                            Text("Входящий поток: +${repository.supplies.sumOf { supply -> supply.items.sumOf { it.actualQuantity ?: 0 } }} ед.")
                            Text("Исходящий поток: -${repository.orders.sumOf { order -> order.items.sumOf { it.pickedQuantity } }} ед.")
                        }
                    }
                }
            }
            item {
                Text("Критически низкий запас", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)
            }
            items(lowStock.take(10), key = { it.id }) { product ->
                ProductCompactRow(product)
            }
        }
    }
}

@Composable
private fun MetricCard(title: String, value: String, color: Color) {
    ElevatedCard(
        modifier = Modifier.fillMaxWidth(),
        shape = RoundedCornerShape(8.dp),
        colors = CardDefaults.elevatedCardColors(containerColor = color.copy(alpha = 0.12f))
    ) {
        Row(
            Modifier
                .fillMaxWidth()
                .padding(14.dp),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(title, color = MaterialTheme.colorScheme.onSurfaceVariant, maxLines = 1, overflow = TextOverflow.Ellipsis)
            Text(value, color = color, fontWeight = FontWeight.Bold, fontSize = 24.sp, maxLines = 1)
        }
    }
}

@Composable
private fun ProductCompactRow(product: Product) {
    ElevatedCard(shape = RoundedCornerShape(8.dp)) {
        Row(
            Modifier
                .fillMaxWidth()
                .padding(14.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Column(Modifier.weight(1f)) {
                Text(product.name, fontWeight = FontWeight.SemiBold)
                Text("${product.sku} · ${product.location}", color = MaterialTheme.colorScheme.onSurfaceVariant)
            }
            Text("${product.currentStock} ${product.unit}", color = if (product.isLowStock) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary, fontWeight = FontWeight.Bold)
        }
    }
}

@Composable
private fun FilterStrip(content: @Composable RowScope.() -> Unit) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .horizontalScroll(rememberScrollState()),
        horizontalArrangement = Arrangement.spacedBy(8.dp),
        verticalAlignment = Alignment.CenterVertically,
        content = content
    )
}

@Composable
private fun FilterMenu(label: String, value: String, options: List<String>, onSelected: (String) -> Unit) {
    var expanded by remember { mutableStateOf(false) }
    Box(Modifier.fillMaxWidth()) {
        OutlinedButton(onClick = { expanded = true }, modifier = Modifier.fillMaxWidth()) {
            Text("$label: $value", maxLines = 1, overflow = TextOverflow.Ellipsis)
        }
        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
            options.forEach {
                DropdownMenuItem(
                    text = { Text(it) },
                    onClick = {
                        onSelected(it)
                        expanded = false
                    }
                )
            }
        }
    }
}

@Composable
private fun SearchFilterBar(
    query: String,
    onQueryChange: (String) -> Unit,
    placeholder: String,
    onFilterClick: () -> Unit
) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.spacedBy(8.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        OutlinedTextField(
            value = query,
            onValueChange = onQueryChange,
            modifier = Modifier.weight(1f),
            label = { Text(placeholder, maxLines = 1, overflow = TextOverflow.Ellipsis) },
            singleLine = true
        )
        OutlinedButton(
            onClick = onFilterClick,
            modifier = Modifier.width(112.dp)
        ) {
            Text("Фильтр", maxLines = 1)
        }
    }
}

@Composable
private fun FilterDialog(
    title: String,
    onDismiss: () -> Unit,
    content: @Composable () -> Unit
) {
    AlertDialog(
        onDismissRequest = onDismiss,
        title = { Text(title) },
        text = {
            Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
                content()
            }
        },
        confirmButton = {
            Button(onClick = onDismiss) {
                Text("Готово")
            }
        }
    )
}

@Composable
private fun ProductsScreen(user: User, repository: PromSnabRepository, snackbarHostState: SnackbarHostState) {
    var search by remember { mutableStateOf("") }
    var category by remember { mutableStateOf("Все категории") }
    var supplier by remember { mutableStateOf("Все поставщики") }
    var stockFilter by remember { mutableStateOf("Все остатки") }
    var showFilters by remember { mutableStateOf(false) }
    var showEditor by remember { mutableStateOf<Product?>(null) }
    var createNew by remember { mutableStateOf(false) }
    val categories = listOf("Все категории") + repository.products.map { it.category }.distinct()
    val suppliers = listOf("Все поставщики") + repository.products.map { it.supplier }.distinct()
    val stockFilters = listOf("Все остатки", "В наличии", "Низкий запас", "Нет на складе")
    val filtered = repository.products.filter {
        val matchesSearch = search.isBlank() || it.name.contains(search, true) || it.sku.contains(search, true) || it.supplier.contains(search, true)
        val matchesCategory = category == "Все категории" || it.category == category
        val matchesSupplier = supplier == "Все поставщики" || it.supplier == supplier
        val matchesStock = when (stockFilter) {
            "В наличии" -> it.currentStock > 0
            "Низкий запас" -> it.isLowStock
            "Нет на складе" -> it.currentStock == 0
            else -> true
        }
        matchesSearch && matchesCategory && matchesSupplier && matchesStock
    }
    val scope = rememberCoroutineScope()

    ScreenScaffold("Товары") {
        Box(Modifier.fillMaxSize()) {
            LazyColumn(verticalArrangement = Arrangement.spacedBy(10.dp), modifier = Modifier.fillMaxSize()) {
                item {
                    SearchFilterBar(
                        query = search,
                        onQueryChange = { search = it },
                        placeholder = "Поиск товара",
                        onFilterClick = { showFilters = true }
                    )
                }
                if (user.role.canManageProducts) {
                    item {
                        Button(modifier = Modifier.fillMaxWidth(), onClick = { createNew = true }) {
                            Text("Добавить товар")
                        }
                    }
                }
                items(filtered, key = { it.id }) { product ->
                    ProductCard(
                        user = user,
                        product = product,
                        onEdit = { showEditor = product },
                        onDelete = {
                            repository.removeProduct(product)
                            scope.launch { snackbarHostState.showSnackbar("Товар удален") }
                        }
                    )
                }
                item { Spacer(Modifier.height(80.dp)) }
            }
        }
    }

    if (showFilters) {
        FilterDialog(title = "Фильтры товаров", onDismiss = { showFilters = false }) {
            FilterMenu("Категория", category, categories) { category = it }
            FilterMenu("Поставщик", supplier, suppliers) { supplier = it }
            FilterMenu("Остаток", stockFilter, stockFilters) { stockFilter = it }
        }
    }

    if (showEditor != null || createNew) {
        ProductEditorDialog(
            initial = showEditor,
            onDismiss = {
                showEditor = null
                createNew = false
            },
            onSave = {
                repository.upsertProduct(it)
                showEditor = null
                createNew = false
                scope.launch { snackbarHostState.showSnackbar("Товар сохранен") }
            }
        )
    }
}

@Composable
private fun ProductCard(user: User, product: Product, onEdit: () -> Unit, onDelete: () -> Unit) {
    ElevatedCard(
        shape = RoundedCornerShape(8.dp),
        colors = CardDefaults.elevatedCardColors(
            containerColor = if (product.isLowStock) Color(0xFFFFEBEE) else MaterialTheme.colorScheme.surface
        )
    ) {
        Column(Modifier.padding(14.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
            Row(verticalAlignment = Alignment.CenterVertically) {
                Column(Modifier.weight(1f)) {
                    Text(product.name, style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)
                    Text("${product.sku} · ${product.category} · ${product.supplier}", color = MaterialTheme.colorScheme.onSurfaceVariant)
                }
                AssistChip(onClick = {}, label = { Text("${product.currentStock} ${product.unit}") })
            }
            Text("Цена: закупка ${product.purchasePrice} ₽, продажа ${product.sellingPrice} ₽ · Ячейка ${product.location}")
            if (user.role.canManageProducts || user.role.canDeleteProducts) {
                Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                    if (user.role.canManageProducts) OutlinedButton(onClick = onEdit) { Text("Редактировать") }
                    if (user.role.canDeleteProducts) OutlinedButton(onClick = onDelete) { Text("Удалить") }
                }
            }
        }
    }
}

@Composable
private fun ProductEditorDialog(initial: Product?, onDismiss: () -> Unit, onSave: (Product) -> Unit) {
    var sku by remember { mutableStateOf(initial?.sku ?: "") }
    var name by remember { mutableStateOf(initial?.name ?: "") }
    var category by remember { mutableStateOf(initial?.category ?: "") }
    var supplier by remember { mutableStateOf(initial?.supplier ?: "") }
    var unit by remember { mutableStateOf(initial?.unit ?: "шт") }
    var minStock by remember { mutableStateOf((initial?.minStock ?: 0).toString()) }
    var currentStock by remember { mutableStateOf((initial?.currentStock ?: 0).toString()) }
    var purchasePrice by remember { mutableStateOf((initial?.purchasePrice ?: 0.0).toString()) }
    var sellingPrice by remember { mutableStateOf((initial?.sellingPrice ?: 0.0).toString()) }
    var location by remember { mutableStateOf(initial?.location ?: "") }

    AlertDialog(
        onDismissRequest = onDismiss,
        title = { Text(if (initial == null) "Новый товар" else "Редактирование товара") },
        text = {
            Column(
                Modifier
                    .verticalScroll(rememberScrollState())
                    .fillMaxWidth(),
                verticalArrangement = Arrangement.spacedBy(8.dp)
            ) {
                OutlinedTextField(sku, { sku = it }, Modifier.fillMaxWidth(), label = { Text("Артикул") }, singleLine = true)
                OutlinedTextField(name, { name = it }, Modifier.fillMaxWidth(), label = { Text("Название") }, singleLine = true)
                OutlinedTextField(category, { category = it }, Modifier.fillMaxWidth(), label = { Text("Категория") }, singleLine = true)
                OutlinedTextField(supplier, { supplier = it }, Modifier.fillMaxWidth(), label = { Text("Поставщик") }, singleLine = true)
                OutlinedTextField(unit, { unit = it }, Modifier.fillMaxWidth(), label = { Text("Ед. изм.") }, singleLine = true)
                OutlinedTextField(minStock, { minStock = it.onlyDigits() }, Modifier.fillMaxWidth(), label = { Text("Минимальный запас") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), singleLine = true)
                OutlinedTextField(currentStock, { currentStock = it.onlyDigits() }, Modifier.fillMaxWidth(), label = { Text("Остаток") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), singleLine = true)
                OutlinedTextField(purchasePrice, { purchasePrice = it.decimalInput() }, Modifier.fillMaxWidth(), label = { Text("Цена закупки") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal), singleLine = true)
                OutlinedTextField(sellingPrice, { sellingPrice = it.decimalInput() }, Modifier.fillMaxWidth(), label = { Text("Цена продажи") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal), singleLine = true)
                OutlinedTextField(location, { location = it }, Modifier.fillMaxWidth(), label = { Text("Место хранения") }, singleLine = true)
            }
        },
        confirmButton = {
            Button(
                onClick = {
                    onSave(
                        Product(
                            id = initial?.id ?: 0,
                            sku = sku.trim(),
                            name = name.trim(),
                            category = category.trim(),
                            supplier = supplier.trim(),
                            unit = unit.trim().ifBlank { "шт" },
                            minStock = minStock.toIntOrNull() ?: 0,
                            currentStock = currentStock.toIntOrNull() ?: 0,
                            purchasePrice = purchasePrice.toDoubleOrNull() ?: 0.0,
                            sellingPrice = sellingPrice.toDoubleOrNull() ?: 0.0,
                            location = location.trim()
                        )
                    )
                },
                enabled = sku.isNotBlank() && name.isNotBlank()
            ) { Text("Сохранить") }
        },
        dismissButton = { TextButton(onClick = onDismiss) { Text("Отмена") } }
    )
}

@Composable
private fun SuppliesScreen(user: User, repository: PromSnabRepository, snackbarHostState: SnackbarHostState) {
    var tab by remember { mutableStateOf(0) }
    var search by remember { mutableStateOf("") }
    var statusFilter by remember { mutableStateOf("Все статусы") }
    var supplierFilter by remember { mutableStateOf("Все поставщики") }
    var showFilters by remember { mutableStateOf(false) }
    var showCreate by remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope()
    val tabs = listOf("Ожидаются", "История")
    val tabbedSupplies = if (tab == 0) {
        repository.supplies.filter { it.status != "Завершена" && it.status != "Расхождение" }
    } else {
        repository.supplies.filter { it.status == "Завершена" || it.status == "Расхождение" }
    }
    val statusFilters = listOf("Все статусы") + tabbedSupplies.map { it.status }.distinct()
    val supplierFilters = listOf("Все поставщики") + tabbedSupplies.map { it.supplier }.distinct()
    val filteredSupplies = tabbedSupplies.filter {
        val matchesSearch = search.isBlank() || it.documentNumber.contains(search, true) || it.supplier.contains(search, true)
        val matchesStatus = statusFilter == "Все статусы" || it.status == statusFilter
        val matchesSupplier = supplierFilter == "Все поставщики" || it.supplier == supplierFilter
        matchesSearch && matchesStatus && matchesSupplier
    }
    ScreenScaffold("Поставки / Приемка") {
        TabRow(selectedTabIndex = tab) {
            tabs.forEachIndexed { index, title ->
                Tab(
                    selected = tab == index,
                    onClick = {
                        tab = index
                        statusFilter = "Все статусы"
                        supplierFilter = "Все поставщики"
                    },
                    text = { Text(title, maxLines = 1, softWrap = false) }
                )
            }
        }
        Box(Modifier.fillMaxSize()) {
            LazyColumn(verticalArrangement = Arrangement.spacedBy(10.dp)) {
                item {
                    SearchFilterBar(
                        query = search,
                        onQueryChange = { search = it },
                        placeholder = "Поиск поставки",
                        onFilterClick = { showFilters = true }
                    )
                }
                if (user.role.canCreateDocuments) {
                    item {
                        Button(modifier = Modifier.fillMaxWidth(), onClick = { showCreate = true }) {
                            Text("Новая поставка")
                        }
                    }
                }
                items(filteredSupplies, key = { it.id }) { supply ->
                    SupplyCard(
                        user = user,
                        repository = repository,
                        supply = supply,
                        onMessage = { scope.launch { snackbarHostState.showSnackbar(it) } }
                    )
                }
                item { Spacer(Modifier.height(80.dp)) }
            }
        }
    }
    if (showFilters) {
        FilterDialog(title = "Фильтры поставок", onDismiss = { showFilters = false }) {
            FilterMenu("Статус", statusFilter, statusFilters) { statusFilter = it }
            FilterMenu("Поставщик", supplierFilter, supplierFilters) { supplierFilter = it }
        }
    }
    if (showCreate) {
        CreateSupplyDialog(repository, onDismiss = { showCreate = false }, onCreate = {
            showCreate = false
            scope.launch { snackbarHostState.showSnackbar("Поставка создана") }
        })
    }
}

@Composable
private fun SupplyCard(user: User, repository: PromSnabRepository, supply: Supply, onMessage: (String) -> Unit) {
    ElevatedCard(shape = RoundedCornerShape(8.dp)) {
        Column(Modifier.padding(14.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) {
            Row(verticalAlignment = Alignment.CenterVertically) {
                Column(Modifier.weight(1f)) {
                    Text(supply.documentNumber, fontWeight = FontWeight.SemiBold, style = MaterialTheme.typography.titleMedium)
                    Text("${supply.supplier} · ${supply.status}", color = MaterialTheme.colorScheme.onSurfaceVariant)
                }
                StatusChip(supply.status)
            }
            Text(supply.notes)
            supply.items.forEach { item ->
                var actual by remember(supply.id, item.productId, item.actualQuantity) { mutableStateOf((item.actualQuantity ?: item.plannedQuantity).toString()) }
                HorizontalDivider(color = DividerDefaults.color.copy(alpha = 0.6f))
                Text(repository.productName(item.productId), fontWeight = FontWeight.SemiBold)
                Text("План: ${item.plannedQuantity} · Факт: ${item.actualQuantity ?: "-"}")
                if (user.role.canOperateWarehouse && supply.status != "Завершена" && supply.status != "Расхождение") {
                    Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
                        OutlinedTextField(
                            value = actual,
                            onValueChange = { actual = it.onlyDigits() },
                            modifier = Modifier.weight(1f),
                            label = { Text("Принято фактически") },
                            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                            singleLine = true
                        )
                        Button(onClick = {
                            repository.acceptSupplyItem(supply, item, actual.toIntOrNull() ?: 0)
                            onMessage("Позиция подтверждена")
                        }) { Text("Подтвердить") }
                    }
                }
            }
            if (user.role.canOperateWarehouse && supply.status != "Завершена" && supply.items.all { it.accepted }) {
                Button(onClick = {
                    repository.finishSupply(supply)
                    onMessage("Приемка завершена")
                }) { Text("Завершить приемку") }
            }
            if (user.role.canConfirmDocuments && supply.status == "Расхождение") {
                OutlinedButton(onClick = { onMessage("Акт расхождений подготовлен") }) { Text("Акт расхождений") }
            }
        }
    }
}

@Composable
private fun CreateSupplyDialog(repository: PromSnabRepository, onDismiss: () -> Unit, onCreate: () -> Unit) {
    var documentNumber by remember { mutableStateOf("") }
    var supplier by remember { mutableStateOf("") }
    var productId by remember { mutableStateOf(repository.products.firstOrNull()?.id ?: 0) }
    var quantity by remember { mutableStateOf("1") }
    AlertDialog(
        onDismissRequest = onDismiss,
        title = { Text("Новая поставка") },
        text = {
            Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
                OutlinedTextField(documentNumber, { documentNumber = it }, Modifier.fillMaxWidth(), label = { Text("Номер документа") }, singleLine = true)
                OutlinedTextField(supplier, { supplier = it }, Modifier.fillMaxWidth(), label = { Text("Поставщик") }, singleLine = true)
                ProductSelector(repository, productId) { productId = it }
                OutlinedTextField(quantity, { quantity = it.onlyDigits() }, Modifier.fillMaxWidth(), label = { Text("Количество по плану") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), singleLine = true)
            }
        },
        confirmButton = {
            Button(
                onClick = {
                    repository.createSupply(documentNumber, supplier, productId, quantity.toIntOrNull() ?: 1)
                    onCreate()
                },
                enabled = documentNumber.isNotBlank() && supplier.isNotBlank() && productId != 0
            ) { Text("Создать") }
        },
        dismissButton = { TextButton(onClick = onDismiss) { Text("Отмена") } }
    )
}

@Composable
private fun ShipmentsScreen(user: User, repository: PromSnabRepository, snackbarHostState: SnackbarHostState) {
    var tab by remember { mutableStateOf(0) }
    var search by remember { mutableStateOf("") }
    var statusFilter by remember { mutableStateOf("Все статусы") }
    var warehouseFilter by remember { mutableStateOf("Все склады") }
    var showFilters by remember { mutableStateOf(false) }
    var showCreate by remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope()
    val tabs = listOf("В сборке", "Готово", "История")
    val tabbedOrders = when (tab) {
        0 -> repository.orders.filter { it.status == "В сборке" }
        1 -> repository.orders.filter { it.status == "Готов" }
        else -> repository.orders.filter { it.status == "Отгружен" || it.status == "Отменен" }
    }.filter { user.role != Role.Storekeeper || it.assignedTo == user.id }
    val statusFilters = listOf("Все статусы") + tabbedOrders.map { it.status }.distinct()
    val warehouseFilters = listOf("Все склады") + tabbedOrders.map { it.warehouse }.distinct()
    val filteredOrders = tabbedOrders.filter {
        val matchesSearch = search.isBlank() || it.number.contains(search, true) || it.customerName.contains(search, true)
        val matchesStatus = statusFilter == "Все статусы" || it.status == statusFilter
        val matchesWarehouse = warehouseFilter == "Все склады" || it.warehouse == warehouseFilter
        matchesSearch && matchesStatus && matchesWarehouse
    }
    ScreenScaffold("Отгрузки") {
        TabRow(selectedTabIndex = tab) {
            tabs.forEachIndexed { index, title ->
                Tab(
                    selected = tab == index,
                    onClick = {
                        tab = index
                        statusFilter = "Все статусы"
                        warehouseFilter = "Все склады"
                    },
                    text = { Text(title, maxLines = 1, softWrap = false) }
                )
            }
        }
        Box(Modifier.fillMaxSize()) {
            LazyColumn(verticalArrangement = Arrangement.spacedBy(10.dp)) {
                item {
                    SearchFilterBar(
                        query = search,
                        onQueryChange = { search = it },
                        placeholder = "Поиск отгрузки",
                        onFilterClick = { showFilters = true }
                    )
                }
                if (user.role.canCreateDocuments) {
                    item {
                        Button(modifier = Modifier.fillMaxWidth(), onClick = { showCreate = true }) {
                            Text("Новая отгрузка")
                        }
                    }
                }
                items(filteredOrders, key = { it.id }) { order ->
                    OrderCard(user, repository, order) { scope.launch { snackbarHostState.showSnackbar(it) } }
                }
                item { Spacer(Modifier.height(80.dp)) }
            }
        }
    }
    if (showFilters) {
        FilterDialog(title = "Фильтры отгрузок", onDismiss = { showFilters = false }) {
            FilterMenu("Статус", statusFilter, statusFilters) { statusFilter = it }
            FilterMenu("Склад", warehouseFilter, warehouseFilters) { warehouseFilter = it }
        }
    }
    if (showCreate) {
        CreateOrderDialog(repository, onDismiss = { showCreate = false }, onCreate = {
            showCreate = false
            scope.launch { snackbarHostState.showSnackbar("Отгрузка создана") }
        })
    }
}

@Composable
private fun OrderCard(user: User, repository: PromSnabRepository, order: WarehouseOrder, onMessage: (String) -> Unit) {
    var waybill by remember(order.id, order.waybillNumber) { mutableStateOf(order.waybillNumber) }
    var carrier by remember(order.id, order.carrier) { mutableStateOf(order.carrier) }
    ElevatedCard(shape = RoundedCornerShape(8.dp)) {
        Column(Modifier.padding(14.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) {
            Row(verticalAlignment = Alignment.CenterVertically) {
                Column(Modifier.weight(1f)) {
                    Text(order.number, fontWeight = FontWeight.SemiBold, style = MaterialTheme.typography.titleMedium)
                    Text("${order.customerName} · ${order.plannedDate} · ${order.warehouse}", color = MaterialTheme.colorScheme.onSurfaceVariant)
                }
                StatusChip(order.status)
            }
            val picked = order.items.count { it.pickedQuantity >= it.orderedQuantity }
            Text("Прогресс сборки: $picked / ${order.items.size}")
            order.items.forEach { item ->
                var pickedQuantity by remember(order.id, item.productId, item.pickedQuantity) { mutableStateOf(item.pickedQuantity.toString()) }
                HorizontalDivider()
                Text(repository.productName(item.productId), fontWeight = FontWeight.SemiBold)
                Text("Ячейка: ${repository.productLocation(item.productId)} · Требуется: ${item.orderedQuantity} · Собрано: ${item.pickedQuantity}")
                if (user.role.canOperateWarehouse && order.status == "В сборке") {
                    Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
                        OutlinedTextField(pickedQuantity, { pickedQuantity = it.onlyDigits() }, Modifier.weight(1f), label = { Text("Собрано фактически") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), singleLine = true)
                        Button(onClick = {
                            val error = repository.pickOrderItem(order, item, pickedQuantity.toIntOrNull() ?: 0)
                            onMessage(error ?: "Позиция сборки обновлена")
                        }) { Text("Подтвердить") }
                    }
                    if (item.status == "shortage") {
                        OutlinedButton(onClick = { onMessage("Недостача отправлена менеджеру") }) { Text("Сообщить о недостаче") }
                    }
                }
            }
            if (user.role.canConfirmDocuments && order.status == "Готов") {
                OutlinedTextField(waybill, { waybill = it }, Modifier.fillMaxWidth(), label = { Text("Номер транспортной накладной") }, singleLine = true)
                OutlinedTextField(carrier, { carrier = it }, Modifier.fillMaxWidth(), label = { Text("Перевозчик") }, singleLine = true)
                Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                    Button(onClick = {
                        repository.confirmOrder(order, waybill, carrier)
                        onMessage("Отгрузка подтверждена, остатки списаны")
                    }, enabled = waybill.isNotBlank()) { Text("Подтвердить отгрузку") }
                    OutlinedButton(onClick = { onMessage("Печать документов недоступна в MVP") }) { Text("Печать") }
                }
            }
        }
    }
}

@Composable
private fun CreateOrderDialog(repository: PromSnabRepository, onDismiss: () -> Unit, onCreate: () -> Unit) {
    var customer by remember { mutableStateOf("") }
    var productId by remember { mutableStateOf(repository.products.firstOrNull()?.id ?: 0) }
    var quantity by remember { mutableStateOf("1") }
    var assignedTo by remember { mutableStateOf(repository.warehouseUsers().firstOrNull()?.id) }
    AlertDialog(
        onDismissRequest = onDismiss,
        title = { Text("Новая отгрузка") },
        text = {
            Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
                OutlinedTextField(customer, { customer = it }, Modifier.fillMaxWidth(), label = { Text("Клиент") }, singleLine = true)
                ProductSelector(repository, productId) { productId = it }
                UserSelector(repository, assignedTo) { assignedTo = it }
                OutlinedTextField(quantity, { quantity = it.onlyDigits() }, Modifier.fillMaxWidth(), label = { Text("Количество") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), singleLine = true)
            }
        },
        confirmButton = {
            Button(
                onClick = {
                    repository.createOrder(customer, productId, quantity.toIntOrNull() ?: 1, assignedTo)
                    onCreate()
                },
                enabled = customer.isNotBlank() && productId != 0
            ) { Text("Создать") }
        },
        dismissButton = { TextButton(onClick = onDismiss) { Text("Отмена") } }
    )
}

@Composable
private fun InventoryScreen(user: User, repository: PromSnabRepository, snackbarHostState: SnackbarHostState) {
    var search by remember { mutableStateOf("") }
    var countFilter by remember { mutableStateOf("Все позиции") }
    var showFilters by remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope()
    val active = repository.inventories.firstOrNull { it.status == "active" }
    val countFilters = listOf("Все позиции", "Не посчитано", "Есть расхождение", "Без расхождений")
    val filteredActiveItems = active?.items.orEmpty().filter {
        val productName = repository.productName(it.productId)
        val matchesSearch = search.isBlank() || productName.contains(search, true)
        val matchesState = when (countFilter) {
            "Не посчитано" -> it.actualQuantity == null
            "Есть расхождение" -> (it.difference ?: 0) != 0
            "Без расхождений" -> it.actualQuantity != null && it.difference == 0
            else -> true
        }
        matchesSearch && matchesState
    }
    ScreenScaffold("Инвентаризация") {
        LazyColumn(verticalArrangement = Arrangement.spacedBy(10.dp)) {
            item {
                if (active == null && user.role.canOperateWarehouse) {
                    Button(onClick = {
                        repository.startInventory(user)
                        scope.launch { snackbarHostState.showSnackbar("Инвентаризация начата") }
                    }) { Text("Начать новую инвентаризацию") }
                } else if (active != null) {
                    Text("Активная инвентаризация: ${active.number}", fontWeight = FontWeight.SemiBold)
                }
            }
            if (active != null) {
                item {
                    SearchFilterBar(
                        query = search,
                        onQueryChange = { search = it },
                        placeholder = "Поиск товара",
                        onFilterClick = { showFilters = true }
                    )
                }
                items(filteredActiveItems, key = { it.productId }) { item ->
                    InventoryItemCard(user, repository, active, item) {
                        scope.launch { snackbarHostState.showSnackbar(it) }
                    }
                }
                item {
                    val canFinish = active.items.all { it.actualQuantity != null }
                    Button(
                        onClick = {
                            repository.finishInventory(active, applyCorrections = user.role == Role.Administrator)
                            scope.launch { snackbarHostState.showSnackbar("Инвентаризация завершена") }
                        },
                        enabled = canFinish && user.role.canOperateWarehouse
                    ) {
                        Text(if (user.role == Role.Administrator) "Завершить и применить корректировки" else "Завершить инвентаризацию")
                    }
                }
            }
            item {
                Text("История", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)
            }
            items(repository.inventories.filter { it.status == "completed" }, key = { it.id }) { session ->
                ElevatedCard(shape = RoundedCornerShape(8.dp)) {
                    Column(Modifier.padding(14.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
                        Text(session.number, fontWeight = FontWeight.SemiBold)
                        Text("Позиций: ${session.items.size} · Расхождений: ${session.items.count { (it.difference ?: 0) != 0 }}")
                        if (user.role.canConfirmDocuments) {
                            Text("Доступно утверждение результатов и анализ расхождений", color = MaterialTheme.colorScheme.onSurfaceVariant)
                        }
                    }
                }
            }
        }
    }
    if (showFilters) {
        FilterDialog(title = "Фильтры инвентаризации", onDismiss = { showFilters = false }) {
            FilterMenu("Состояние", countFilter, countFilters) { countFilter = it }
        }
    }
}

@Composable
private fun InventoryItemCard(user: User, repository: PromSnabRepository, session: InventorySession, item: InventoryItem, onMessage: (String) -> Unit) {
    var actual by remember(session.id, item.productId, item.actualQuantity) { mutableStateOf((item.actualQuantity ?: item.expectedQuantity).toString()) }
    ElevatedCard(shape = RoundedCornerShape(8.dp)) {
        Column(Modifier.padding(14.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
            Text(repository.productName(item.productId), fontWeight = FontWeight.SemiBold)
            Text("В системе: ${item.expectedQuantity} · Факт: ${item.actualQuantity ?: "-"} · Разница: ${item.difference ?: "-"}")
            if (user.role.canOperateWarehouse) {
                Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
                    OutlinedTextField(actual, { actual = it.onlyDigits() }, Modifier.weight(1f), label = { Text("Фактический остаток") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), singleLine = true)
                    Button(onClick = {
                        repository.countInventoryItem(session, item, actual.toIntOrNull() ?: 0)
                        onMessage("Остаток зафиксирован")
                    }) { Text("Сохранить") }
                }
            }
        }
    }
}

@Composable
private fun ProfileScreen(user: User, onLogout: () -> Unit) {
    var fullName by remember(user) { mutableStateOf(user.fullName) }
    ScreenScaffold("Профиль") {
        Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
            val isStorekeeper = user.role == Role.Storekeeper
            OutlinedTextField(
                value = fullName,
                onValueChange = { if (!isStorekeeper) fullName = it },
                modifier = Modifier.fillMaxWidth(),
                label = { Text("ФИО") },
                enabled = !isStorekeeper,
                singleLine = true
            )
            if (!isStorekeeper) {
                OutlinedTextField(user.login, {}, Modifier.fillMaxWidth(), label = { Text("Логин") }, enabled = false, singleLine = true)
                OutlinedTextField(user.email, {}, Modifier.fillMaxWidth(), label = { Text("Email") }, enabled = false, singleLine = true)
            }
            RoleSelector(role = user.role, enabled = false, onRoleSelected = {})
            if (!isStorekeeper) {
                Button(onClick = {}, modifier = Modifier.fillMaxWidth()) { Text("Сохранить") }
            }
            OutlinedButton(onClick = onLogout, modifier = Modifier.fillMaxWidth()) { Text("Выйти из аккаунта") }
        }
    }
}

@Composable
private fun ProductSelector(repository: PromSnabRepository, selectedId: Int, onSelected: (Int) -> Unit) {
    var expanded by remember { mutableStateOf(false) }
    val product = repository.products.firstOrNull { it.id == selectedId }
    Box {
        OutlinedButton(onClick = { expanded = true }, modifier = Modifier.fillMaxWidth()) {
            Text(product?.name ?: "Выберите товар")
        }
        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
            repository.products.forEach {
                DropdownMenuItem(text = { Text("${it.sku} · ${it.name}") }, onClick = {
                    onSelected(it.id)
                    expanded = false
                })
            }
        }
    }
}

@Composable
private fun UserSelector(repository: PromSnabRepository, selectedId: Int?, onSelected: (Int?) -> Unit) {
    var expanded by remember { mutableStateOf(false) }
    val user = repository.users.firstOrNull { it.id == selectedId }
    Box {
        OutlinedButton(onClick = { expanded = true }, modifier = Modifier.fillMaxWidth()) {
            Text(user?.fullName ?: "Назначить сборщика")
        }
        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
            repository.warehouseUsers().forEach {
                DropdownMenuItem(text = { Text("${it.fullName} · ${it.role.label}") }, onClick = {
                    onSelected(it.id)
                    expanded = false
                })
            }
        }
    }
}

@Composable
private fun StatusChip(status: String) {
    val color = when (status) {
        "Завершена", "Готов", "Отгружен", "completed" -> Color(0xFF27AE60)
        "Расхождение", "shortage" -> Color(0xFFE74C3C)
        else -> Color(0xFF3498DB)
    }
    AssistChip(onClick = {}, label = { Text(status) }, colors = androidx.compose.material3.AssistChipDefaults.assistChipColors(labelColor = color))
}

private fun String.onlyDigits(): String = filter { it.isDigit() }
private fun String.decimalInput(): String = filter { it.isDigit() || it == '.' || it == ',' }.replace(',', '.')

@Preview(showBackground = true)
@Composable
private fun PromSnabPreview() {
    PromSnabTheme {
        PromSnabApp()
    }
}