@file:Suppress("AssignedValueIsNeverRead")

package eu.gaudian.translator.view.settings

import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Checkbox
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.navigation.NavController
import eu.gaudian.translator.R
import eu.gaudian.translator.model.Language
import eu.gaudian.translator.utils.StatusMessageId
import eu.gaudian.translator.utils.StatusMessageService
import eu.gaudian.translator.utils.findActivity
import eu.gaudian.translator.view.composable.AppButton
import eu.gaudian.translator.view.composable.AppCard
import eu.gaudian.translator.view.composable.AppOutlinedButton
import eu.gaudian.translator.view.composable.AppScaffold
import eu.gaudian.translator.view.composable.AppTopAppBar
import eu.gaudian.translator.view.composable.PrimaryButton
import eu.gaudian.translator.view.composable.SecondaryButton
import eu.gaudian.translator.view.composable.SingleLanguageDropDown
import eu.gaudian.translator.viewmodel.LanguageViewModel
import eu.gaudian.translator.viewmodel.VocabularyViewModel

@Composable
fun VocabularyRepositoryOptionsScreen(
    navController: NavController
) {

    val activity = LocalContext.current.findActivity()
    val vocabularyViewModel: VocabularyViewModel = hiltViewModel(viewModelStoreOwner = activity)
    val statusMessageService = StatusMessageService


    val context = LocalContext.current
    val repositoryStateImportedFrom = stringResource(R.string.repository_state_imported_from)

    val importFileLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.OpenDocument(),
        onResult = { uri ->
            uri?.let {
                context.contentResolver.openInputStream(it)?.use { inputStream ->
                    val jsonString = inputStream.bufferedReader().use { reader -> reader.readText() }
                    vocabularyViewModel.importVocabulary(jsonString)
                    statusMessageService.showInfoMessage(repositoryStateImportedFrom + " " +it.path)
                }
            }
        }
    )

    // CSV/Excel import state
    val languageViewModel: LanguageViewModel = hiltViewModel(viewModelStoreOwner = activity)
    val showTableImportDialog = remember { mutableStateOf(false) }
    var parsedTable by remember { mutableStateOf<List<List<String>>>(emptyList()) }
    var selectedColFirst by remember { mutableIntStateOf(0) }
    var selectedColSecond by remember { mutableIntStateOf(1) }
    var skipHeader by remember { mutableStateOf(true) }
    var selectedLangFirst by remember { mutableStateOf<Language?>(null) }
    var selectedLangSecond by remember { mutableStateOf<Language?>(null) }
    var parseError by remember { mutableStateOf<String?>(null) }

    fun parseCsv(text: String): List<List<String>> {
        if (text.isBlank()) return emptyList()
        // Detect delimiter by highest occurrence among comma, semicolon, tab
        val candidates = listOf(',', ';', '\t')
        val sampleLine = text.lineSequence().firstOrNull { it.isNotBlank() } ?: return emptyList()
        val delimiter = candidates.maxBy { c -> sampleLine.count { it == c } }

        val rows = mutableListOf<List<String>>()
        var current = StringBuilder()
        var inQuotes = false
        val currentRow = mutableListOf<String>()

        var i = 0
        while (i < text.length) {
            when (val ch = text[i]) {
                '"' -> {
                    if (inQuotes && i + 1 < text.length && text[i + 1] == '"') {
                        current.append('"')
                        i++ // skip escaped quote
                    } else {
                        inQuotes = !inQuotes
                    }
                }
                '\r' -> { /* ignore, handle on \n */ }
                '\n' -> {
                    // end of line
                    val field = current.toString()
                    current = StringBuilder()
                    currentRow.add(if (inQuotes) field else field)
                    rows.add(currentRow.toList())
                    currentRow.clear()
                    inQuotes = false
                }
                else -> {
                    if (ch == delimiter && !inQuotes) {
                        val field = current.toString()
                        currentRow.add(field)
                        current = StringBuilder()
                    } else {
                        current.append(ch)
                    }
                }
            }
            i++
        }
        // flush last field/row if any
        if (current.isNotEmpty() || currentRow.isNotEmpty()) {
            currentRow.add(current.toString())
            rows.add(currentRow.toList())
        }
        // Normalize: trim and drop trailing empty columns
        return rows.map { row ->
            row.map { it.trim().trim('"') }
        }.filter { r -> r.any { it.isNotBlank() } }
    }

    val errorParsingTable = stringResource(R.string.error_parsing_table)
    val errorParsingTableWithReason = stringResource(R.string.error_parsing_table_with_reason)
    val importTableLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.OpenDocument(),
        onResult = { uri ->
            uri?.let { u ->
                try {
                    context.contentResolver.takePersistableUriPermission(u, android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION)
                } catch (_: Exception) {}
                try {
                    val mime = context.contentResolver.getType(u)
                    val isExcel = mime == "application/vnd.ms-excel" || mime == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                    if (isExcel) {
                        statusMessageService.showErrorById(StatusMessageId.ERROR_EXCEL_NOT_SUPPORTED)
                        return@let
                    }
                    context.contentResolver.openInputStream(u)?.use { inputStream ->
                        val text = inputStream.bufferedReader().use { it.readText() }
                        val rows = parseCsv(text)
                        if (rows.isNotEmpty() && rows.maxOf { it.size } >= 2) {
                            parsedTable = rows
                            selectedColFirst = 0
                            selectedColSecond = 1.coerceAtMost(rows.first().size - 1)
                            showTableImportDialog.value = true
                            parseError = null
                        } else {
                            parseError = errorParsingTable
                            statusMessageService.showErrorMessage(parseError!!)
                        }
                    }
                } catch (e: Exception) {
                    parseError = e.message
                    statusMessageService.showErrorMessage(
                        (errorParsingTableWithReason + " " + e.message)
                    )
                }
            }
        }
    )

    val exportFileLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartActivityForResult(),
        onResult = { result -> vocabularyViewModel.handleSaveResult(result) }
    )

    LaunchedEffect(exportFileLauncher) {
        vocabularyViewModel.initializeSaveFileLauncher(exportFileLauncher)
    }


    AppScaffold(
        topBar = {
            AppTopAppBar(
                title = stringResource(R.string.vocabulary_repository),
                onNavigateBack = { navController.popBackStack() },
            )
        }
    ) { paddingValues ->
        LazyColumn(
            modifier = Modifier
                .fillMaxSize()
                .padding(paddingValues)
                .padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            item {
                // Backup and Restore Section
                AppCard {
                    Column(
                        modifier = Modifier.padding(16.dp),
                        verticalArrangement = Arrangement.spacedBy(12.dp)
                    ) {
                        Text(
                            text = stringResource(R.string.label_backup_and_restore),
                            style = MaterialTheme.typography.titleMedium
                        )
                        PrimaryButton(
                            onClick = { vocabularyViewModel.saveRepositoryState() },
                            text = stringResource(R.string.export_vocabulary_data),
                            modifier = Modifier.fillMaxWidth()
                        )
                        SecondaryButton(
                            onClick = { importFileLauncher.launch(arrayOf("application/json")) },
                            text = stringResource(R.string.import_vocabulary_data),
                            modifier = Modifier.fillMaxWidth()
                        )
                        SecondaryButton(
                            onClick = {
                                // Allow CSV and Excel mime types, but we only support CSV parsing in-app
                                @Suppress("HardCodedStringLiteral")
                                importTableLauncher.launch(
                                    arrayOf(
                                        "text/csv",
                                        "text/comma-separated-values",
                                        "text/tab-separated-values",
                                        "text/plain",
                                        "application/vnd.ms-excel",
                                        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                                    )
                                )
                            },
                            text = stringResource(R.string.label_import_table_csv_excel),
                            modifier = Modifier.fillMaxWidth()
                        )
                    }
                }
            }
            item {
                AppCard {
                    Column(
                        modifier = Modifier.padding(16.dp),
                        verticalArrangement = Arrangement.spacedBy(12.dp)
                    ) {
                        Text(
                            text = stringResource(R.string.danger_zone),
                            style = MaterialTheme.typography.titleMedium,
                            color = MaterialTheme.colorScheme.error
                        )

                        val showConfirm = androidx.compose.runtime.remember { mutableStateOf(false) }

                        AppButton(
                            onClick = { showConfirm.value = true },
                            modifier = Modifier.fillMaxWidth(),
                            colors = ButtonDefaults.buttonColors(
                                containerColor = MaterialTheme.colorScheme.error,
                                contentColor = MaterialTheme.colorScheme.onError
                            )
                        ) {
                            Text(stringResource(R.string.wipe_repository_delete_all_data))
                        }

                        if (showConfirm.value) {
                            AlertDialog(
                                onDismissRequest = { showConfirm.value = false },
                                title = { Text(stringResource(R.string.label_warning)) },
                                text = { Text(stringResource(R.string.wipe_repository_delete_all_data)) },
                                confirmButton = {
                                    TextButton(onClick = {
                                        showConfirm.value = false
                                        vocabularyViewModel.wipeRepository()
                                    },
                                        colors = ButtonDefaults.textButtonColors(
                                            contentColor = MaterialTheme.colorScheme.error
                                        )) {
                                        Text(stringResource(R.string.label_confirm))
                                    }
                                },
                                dismissButton = {
                                    TextButton(onClick = { showConfirm.value = false }) {
                                        Text(stringResource(R.string.label_cancel))
                                    }
                                }
                            )
                        }
                    }
                }
            }
        }


        if (showTableImportDialog.value) {
            AlertDialog(
                onDismissRequest = { showTableImportDialog.value = false },
                title = { Text(stringResource(R.string.label_import_table_csv_excel)) },
                text = {
                    Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
                        val columnCount = parsedTable.maxOfOrNull { it.size } ?: 0
                        // Column selectors
                        Row(verticalAlignment = Alignment.CenterVertically) {
                            Text(stringResource(R.string.label_first_column), modifier = Modifier.weight(1f))
                            var menu1Expanded by remember { mutableStateOf(false) }
                            AppOutlinedButton(onClick = { menu1Expanded = true }) { Text(stringResource(R.string.label_column_n, selectedColFirst + 1)) }
                            DropdownMenu(expanded = menu1Expanded, onDismissRequest = { menu1Expanded = false }) {
                                (0 until columnCount).forEach { idx ->
                                    val header = parsedTable.firstOrNull()?.getOrNull(idx).orEmpty()
                                    DropdownMenuItem(
                                        text = { Text("#${idx + 1} • $header") },
                                        onClick = { selectedColFirst = idx; menu1Expanded = false }
                                    )
                                }
                            }
                        }
                        Row(verticalAlignment = Alignment.CenterVertically) {
                            Text(stringResource(R.string.label_second_column), modifier = Modifier.weight(1f))
                            var menu2Expanded by remember { mutableStateOf(false) }
                            AppOutlinedButton(onClick = { menu2Expanded = true }) { Text(stringResource(R.string.label_column_n, selectedColSecond + 1)) }
                            DropdownMenu(expanded = menu2Expanded, onDismissRequest = { menu2Expanded = false }) {
                                (0 until columnCount).forEach { idx ->
                                    val header = parsedTable.firstOrNull()?.getOrNull(idx).orEmpty()
                                    DropdownMenuItem(
                                        text = { Text("#${idx + 1} • $header") },
                                        onClick = { selectedColSecond = idx; menu2Expanded = false }
                                    )
                                }
                            }
                        }
                        // Language selectors
                        Text(stringResource(R.string.label_languages))
                        Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
                            Column(modifier = Modifier.weight(1f)) {
                                Text(stringResource(R.string.label_first_language))
                                SingleLanguageDropDown(
                                    languageViewModel = languageViewModel,
                                    selectedLanguage = selectedLangFirst,
                                    onLanguageSelected = { selectedLangFirst = it }
                                )
                            }
                            Column(modifier = Modifier.weight(1f)) {
                                Text(stringResource(R.string.label_second_language))
                                SingleLanguageDropDown(
                                    languageViewModel = languageViewModel,
                                    selectedLanguage = selectedLangSecond,
                                    onLanguageSelected = { selectedLangSecond = it }
                                )
                            }
                        }
                        // Header toggle
                        Row(verticalAlignment = Alignment.CenterVertically) {
                            Checkbox(checked = skipHeader, onCheckedChange = { skipHeader = it })
                            Spacer(modifier = Modifier.width(4.dp))
                            Text(stringResource(R.string.label_header_row))
                        }
                        // Previews
                        val startIdx = if (skipHeader) 1 else 0
                        val previewA = parsedTable.drop(startIdx).take(5).mapNotNull { it.getOrNull(selectedColFirst) }.joinToString(", ")
                        val previewB = parsedTable.drop(startIdx).take(5).mapNotNull { it.getOrNull(selectedColSecond) }.joinToString(", ")
                        Text(stringResource(R.string.label_preview_first, previewA))
                        Text(stringResource(R.string.label_preview_second, previewB))
                        val totalRows = parsedTable.drop(startIdx).count { row ->
                            val a = row.getOrNull(selectedColFirst).orEmpty().isNotBlank()
                            val b = row.getOrNull(selectedColSecond).orEmpty().isNotBlank()
                            a || b
                        }
                        Text(stringResource(R.string.text_rows_to_import_1d, totalRows))
                    }
                },
                confirmButton = {
                    val errorSelectTwoColumns = stringResource(R.string.error_select_two_columns)
                    val errorSelectLanguages = stringResource(R.string.error_select_languages)
                    val errorNoRowsToImport = stringResource(R.string.error_no_rows_to_import)
                    val infoImportedItemsFrom = stringResource(R.string.info_imported_items_from)
                    TextButton(onClick = {
                        if (selectedColFirst == selectedColSecond) {
                            statusMessageService.showErrorMessage(errorSelectTwoColumns)
                            return@TextButton
                        }
                        val langA = selectedLangFirst
                        val langB = selectedLangSecond
                        if (langA == null || langB == null) {
                            statusMessageService.showErrorMessage(errorSelectLanguages)
                            return@TextButton
                        }
                        val startIdx = if (skipHeader) 1 else 0
                        val items = parsedTable.drop(startIdx).mapNotNull { row ->
                            val a = row.getOrNull(selectedColFirst)?.trim().orEmpty()
                            val b = row.getOrNull(selectedColSecond)?.trim().orEmpty()
                            if (a.isBlank() && b.isBlank()) null else eu.gaudian.translator.model.VocabularyItem(
                                id = 0,
                                languageFirstId = langA.nameResId,
                                languageSecondId = langB.nameResId,
                                wordFirst = a,
                                wordSecond = b
                            )
                        }
                        if (items.isEmpty()) {
                            statusMessageService.showErrorMessage(errorNoRowsToImport)
                            return@TextButton
                        }
                        vocabularyViewModel.addVocabularyItems(items)
                        statusMessageService.showSuccessMessage(infoImportedItemsFrom + " " +items.size)
                        showTableImportDialog.value = false
                    }) { Text(stringResource(R.string.label_import)) }
                },
                dismissButton = {
                    TextButton(onClick = { showTableImportDialog.value = false }) { Text(stringResource(R.string.label_cancel)) }
                }
            )
        }
    }
}