package com.rosetta.messenger.ui.chats.input

import java.util.Locale

data class EmojiWordMatch(
    val normalizedWord: String,
    val start: Int,
    val end: Int
)

object EmojiKeywordSuggester {

    private const val MIN_WORD_LENGTH = 2
    private const val MAX_WORD_LENGTH = 32

// test

    private val keywordToEmoji: Map<String, List<String>> =
        linkedMapOf(
            "спасибо" to listOf("🙏", "😊", "❤️", "🤝"),
            "спс" to listOf("🙏", "😊"),
            "благодарю" to listOf("🙏", "🤝"),
            "пожалуйста" to listOf("🙏", "🙂"),
            "привет" to listOf("👋", "🙂", "😊"),
            "здравствуйте" to listOf("👋", "🙂"),
            "пока" to listOf("👋", "🫡"),
            "доброеутро" to listOf("☀️", "🌤️", "🙂"),
            "добрыйдень" to listOf("☀️", "🙂"),
            "добрыйвечер" to listOf("🌇", "🙂"),
            "ок" to listOf("👌", "👍"),
            "хорошо" to listOf("👌", "👍", "✅"),
            "круто" to listOf("🔥", "😎", "🤘"),
            "класс" to listOf("🔥", "😎", "✨"),
            "да" to listOf("✅", "👍"),
            "нет" to listOf("❌", "🙅"),
            "люблю" to listOf("❤️", "🥰", "😘"),
            "любовь" to listOf("❤️", "😍", "🥰"),
            "скучаю" to listOf("🥺", "❤️"),
            "смешно" to listOf("😂", "🤣", "😄"),
            "лол" to listOf("😂", "🤣"),
            "печаль" to listOf("😢", "🥺", "💔"),
            "грустно" to listOf("😢", "🥺"),
            "злюсь" to listOf("😡", "🤬"),
            "злой" to listOf("😡", "🤬"),
            "sorry" to listOf("🙏", "😔"),
            "thanks" to listOf("🙏", "😊", "❤️"),
            "thankyou" to listOf("🙏", "😊"),
            "hello" to listOf("👋", "🙂", "😊"),
            "hi" to listOf("👋", "🙂"),
            "bye" to listOf("👋", "🫡"),
            "goodmorning" to listOf("☀️", "🌤️", "🙂"),
            "goodevening" to listOf("🌇", "🙂"),
            "okey" to listOf("👌", "👍"),
            "okay" to listOf("👌", "👍"),
            "yes" to listOf("✅", "👍"),
            "no" to listOf("❌", "🙅"),
            "love" to listOf("❤️", "🥰", "😍"),
            "missyou" to listOf("🥺", "❤️"),
            "funny" to listOf("😂", "🤣", "😄"),
            "sad" to listOf("😢", "🥺", "💔"),
            "angry" to listOf("😡", "🤬"),
            "spasibo" to listOf("🙏", "😊", "❤️"),
            "privet" to listOf("👋", "🙂", "😊"),
            "poka" to listOf("👋", "🫡"),
            "lyublyu" to listOf("❤️", "🥰", "😘")
        )

    fun findWordAtCursor(
        text: String,
        selectionStart: Int,
        selectionEnd: Int
    ): EmojiWordMatch? {
        if (selectionStart != selectionEnd) return null
        if (text.isEmpty()) return null

        val cursor = selectionEnd.coerceIn(0, text.length)
        var wordStart = cursor
        var wordEnd = cursor

        while (wordStart > 0 && isWordChar(text[wordStart - 1])) {
            wordStart--
        }
        while (wordEnd < text.length && isWordChar(text[wordEnd])) {
            wordEnd++
        }

        if (wordStart == wordEnd) return null

        val rawWord = text.substring(wordStart, wordEnd)
        val normalized = normalizeWord(rawWord)
        if (normalized.length !in MIN_WORD_LENGTH..MAX_WORD_LENGTH) return null

        return EmojiWordMatch(
            normalizedWord = normalized,
            start = wordStart,
            end = wordEnd
        )
    }

    fun suggest(match: EmojiWordMatch, maxCount: Int = 8): List<String> {
        if (maxCount <= 0) return emptyList()

        val exact = keywordToEmoji[match.normalizedWord].orEmpty()
        val prefix =
            keywordToEmoji
                .asSequence()
                .filter { (keyword, _) ->
                    keyword != match.normalizedWord && keyword.startsWith(match.normalizedWord)
                }
                .sortedBy { (keyword, _) -> keyword.length }
                .flatMap { (_, emoji) -> emoji.asSequence() }
                .toList()

        return buildList {
            val dedupe = LinkedHashSet<String>()
            (exact + prefix).forEach { emoji ->
                if (dedupe.add(emoji)) {
                    add(emoji)
                    if (size >= maxCount) return@buildList
                }
            }
        }
    }

    fun applySuggestion(
        text: String,
        selectionStart: Int,
        selectionEnd: Int,
        emoji: String
    ): String {
        val match = findWordAtCursor(text, selectionStart, selectionEnd) ?: return text
        val prefix = text.substring(0, match.start)
        val suffix = text.substring(match.end)

        val shouldAddSpace =
            suffix.isEmpty() || (!suffix.first().isWhitespace() && suffix.first() !in setOf(',', '.', '!', '?', ':', ';'))
        val trailing = if (shouldAddSpace) " " else ""

        return prefix + emoji + trailing + suffix
    }

    private fun isWordChar(char: Char): Boolean {
        return char.isLetterOrDigit() || char == '_'
    }

    private fun normalizeWord(word: String): String {
        return buildString(word.length) {
            word.forEach { char ->
                if (isWordChar(char)) append(char.lowercaseChar())
            }
        }.lowercase(Locale.ROOT)
    }
}
