package eu.gaudian.translator.view.dictionary

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import eu.gaudian.translator.R
import eu.gaudian.translator.model.Language
import eu.gaudian.translator.model.repository.DictionaryWordEntry
import eu.gaudian.translator.utils.Log
import eu.gaudian.translator.utils.dictionary.LocalDictionaryAccess
import eu.gaudian.translator.utils.formatJsonForDisplay
import eu.gaudian.translator.viewmodel.DictionaryViewModel
import kotlinx.coroutines.launch

@Composable
fun LocalWordEntryDisplay(
    entry: DictionaryWordEntry,
    dictionaryViewModel: DictionaryViewModel,
    allLanguages: List<Language>,
    expandable: Boolean = false
) {
    // State to hold the parsed data
    val structuredData by dictionaryViewModel.getStructuredDictionaryDataState(entry).collectAsState()
    val isLoading by dictionaryViewModel.getStructuredDictionaryDataLoading(entry).collectAsState()
    val scope = rememberCoroutineScope()

    // TODO: Move `LocalDictionaryAccess.parseWordInfo` to ViewModel.
    // It creates `localInfo` which is derived data, should be part of a UI State object.
    val localInfo = remember(entry.json) {
        try {
            LocalDictionaryAccess.parseWordInfo(entry)
        } catch (e: Exception) {
            @Suppress("HardCodedStringLiteral")
            Log.e("LocalDisplay", "Failed to parse LocalDictionaryWordInfo for ${entry.word}: ${e.message}")
            null
        }
    }

    val onWordClick: (String, String) -> Unit = { targetLangCode, targetWord ->
        val targetLang = allLanguages.firstOrNull { it.code.equals(targetLangCode, ignoreCase = true) }
        scope.launch {
            if (targetLang != null && dictionaryViewModel.hasWordInDictionary(targetWord, targetLang.code.lowercase())) {
                dictionaryViewModel.performSearch(
                    query = targetWord,
                    language = targetLang,
                    regenerate = false,
                    useDownloaded = true,
                    isDrillDown = true
                )
            } else {
                @Suppress("HardCodedStringLiteral")
                Log.d("LocalWordEntryDisplay", "Cannot navigate to word '$targetWord' - not available")
            }
        }
    }

    if (isLoading) {
        Box(modifier = Modifier.fillMaxWidth().padding(16.dp), contentAlignment = Alignment.Center) {
            CircularProgressIndicator(modifier = Modifier.size(24.dp), strokeWidth = 2.dp)
        }
    } else {
        structuredData?.let { data ->
            RichLocalEntryDisplay(
                word = entry.word,
                langCode = entry.langCode,
                pos = entry.pos,
                data = data,
                localInfo = localInfo,
                onWordClick = onWordClick,
                dictionaryViewModel = dictionaryViewModel,
                allLanguages = allLanguages,
                expandable = expandable
            )
        } ?: run {
            Column(modifier = Modifier.fillMaxWidth()) {
                Text(
                    text = stringResource(R.string.label_raw_data_2d),
                    style = MaterialTheme.typography.labelMedium,
                    color = MaterialTheme.colorScheme.error
                )
                SelectionContainer {
                    Text(text = formatJsonForDisplay(entry.json), style = MaterialTheme.typography.bodySmall)
                }
            }
        }
    }
}

