/*
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package com.bartek.iwentaryzacja

import android.content.Context
import android.net.Uri
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.List
import androidx.compose.material.icons.filled.*
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextAlign
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.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.viewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import org.apache.poi.ss.usermodel.WorkbookFactory
import org.json.JSONArray
import org.json.JSONObject
import java.io.InputStream

// ==========================================
// 1. MODEL DANYCH MASZYNY
// ==========================================
data class Machine(
    val id: String,          // Nr ewid. (np. 7065/K)
    val name: String,        // Nazwa sprzętu
    val category: String,    // Kategoria (np. minikoparki)
    val originalStatus: String, // Status z kolumny H
    val isChecked: Boolean = false
)

// ==========================================
// 2. VIEWMODEL (DOPASOWANY PARSER .XLSX)
// ==========================================
class InventoryViewModel : ViewModel() {
    private val _machines = MutableStateFlow<List<Machine>>(emptyList())
    val machines: StateFlow<List<Machine>> = _machines.asStateFlow()

    private val _searchQuery = MutableStateFlow("")
    val searchQuery: StateFlow<String> = _searchQuery.asStateFlow()

    private val _filterMissing = MutableStateFlow(false)
    val filterMissing: StateFlow<Boolean> = _filterMissing.asStateFlow()

    private val _notes = MutableStateFlow("")
    val notes: StateFlow<String> = _notes.asStateFlow()

    fun loadState(context: Context) {
        val prefs = context.getSharedPreferences("inventory_prefs", Context.MODE_PRIVATE)
        _notes.value = prefs.getString("notes", "") ?: ""
        
        val machinesJson = prefs.getString("machines", null)
        if (machinesJson != null) {
            try {
                val jsonArray = JSONArray(machinesJson)
                val loadedList = mutableListOf<Machine>()
                for (i in 0 until jsonArray.length()) {
                    val obj = jsonArray.getJSONObject(i)
                    loadedList.add(
                        Machine(
                            id = obj.getString("id"),
                            name = obj.getString("name"),
                            category = obj.getString("category"),
                            originalStatus = obj.getString("originalStatus"),
                            isChecked = obj.getBoolean("isChecked")
                        )
                    )
                }
                _machines.value = loadedList
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    private fun saveState(context: Context) {
        val prefs = context.getSharedPreferences("inventory_prefs", Context.MODE_PRIVATE)
        val editor = prefs.edit()
        editor.putString("notes", _notes.value)
        
        val jsonArray = JSONArray()
        _machines.value.forEach { machine ->
            val obj = JSONObject()
            obj.put("id", machine.id)
            obj.put("name", machine.name)
            obj.put("category", machine.category)
            obj.put("originalStatus", machine.originalStatus)
            obj.put("isChecked", machine.isChecked)
            jsonArray.put(obj)
        }
        editor.putString("machines", jsonArray.toString())
        editor.apply()
    }

    fun setSearchQuery(query: String) {
        _searchQuery.value = query
    }

    fun setNotes(context: Context, newNotes: String) {
        _notes.value = newNotes
        saveState(context)
    }

    fun appendDigit(digit: String) {
        _searchQuery.value += digit
    }

    fun backspace() {
        if (_searchQuery.value.isNotEmpty()) {
            _searchQuery.value = _searchQuery.value.dropLast(1)
        }
    }

    fun clearSearch() {
        _searchQuery.value = ""
    }

    fun toggleFilterMissing() {
        _filterMissing.value = !_filterMissing.value
    }

    fun getUniqueStatuses(): List<String> {
        return _machines.value
            .map { it.originalStatus }
            .filter { it.isNotEmpty() }
            .distinct()
            .sorted()
    }

    fun markMachinesByStatuses(context: Context, statuses: Set<String>, isChecked: Boolean) {
        _machines.value = _machines.value.map { machine ->
            if (statuses.contains(machine.originalStatus)) {
                machine.copy(isChecked = isChecked)
            } else {
                machine
            }
        }
        saveState(context)
    }

    fun toggleMachineCheck(context: Context, machineId: String) {
        _machines.value = _machines.value.map { machine ->
            if (machine.id == machineId) {
                machine.copy(isChecked = !machine.isChecked)
            } else {
                machine
            }
        }
        saveState(context)
    }

    // Parser zoptymalizowany pod strukturę raportu z systemu
    fun parseXlsFile(context: Context, inputStream: InputStream) {
        try {
            // WorkbookFactory automatycznie obsługuje zarówno .xls jak i .xlsx
            val workbook = WorkbookFactory.create(inputStream)
            val sheet = workbook.getSheetAt(0)
            val parsedList = mutableListOf<Machine>()

            // Dane zaczynają się od wiersza indeks 2 (po 2 wierszach nagłówka)
            for (rowIndex in 2..sheet.lastRowNum) {
                val row = sheet.getRow(rowIndex) ?: continue

                val category = row.getCell(1)?.toString()?.trim() ?: ""
                val id = row.getCell(2)?.toString()?.trim() ?: ""
                val name = row.getCell(3)?.toString()?.trim() ?: ""
                val status = row.getCell(7)?.toString()?.trim() ?: ""

                // Wczytujemy tylko, gdy pozycja ma nazwę i nr ewidencyjny
                if (name.isNotEmpty() && id.isNotEmpty()) {
                    parsedList.add(
                        Machine(
                            id = id,
                            name = name,
                            category = category,
                            originalStatus = status
                        )
                    )
                }
            }
            _machines.value = parsedList
            workbook.close()
            saveState(context)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}

// ==========================================
// 3. GŁÓWNA AKTYWNOŚĆ
// ==========================================
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()

        setContent {
            MaterialTheme(
                colorScheme = darkColorScheme(
                    primary = Color(0xFF007ACC),
                    background = Color(0xFF121824),
                    surface = Color(0xFF1E2638)
                )
            ) {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    InventoryScreen()
                }
            }
        }
    }
}

// ==========================================
// 4. EKRAN GŁÓWNY
// ==========================================
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun InventoryScreen(viewModel: InventoryViewModel = viewModel()) {
    val context = LocalContext.current
    val machines by viewModel.machines.collectAsState()
    val searchQuery by viewModel.searchQuery.collectAsState()
    val filterMissing by viewModel.filterMissing.collectAsState()
    val notes by viewModel.notes.collectAsState()
    
    var showStatusDialog by remember { mutableStateOf(false) }
    var showNotesDialog by remember { mutableStateOf(false) }

    LaunchedEffect(Unit) {
        viewModel.loadState(context)
    }

    // Launcher akceptujący pliki .xlsx oraz .xls
    val filePickerLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.GetContent()
    ) { uri: Uri? ->
        uri?.let {
            context.contentResolver.openInputStream(it)?.use { inputStream ->
                viewModel.parseXlsFile(context, inputStream)
            }
        }
    }

    if (showStatusDialog) {
        StatusSelectionDialog(
            statuses = viewModel.getUniqueStatuses(),
            onDismiss = { showStatusDialog = false },
            onConfirm = { selectedStatuses ->
                viewModel.markMachinesByStatuses(context, selectedStatuses, true)
                showStatusDialog = false
            }
        )
    }

    if (showNotesDialog) {
        NotesDialog(
            notes = notes,
            onNotesChange = { viewModel.setNotes(context, it) },
            onDismiss = { showNotesDialog = false }
        )
    }

    val filteredMachines = remember(machines, searchQuery, filterMissing) {
        var list = if (searchQuery.isBlank()) machines
        else machines.filter {
            it.name.contains(searchQuery, ignoreCase = true) ||
                    it.id.contains(searchQuery, ignoreCase = true) ||
                    it.category.contains(searchQuery, ignoreCase = true)
        }
        
        if (filterMissing) {
            list = list.filter { !it.isChecked }
        }
        list
    }

    val checkedCount = machines.count { it.isChecked }
    val totalCount = machines.size
    val progress = if (totalCount > 0) checkedCount.toFloat() / totalCount.toFloat() else 0f

    Scaffold(
        modifier = Modifier.fillMaxSize(),
        containerColor = MaterialTheme.colorScheme.background,
        contentWindowInsets = WindowInsets.safeDrawing
    ) { innerPadding ->
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(innerPadding)
                .padding(horizontal = 16.dp, vertical = 8.dp)
        ) {
            // Cztery małe kafelki w jednej linii
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.spacedBy(4.dp)
            ) {
                DashboardTile(
                    title = "Wczytaj",
                    icon = Icons.Default.FileDownload,
                    color = Color(0xFF007ACC),
                    onClick = { filePickerLauncher.launch("*/*") },
                    modifier = Modifier.weight(1f)
                )
                DashboardTile(
                    title = if (filterMissing) "Wszystkie" else "Brakujące",
                    icon = if (filterMissing) Icons.AutoMirrored.Filled.List else Icons.Default.Search,
                    color = if (filterMissing) Color(0xFFFF9800) else Color(0xFFE91E63),
                    onClick = { viewModel.toggleFilterMissing() },
                    modifier = Modifier.weight(1f)
                )
                DashboardTile(
                    title = "Statusy",
                    icon = Icons.Default.Info,
                    color = Color(0xFF9C27B0),
                    onClick = { showStatusDialog = true },
                    modifier = Modifier.weight(1f)
                )
                DashboardTile(
                    title = "Dopisz",
                    icon = Icons.Default.EditNote,
                    color = Color(0xFF4CAF50),
                    onClick = { showNotesDialog = true },
                    modifier = Modifier.weight(1f)
                )
            }

            Spacer(modifier = Modifier.height(16.dp))

            if (machines.isNotEmpty()) {
                Card(
                    colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
                    shape = RoundedCornerShape(8.dp),
                    modifier = Modifier.fillMaxWidth()
                ) {
                    Column(modifier = Modifier.padding(8.dp)) {
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            horizontalArrangement = Arrangement.SpaceBetween
                        ) {
                            Text("Postęp:", color = Color.Gray, fontSize = 12.sp)
                            Text(
                                "$checkedCount / $totalCount (${(progress * 100).toInt()}%)",
                                color = Color.White,
                                fontWeight = FontWeight.Bold,
                                fontSize = 12.sp
                            )
                        }
                        Spacer(modifier = Modifier.height(4.dp))
                        LinearProgressIndicator(
                            progress = { progress },
                            modifier = Modifier
                                .fillMaxWidth()
                                .height(4.dp)
                                .clip(RoundedCornerShape(2.dp)),
                            color = Color(0xFF11CAA0),
                            trackColor = Color(0xFF2A3447)
                        )
                    }
                }

                Spacer(modifier = Modifier.height(8.dp))

                // Lista zajmuje elastyczną przestrzeń, ale zostanie ograniczona przez klawiaturę
                LazyColumn(
                    verticalArrangement = Arrangement.spacedBy(4.dp),
                    modifier = Modifier.weight(1f) // Używamy weight, aby zajęła resztę miejsca przed klawiaturą
                ) {
                    items(filteredMachines, key = { it.id }) { machine ->
                        MachineItem(
                            machine = machine,
                            onToggle = { viewModel.toggleMachineCheck(context, machine.id) }
                        )
                    }
                }
                
                Spacer(modifier = Modifier.height(8.dp))
                
                // Bardzo mały pasek szukania nad klawiaturą
                OutlinedTextField(
                    value = searchQuery,
                    onValueChange = { viewModel.setSearchQuery(it) },
                    placeholder = { Text("Szukaj...", fontSize = 12.sp, color = Color.Gray) },
                    modifier = Modifier.fillMaxWidth().height(48.dp),
                    shape = RoundedCornerShape(8.dp),
                    singleLine = true,
                    textStyle = LocalTextStyle.current.copy(fontSize = 13.sp),
                    colors = OutlinedTextFieldDefaults.colors(
                        focusedBorderColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.5f),
                        unfocusedBorderColor = Color(0xFF2A3447),
                        focusedContainerColor = MaterialTheme.colorScheme.surface,
                        unfocusedContainerColor = MaterialTheme.colorScheme.surface,
                        focusedTextColor = Color.White,
                        unfocusedTextColor = Color.White
                    )
                )
                
                Spacer(modifier = Modifier.height(8.dp))
                
                // Klawiatura numeryczna na dole
                NumericKeyboard(
                    onDigitClick = { viewModel.appendDigit(it) },
                    onBackspace = { viewModel.backspace() },
                    onClear = { viewModel.clearSearch() }
                )
            } else {
                Box(
                    modifier = Modifier
                        .fillMaxSize()
                        .padding(32.dp),
                    contentAlignment = Alignment.Center
                ) {
                    Text(
                        text = "Brak wczytanych maszyn.\nWybierz plik .xlsx wygenerowany z systemu.",
                        color = Color.Gray,
                        fontSize = 16.sp,
                        textAlign = TextAlign.Center
                    )
                }
            }
        }
    }
}

// ==========================================
// 5. POJEDYNCZY ELEMENT LISTY
// ==========================================
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DashboardTile(
    title: String,
    icon: ImageVector,
    color: Color,
    onClick: () -> Unit,
    modifier: Modifier = Modifier
) {
    Card(
        onClick = onClick,
        modifier = modifier.height(70.dp), // Zmniejszona wysokość
        shape = RoundedCornerShape(12.dp),
        colors = CardDefaults.cardColors(containerColor = color.copy(alpha = 0.15f)),
        border = androidx.compose.foundation.BorderStroke(1.dp, color.copy(alpha = 0.3f))
    ) {
        Column(
            modifier = Modifier.fillMaxSize().padding(4.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Icon(icon, contentDescription = null, tint = color, modifier = Modifier.size(24.dp))
            Spacer(modifier = Modifier.height(2.dp))
            Text(
                text = title,
                fontSize = 11.sp,
                fontWeight = FontWeight.Bold,
                color = Color.White,
                textAlign = TextAlign.Center,
                lineHeight = 12.sp
            )
        }
    }
}

@Composable
fun StatusSelectionDialog(
    statuses: List<String>,
    onDismiss: () -> Unit,
    onConfirm: (Set<String>) -> Unit
) {
    var selectedStatuses by remember { mutableStateOf(setOf<String>()) }

    AlertDialog(
        onDismissRequest = onDismiss,
        title = { Text("Wybierz statusy do zaznaczenia") },
        text = {
            if (statuses.isEmpty()) {
                Text("Brak wczytanych maszyn ze statusami.")
            } else {
                LazyColumn(modifier = Modifier.fillMaxWidth().heightIn(max = 300.dp)) {
                    items(statuses) { status ->
                        Row(
                            verticalAlignment = Alignment.CenterVertically,
                            modifier = Modifier
                                .fillMaxWidth()
                                .clickable {
                                    selectedStatuses = if (selectedStatuses.contains(status)) {
                                        selectedStatuses - status
                                    } else {
                                        selectedStatuses + status
                                    }
                                }
                                .padding(vertical = 8.dp)
                        ) {
                            Checkbox(
                                checked = selectedStatuses.contains(status),
                                onCheckedChange = null // Obsłużone w Row.clickable
                            )
                            Spacer(modifier = Modifier.width(8.dp))
                            Text(status, color = Color.White)
                        }
                    }
                }
            }
        },
        confirmButton = {
            TextButton(onClick = { onConfirm(selectedStatuses) }) {
                Text("Zastosuj")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Anuluj")
            }
        },
        containerColor = Color(0xFF1E2638),
        titleContentColor = Color.White,
        textContentColor = Color.White
    )
}

@Composable
fun NotesDialog(
    notes: String,
    onNotesChange: (String) -> Unit,
    onDismiss: () -> Unit
) {
    AlertDialog(
        onDismissRequest = onDismiss,
        title = { Text("Notatnik", color = Color.White) },
        text = {
            OutlinedTextField(
                value = notes,
                onValueChange = onNotesChange,
                modifier = Modifier.fillMaxWidth().height(200.dp),
                placeholder = { Text("Wpisz notatki tutaj...", color = Color.Gray) },
                colors = OutlinedTextFieldDefaults.colors(
                    focusedTextColor = Color.White,
                    unfocusedTextColor = Color.White,
                    focusedContainerColor = Color(0xFF2A3447),
                    unfocusedContainerColor = Color(0xFF2A3447)
                )
            )
        },
        confirmButton = {
            TextButton(onClick = onDismiss) {
                Text("Zamknij")
            }
        },
        containerColor = Color(0xFF1E2638)
    )
}

@Composable
fun NumericKeyboard(
    onDigitClick: (String) -> Unit,
    onBackspace: () -> Unit,
    onClear: () -> Unit
) {
    Column(
        modifier = Modifier.fillMaxWidth(),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        val buttons = listOf(
            listOf("1", "2", "3"),
            listOf("4", "5", "6"),
            listOf("7", "8", "9"),
            listOf("C", "0", "⌫")
        )

        buttons.forEach { row ->
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.spacedBy(8.dp)
            ) {
                row.forEach { label ->
                    val isSpecial = label == "C" || label == "⌫"
                    KeyButton(
                        label = label,
                        onClick = {
                            when (label) {
                                "C" -> onClear()
                                "⌫" -> onBackspace()
                                else -> onDigitClick(label)
                            }
                        },
                        color = if (isSpecial) Color(0xFF2A3447) else Color(0xFF1E2638),
                        textColor = if (label == "⌫") Color(0xFFE91E63) else if (label == "C") Color(0xFFFF9800) else Color.White,
                        modifier = Modifier.weight(1f)
                    )
                }
            }
        }
    }
}

@Composable
fun KeyButton(
    label: String,
    onClick: () -> Unit,
    color: Color,
    textColor: Color,
    modifier: Modifier = Modifier
) {
    Surface(
        onClick = onClick,
        modifier = modifier.height(54.dp),
        shape = RoundedCornerShape(12.dp),
        color = color,
        border = androidx.compose.foundation.BorderStroke(1.dp, Color.White.copy(alpha = 0.1f))
    ) {
        Box(contentAlignment = Alignment.Center) {
            Text(
                text = label,
                fontSize = 20.sp,
                fontWeight = FontWeight.Bold,
                color = textColor
            )
        }
    }
}

@Composable
fun MachineItem(
    machine: Machine,
    onToggle: () -> Unit
) {
    Card(
        shape = RoundedCornerShape(8.dp),
        colors = CardDefaults.cardColors(
            containerColor = if (machine.isChecked) Color(0xFF183B32) else MaterialTheme.colorScheme.surface
        ),
        modifier = Modifier
            .fillMaxWidth()
            .clickable { onToggle() }
    ) {
        Row(
            modifier = Modifier
                .padding(8.dp)
                .fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            Column(modifier = Modifier.weight(1f)) {
                Text(
                    text = machine.id,
                    fontWeight = FontWeight.Bold,
                    fontSize = 14.sp,
                    color = Color.White
                )
                Text(
                    text = machine.name,
                    fontSize = 11.sp,
                    color = Color.LightGray,
                    maxLines = 1
                )
            }
            
            if (machine.originalStatus.isNotEmpty()) {
                Text(
                    text = machine.originalStatus,
                    fontSize = 10.sp,
                    fontWeight = FontWeight.Medium,
                    color = Color(0xFF11CAA0),
                    modifier = Modifier.padding(start = 8.dp)
                )
            }
        }
    }
}