package com.aletheia.app.ui.reader.tts

import java.util.Locale

internal object RussianSpeechTextSplitter {
    fun splitSentences(text: String): List<String> {
        val result = mutableListOf<String>()
        var start = 0
        var index = 0
        while (index < text.length) {
            val char = text[index]
            val isEllipsis = char == '…' || text.startsWith("...", index)
            val isTerminal = when {
                char == '!' || char == '?' || isEllipsis -> true
                char == '.' -> isSentencePeriod(text, index)
                else -> false
            }
            if (!isTerminal) {
                index += 1
                continue
            }
            if (text.startsWith("...", index)) index += 2
            var end = index + 1
            while (end < text.length && text[end] in SENTENCE_CLOSERS) end += 1
            val hasSentenceBoundary = end == text.length || text[end].isWhitespace()
            if (hasSentenceBoundary && !isFollowedByDialogueDash(text, end)) {
                val sentence = text.substring(start, end).trim()
                if (sentence.isNotBlank()) result += sentence
                start = end
                while (start < text.length && text[start].isWhitespace()) start += 1
                index = start
            } else {
                index = end
            }
        }
        val remainder = text.substring(start).trim()
        if (remainder.isNotBlank()) result += remainder
        return result
    }

    private fun isFollowedByDialogueDash(text: String, end: Int): Boolean {
        var index = end
        while (index < text.length && text[index].isWhitespace()) index += 1
        return text.getOrNull(index) in DIALOGUE_DASHES
    }

    private fun isSentencePeriod(text: String, index: Int): Boolean {
        if (text.getOrNull(index - 1)?.isDigit() == true && text.getOrNull(index + 1)?.isDigit() == true) return false
        val prefix = text.substring(0, index)
        val token = prefix.takeLastWhile { it.isLetter() }.lowercase(Locale.forLanguageTag("ru"))
        if (token in NON_TERMINAL_ABBREVIATIONS) return false
        if (token.length == 1 && prefix.lastOrNull()?.isUpperCase() == true) return false
        return true
    }

    private val SENTENCE_CLOSERS = setOf('"', '\'', '»', '”', ')')
    private val DIALOGUE_DASHES = setOf('—', '–', '-')
    private val NON_TERMINAL_ABBREVIATIONS = setOf(
        "г", "гг", "ул", "стр", "рис", "им", "т", "д", "п", "н", "э", "е", "к",
        "др", "см", "руб", "коп", "тыс", "млн", "млрд"
    )
}
