package net.sergeych.toread

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import net.sergeych.toread.storage.BookReadingStatus
import kotlin.math.roundToInt

internal enum class AppLanguage(val localeTag: String) {
    English("en"),
    Russian("ru"),
}

internal val availableAppLanguages: List<AppLanguage> = AppLanguage.entries

internal var selectedAppLocaleTag: String? by mutableStateOf(null)

internal val appLanguage: AppLanguage
    get() = if (effectiveAppLocaleTags().any { it.isRussianLanguageTag() }) {
        AppLanguage.Russian
    } else {
        AppLanguage.English
    }

internal val strings: AppStrings
    get() = when (appLanguage) {
        AppLanguage.English -> EnglishStrings
        AppLanguage.Russian -> RussianStrings
    }

internal expect fun platformLocaleTags(): List<String>

private fun effectiveAppLocaleTags(): List<String> =
    selectedAppLocaleTag?.let(::listOf) ?: platformLocaleTags()

private fun String.isRussianLanguageTag(): Boolean =
    substringBefore('-').substringBefore('_').equals("ru", ignoreCase = true)

internal open class AppStrings {
    open val appName = "To Read"
    open val loadingOpeningBook = "Opening book"
    open val scanning = "Scanning..."
    open val scanningDownloads = "Scanning Downloads..."
    open val undo = "Undo"
    open val retry = "Retry"
    open val done = "Done"
    open val cancel = "Cancel"

    open val libraryError = "Library error"
    open val couldNotOpenLibrary = "Could not open library."
    open val couldNotLoadLibrary = "Could not load library."
    open val couldNotOpenBook = "Could not open book."
    open val couldNotUpdateBook = "Could not update book."
    open val bookFileNotAvailable = "Book file is not available."
    open val scanFailed = "Scan failed."
    open val searchFailed = "Search failed."
    open val libraryRescanFailed = "Library rescan failed."
    open val rescanningLibrary = "Rescanning library..."

    open val theme = "Theme"
    open val themeLight = "Light"
    open val themeDark = "Dark"
    open val themeSystem = "System"

    open val libraryOptions = "Library options"
    open val scanDownloadsAutomatically = "Scan Downloads automatically"
    open val locale = "Locale"
    open val systemLocale = "Default"
    open fun appVersion(version: String): String = "Version $version"
    open val scanFolder = "Scan folder"
    open val chooseLibraryFilter = "Choose library filter"
    open val searchLibrary = "Search library"
    open val closeSearch = "Close search"
    open val clearSearch = "Clear search"
    open val noMatches = "No matches"
    open val scanFolderOrChooseFilter = "Scan a folder or choose another library filter."
    open val favorite = "Favorite"
    open val unknownAuthor = "Unknown author"
    open val noMetadata = "No metadata"
    open val lastReadPrefix = "Last read"
    open val open = "Open"
    open val markAsRead = "Mark as read"
    open val markAsUnread = "Mark as unread"
    open val markToRead = "Mark to read"
    open val removeToRead = "Remove to read"
    open val removeMarks = "Remove marks"
    open val notInterested = "Not interested"
    open val clearMarks = "Clear marks"
    open val addFavorite = "Add favorite"
    open val removeFavorite = "Remove favorite"
    open val delete = "Delete"

    open val filterReadingNow = "Reading now"
    open val filterRecentlyAdded = "Recently added"
    open val filterMyLibrary = "My library"
    open val filterToRead = "To read"
    open val filterRead = "Read"

    open val scan = "Scan"
    open val rootFolder = "Root folder"
    open val choose = "Choose"
    open val logPrefix = "Log"

    open val bookInfo = "Book info"
    open val back = "Back"
    open val backToLibrary = "Back to library"
    open val backToReader = "Back to reader"
    open val titleInfo = "Title Info"
    open val title = "Title"
    open val authors = "Authors"
    open val language = "Language"
    open val date = "Date"
    open val genres = "Genres"
    open val source = "Source"
    open val translator = "Translator"
    open val notSpecified = "Not specified"
    open val statistics = "Statistics"
    open val words = "Words"
    open val sections = "Sections"
    open val images = "Images"
    open val sourceFile = "Source file"
    open val fileName = "File name"
    open val filePath = "Path"
    open val lastReadingPosition = "Last Reading Position"
    open val noSavedPosition = "No saved position"
    open val listItem = "List item"
    open val scrollOffset = "Scroll offset"
    open val bookmarks = "Bookmarks"
    open val bookmark = "Bookmark"
    open val noBookmarks = "No bookmarks"
    open val notes = "Notes"
    open val noNotes = "No notes"
    open val loading = "Loading..."
    open val noImage = "No image"

    open val readerTheme = "Theme"
    open val tableOfContents = "Contents"
    open val backToLastPosition = "Back"
    open val readAloud = "Read aloud"
    open val readerMenu = "Book reader menu"
    open val info = "Info..."
    open val readerSettings = "Settings"
    open val fullScreen = "Full screen"
    open val readerFontSizeIncrease = "Increase font size"
    open val readerFontSizeDecrease = "Decrease font size"
    open val readerLineHeightIncrease = "Increase line spacing"
    open val readerLineHeightDecrease = "Decrease line spacing"
    open val readerFontWeightIncrease = "Increase font weight"
    open val readerFontWeightDecrease = "Decrease font weight"
    open val resetReaderFontSettings = "Reset font settings"
    open val revertColorScheme = "Revert color scheme"
    open val readerBackgroundColor = "Reader background color"
    open val readerTextColor = "Reader text color"
    open val extraReaderSettings = "Extra reader settings"
    open val customColor = "Custom color"
    open val red = "R"
    open val green = "G"
    open val blue = "B"
    open val readerColors = "Colors"
    open val readerTypography = "Typography"
    open val readerLayout = "Layout"
    open val readerNavigation = "Navigation"
    open val readerProgress = "Progress"
    open val closeReaderSettings = "Close reader settings"
    open val share = "Share"
    open val viewFile = "View file"
    open val previousSentence = "Previous sentence"
    open val stopReading = "Stop reading"
    open val startReading = "Start reading"
    open val nextSentence = "Next sentence"
    open val readAloudSettings = "Read aloud settings"
    open val ttsEngine = "TTS engine"
    open val systemDefault = "System default"
    open val offlineVoice = "Offline voice"
    open val autoRussian = "Auto Russian"
    open val loadingVoices = "Loading voices..."

    open val imageCopied = "Image copied"
    open val copyFailed = "Copy failed"
    open val zoomIn = "Zoom in"
    open val zoomOut = "Zoom out"
    open val copyImage = "Copy image"

    open val chooseLibraryFolder = "Choose library folder"
    open val downloads = "Downloads"
    open val otherFolder = "Other folder..."
    open val play = "Play"
    open val stop = "Stop"
    open val previous = "Previous"
    open val next = "Next"
    open val readingInBackground = "Reading in the background"
    open val shareBook = "Share book"
    open val couldNotLoadAndroidTtsEngines = "Could not load Android TTS engines."
    open val couldNotLoadSelectedTtsVoices = "Could not load voices for the selected TTS engine."
    open val noOfflineVoices = "No offline voices reported by the selected TTS engine."

    open fun themeChanged(mode: ThemeMode): String = "$theme: ${mode.localizedName()}"
    open fun removed(title: String): String = "Removed $title."
    open fun restored(title: String): String = "Restored $title."
    open fun couldNotRemove(title: String): String = "Could not remove $title."
    open fun couldNotOpen(displayName: String): String = "Could not open $displayName."
    open fun couldNotReopenLastBook(): String = "Could not reopen last book."
    open fun scanReport(scanned: Int, imported: Int, skipped: Int, failed: Int): String =
        "Scanned $scanned, imported $imported, skipped $skipped, failed $failed."
    open val noNewBooksFound = "Nothing new has been found."
    open val show = "Show"
    open fun newBooksAdded(count: Int): String =
        if (count == 1) "1 new book added." else "$count new books added."
    open fun rescanReport(scanned: Int, updated: Int, failed: Int): String =
        "Rescanned $scanned, updated $updated, failed $failed."
    open fun checkingFile(currentFile: String?, scanned: Int, imported: Int, skipped: Int, failed: Int): String =
        buildString {
            append("Checking")
            currentFile?.takeIf(String::isNotBlank)?.let { append(" $it") }
            append(". Found $scanned supported files")
            append(", imported $imported")
            append(", skipped $skipped")
            append(", failed $failed.")
        }
    open fun importedSkippedFailed(imported: Int, skipped: Int, failed: Int): String =
        "Imported $imported, skipped $skipped, failed $failed"
    open fun scannedBooks(scanned: Int): String = "Scanned $scanned books"
    open fun scannedProgress(scanned: Int, total: Int, percent: Int): String =
        "Scanned $scanned of $total, $percent% done"
    open fun noBooksIn(filterLabel: String): String = "No books in ${filterLabel.lowercase()}"
    open fun bookMenuFor(title: String): String = "Book menu for $title"
    open fun markedAsRead(title: String? = null): String = title?.let { "Marked $it as read." } ?: "Marked as read."
    open fun markedAsUnread(title: String): String = "Marked $title as unread."
    open fun markedToRead(title: String? = null): String = title?.let { "Marked $it to read." } ?: "Marked to read."
    open fun markedNotInterested(title: String? = null): String =
        title?.let { "Marked $it as not interested." } ?: "Marked as not interested."
    open fun removedMarks(title: String? = null): String = title?.let { "Removed marks from $it." } ?: "Cleared marks."
    open fun addedToFavorites(title: String? = null): String =
        title?.let { "Added $it to favorites." } ?: "Added to favorites."
    open fun removedFromFavorites(title: String? = null): String =
        title?.let { "Removed $it from favorites." } ?: "Removed from favorites."
    open fun couldNotUpdate(title: String): String = "Could not update $title."
    open fun shareOpened(): String = "Share opened."
    open fun couldNotShareBook(): String = "Could not share book."
    open fun openedFileLocation(): String = "Opened file location."
    open fun couldNotOpenFileLocation(): String = "Could not open file location."
    open fun allFilesAccessRequired(path: String): String = "All files access is required to scan $path."
    open fun couldNotRead(name: String): String = "Could not read $name"
    open fun progressLabel(progress: Double?): String =
        progress?.let { "Progress ${(it * 100).roundToInt()}%" } ?: "Progress not recorded"
    open fun appLanguageName(language: AppLanguage): String =
        when (language) {
            AppLanguage.English -> "English"
            AppLanguage.Russian -> "Russian"
        }
    open fun sectionFallback(index: Int): String = "Section ${index + 1}"
    open fun readingStatus(status: BookReadingStatus): String =
        when (status) {
            BookReadingStatus.NEW -> "New"
            BookReadingStatus.TO_READ -> "To read"
            BookReadingStatus.READING -> "Reading"
            BookReadingStatus.READ -> "Read"
            BookReadingStatus.NOT_INTERESTED -> "Not interested"
        }
}

internal object EnglishStrings : AppStrings()

internal object RussianStrings : AppStrings() {
    override val appName = "Читать"
    override val loadingOpeningBook = "Открываем книгу"
    override val scanning = "Сканируем..."
    override val scanningDownloads = "Сканируем Загрузки..."
    override val undo = "Отменить"
    override val retry = "Повторить"
    override val done = "Готово"
    override val cancel = "Отмена"

    override val libraryError = "Ошибка библиотеки"
    override val couldNotOpenLibrary = "Не удалось открыть библиотеку."
    override val couldNotLoadLibrary = "Не удалось загрузить библиотеку."
    override val couldNotOpenBook = "Не удалось открыть книгу."
    override val couldNotUpdateBook = "Не удалось обновить книгу."
    override val bookFileNotAvailable = "Файл книги недоступен."
    override val scanFailed = "Импорт не удался."
    override val searchFailed = "Поиск не удался."
    override val libraryRescanFailed = "Повторное сканирование библиотеки не удалось."
    override val rescanningLibrary = "Пересканируем библиотеку..."

    override val theme = "Тема"
    override val themeLight = "светлая"
    override val themeDark = "темная"
    override val themeSystem = "системная"

    override val libraryOptions = "Параметры библиотеки"
    override val scanDownloadsAutomatically = "Автоматически сканировать Загрузки"
    override val locale = "Локализация"
    override val systemLocale = "Системная"
    override fun appVersion(version: String): String = "Версия $version"
    override val scanFolder = "Сканировать папку"
    override val chooseLibraryFilter = "Выбрать фильтр библиотеки"
    override val searchLibrary = "Поиск"
    override val closeSearch = "Закрыть поиск"
    override val clearSearch = "Очистить поиск"
    override val noMatches = "Ничего не найдено"
    override val scanFolderOrChooseFilter = "Импортируйте папку или выберите другой фильтр библиотеки."
    override val favorite = "Избранное"
    override val unknownAuthor = "Автор неизвестен"
    override val noMetadata = "Нет метаданных"
    override val lastReadPrefix = "Читали"
    override val open = "Открыть"
    override val markAsRead = "Отметить прочитанной"
    override val markAsUnread = "Отметить непрочитанной"
    override val markToRead = "Отложить к чтению"
    override val removeToRead = "Убрать из отложенного"
    override val removeMarks = "Снять отметки"
    override val notInterested = "Не интересно"
    override val clearMarks = "Очистить отметки"
    override val addFavorite = "Добавить в избранное"
    override val removeFavorite = "Убрать из избранного"
    override val delete = "Удалить"

    override val filterReadingNow = "Сейчас читаю"
    override val filterRecentlyAdded = "Недавно добавленные"
    override val filterMyLibrary = "Моя библиотека"
    override val filterToRead = "К чтению"
    override val filterRead = "Прочитанные"

    override val scan = "Импорт"
    override val rootFolder = "Корневая папка"
    override val choose = "Выбрать"
    override val logPrefix = "Лог"

    override val bookInfo = "Информация о книге"
    override val back = "Назад"
    override val backToLibrary = "Вернуться в библиотеку"
    override val backToReader = "Вернуться к чтению"
    override val titleInfo = "Описание"
    override val title = "Название"
    override val authors = "Авторы"
    override val language = "Язык"
    override val date = "Дата"
    override val genres = "Жанры"
    override val source = "Исходный язык"
    override val translator = "Переводчик"
    override val notSpecified = "Не указано"
    override val statistics = "Статистика"
    override val words = "Слова"
    override val sections = "Разделы"
    override val images = "Иллюстрации"
    override val sourceFile = "Исходный файл"
    override val fileName = "Имя файла"
    override val filePath = "Путь"
    override val lastReadingPosition = "Последняя позиция чтения"
    override val noSavedPosition = "Позиция не сохранена"
    override val listItem = "Элемент списка"
    override val scrollOffset = "Смещение прокрутки"
    override val bookmarks = "Закладки"
    override val bookmark = "Закладка"
    override val noBookmarks = "Закладок нет"
    override val notes = "Заметки"
    override val noNotes = "Заметок нет"
    override val loading = "Загрузка..."
    override val noImage = "Нет изображения"

    override val readerTheme = "Тема"
    override val tableOfContents = "Содержание"
    override val backToLastPosition = "Назад"
    override val readAloud = "Читать вслух"
    override val readerMenu = "Меню чтения"
    override val info = "Информация..."
    override val readerSettings = "Настройки"
    override val fullScreen = "На весь экран"
    override val readerFontSizeIncrease = "Увеличить шрифт"
    override val readerFontSizeDecrease = "Уменьшить шрифт"
    override val readerLineHeightIncrease = "Увеличить межстрочный интервал"
    override val readerLineHeightDecrease = "Уменьшить межстрочный интервал"
    override val readerFontWeightIncrease = "Увеличить насыщенность шрифта"
    override val readerFontWeightDecrease = "Уменьшить насыщенность шрифта"
    override val resetReaderFontSettings = "Сбросить настройки шрифта"
    override val revertColorScheme = "Вернуть цветовую схему"
    override val readerBackgroundColor = "Цвет фона чтения"
    override val readerTextColor = "Цвет текста чтения"
    override val extraReaderSettings = "Дополнительные настройки"
    override val customColor = "Свой цвет"
    override val red = "К"
    override val green = "З"
    override val blue = "С"
    override val readerColors = "Цвета"
    override val readerTypography = "Типографика"
    override val readerLayout = "Макет"
    override val readerNavigation = "Навигация"
    override val readerProgress = "Прогресс"
    override val closeReaderSettings = "Закрыть настройки чтения"
    override val share = "Поделиться"
    override val viewFile = "Показать файл"
    override val previousSentence = "Предыдущее предложение"
    override val stopReading = "Остановить чтение"
    override val startReading = "Начать чтение"
    override val nextSentence = "Следующее предложение"
    override val readAloudSettings = "Настройки чтения вслух"
    override val ttsEngine = "Движок TTS"
    override val systemDefault = "Системный по умолчанию"
    override val offlineVoice = "Офлайн-голос"
    override val autoRussian = "Авто: русский"
    override val loadingVoices = "Загружаем голоса..."

    override val imageCopied = "Изображение скопировано"
    override val copyFailed = "Не удалось скопировать"
    override val zoomIn = "Увеличить"
    override val zoomOut = "Уменьшить"
    override val copyImage = "Скопировать изображение"

    override val chooseLibraryFolder = "Выберите папку библиотеки"
    override val downloads = "Загрузки"
    override val otherFolder = "Другая папка..."
    override val play = "Пуск"
    override val stop = "Стоп"
    override val previous = "Назад"
    override val next = "Вперед"
    override val readingInBackground = "Чтение в фоне"
    override val shareBook = "Поделиться книгой"
    override val couldNotLoadAndroidTtsEngines = "Не удалось загрузить Android TTS-движки."
    override val couldNotLoadSelectedTtsVoices = "Не удалось загрузить голоса для выбранного TTS-движка."
    override val noOfflineVoices = "Выбранный TTS-движок не сообщил об офлайн-голосах."

    override fun themeChanged(mode: ThemeMode): String = "$theme: ${mode.localizedName()}"
    override fun removed(title: String): String = "Удалено: $title."
    override fun restored(title: String): String = "Восстановлено: $title."
    override fun couldNotRemove(title: String): String = "Не удалось удалить: $title."
    override fun couldNotOpen(displayName: String): String = "Не удалось открыть $displayName."
    override fun couldNotReopenLastBook(): String = "Не удалось открыть последнюю книгу."
    override fun scanReport(scanned: Int, imported: Int, skipped: Int, failed: Int): String =
        "Проверено: $scanned, импортировано: $imported, пропущено: $skipped, ошибок: $failed."
    override val noNewBooksFound = "Ничего нового не найдено."
    override val show = "Показать"
    override fun newBooksAdded(count: Int): String =
        when {
            count % 10 == 1 && count % 100 != 11 -> "$count новая книга добавлена."
            count % 10 in 2..4 && count % 100 !in 12..14 -> "$count новые книги добавлены."
            else -> "$count новых книг добавлено."
        }
    override fun rescanReport(scanned: Int, updated: Int, failed: Int): String =
        "Пересканировано: $scanned, обновлено: $updated, ошибок: $failed."
    override fun checkingFile(currentFile: String?, scanned: Int, imported: Int, skipped: Int, failed: Int): String =
        buildString {
            append("Проверяем")
            currentFile?.takeIf(String::isNotBlank)?.let { append(" $it") }
            append(". Найдено поддерживаемых файлов: $scanned")
            append(", импортировано: $imported")
            append(", пропущено: $skipped")
            append(", ошибок: $failed.")
        }
    override fun importedSkippedFailed(imported: Int, skipped: Int, failed: Int): String =
        "Импортировано: $imported, пропущено: $skipped, ошибок: $failed"
    override fun scannedBooks(scanned: Int): String = "Импортировано книг: $scanned"
    override fun scannedProgress(scanned: Int, total: Int, percent: Int): String =
        "Импорт: $scanned из $total, готово $percent%"
    override fun noBooksIn(filterLabel: String): String = "Нет книг: ${filterLabel.lowercase()}"
    override fun bookMenuFor(title: String): String = "Меню книги: $title"
    override fun markedAsRead(title: String?): String =
        title?.let { "Отмечено как прочитанное: $it." } ?: "Отмечено как прочитанное."
    override fun markedAsUnread(title: String): String = "Отмечено как непрочитанное: $title."
    override fun markedToRead(title: String?): String =
        title?.let { "Отложено к чтению: $it." } ?: "Отложено к чтению."
    override fun markedNotInterested(title: String?): String =
        title?.let { "Отмечено как неинтересное: $it." } ?: "Отмечено как неинтересное."
    override fun removedMarks(title: String?): String =
        title?.let { "Сняты отметки: $it." } ?: "Отметки сняты."
    override fun addedToFavorites(title: String?): String =
        title?.let { "Добавлено в избранное: $it." } ?: "Добавлено в избранное."
    override fun removedFromFavorites(title: String?): String =
        title?.let { "Убрано из избранного: $it." } ?: "Убрано из избранного."
    override fun couldNotUpdate(title: String): String = "Не удалось обновить: $title."
    override fun shareOpened(): String = "Открыто окно отправки."
    override fun couldNotShareBook(): String = "Не удалось поделиться книгой."
    override fun openedFileLocation(): String = "Расположение файла открыто."
    override fun couldNotOpenFileLocation(): String = "Не удалось открыть расположение файла."
    override fun allFilesAccessRequired(path: String): String = "Для сканирования $path нужен доступ ко всем файлам."
    override fun couldNotRead(name: String): String = "Не удалось прочитать $name"
    override fun progressLabel(progress: Double?): String =
        progress?.let { "Прогресс ${(it * 100).roundToInt()}%" } ?: "Прогресс не записан"
    override fun appLanguageName(language: AppLanguage): String =
        when (language) {
            AppLanguage.English -> "Английский"
            AppLanguage.Russian -> "Русский"
        }
    override fun sectionFallback(index: Int): String = "Раздел ${index + 1}"
    override fun readingStatus(status: BookReadingStatus): String =
        when (status) {
            BookReadingStatus.NEW -> "Новая"
            BookReadingStatus.TO_READ -> "К чтению"
            BookReadingStatus.READING -> "Читаю"
            BookReadingStatus.READ -> "Прочитана"
            BookReadingStatus.NOT_INTERESTED -> "Не интересно"
        }
}

internal fun ThemeMode.localizedName(): String =
    when (this) {
        ThemeMode.LIGHT -> strings.themeLight
        ThemeMode.DARK -> strings.themeDark
        ThemeMode.SYSTEM -> strings.themeSystem
    }
