package com.pixelized.desktop.lwa.ui.screen.settings

import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingNumberItemUio
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingSectionUio
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingToggleItemUio
import com.pixelized.desktop.lwa.usecase.SettingsUseCase
import kotlinx.coroutines.launch
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.ic_fan_focus_24dp
import lwacharactersheet.composeapp.generated.resources.ic_format_list_numbered_24dp
import lwacharactersheet.composeapp.generated.resources.ic_ifl_24dp
import lwacharactersheet.composeapp.generated.resources.ic_timer_24dp
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_scroll_description
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_scroll_title
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__line_count_description
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__line_count_title
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__section
import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__dyn_dice_delay_description
import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__dyn_dice_delay_tile
import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__dyn_dice_description
import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__dyn_dice_tile
import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__section


class SettingsViewModel(
    private val settingsRepository: SettingsRepository,
    private val settingsUseCase: SettingsUseCase,
) : ViewModel() {
    private val settings = settingsRepository.settingsFlow()
    private val booleanStates = hashMapOf<String, MutableState<Boolean>>()
    private val intStates = hashMapOf<String, MutableState<Int>>()

    val items = listOf(
        SettingSectionUio(
            title = Res.string.settings__player_portrait__section,
        ),
        SettingToggleItemUio(
            icon = Res.drawable.ic_ifl_24dp,
            title = Res.string.settings__player_portrait__dyn_dice_tile,
            description = Res.string.settings__player_portrait__dyn_dice_description,
            checked = booleanStates.dynamicDice,
            onToggle = {
                settingsRepository.update(
                    settings = settings.value.copy(
                        portrait = settings.value.portrait.copy(dynamicDice = it)
                    )
                )
            },
        ),
        SettingNumberItemUio(
            icon = Res.drawable.ic_timer_24dp,
            title = Res.string.settings__player_portrait__dyn_dice_delay_tile,
            description = Res.string.settings__player_portrait__dyn_dice_delay_description,
            enable = booleanStates.dynamicDice,
            value = intStates.dynamicDiceDelay,
            onValueChange = {
                val range = 1000..99999
                if (it < range.first) {
                    settingsRepository.update(
                        settings = settings.value.copy(
                            portrait = settings.value.portrait.copy(dynamicDiceDelay = range.first)
                        )
                    )
                } else if (it in range) {
                    settingsRepository.update(
                        settings = settings.value.copy(
                            portrait = settings.value.portrait.copy(dynamicDiceDelay = it)
                        )
                    )
                } else {
                    settingsRepository.update(
                        settings = settings.value.copy(
                            portrait = settings.value.portrait.copy(dynamicDiceDelay = range.last)
                        )
                    )
                }
            }
        ),
        SettingSectionUio(
            title = Res.string.settings__chat_log__section,
        ),
        SettingToggleItemUio(
            icon = Res.drawable.ic_fan_focus_24dp,
            title = Res.string.settings__chat_log__auto_scroll_title,
            description = Res.string.settings__chat_log__auto_scroll_description,
            checked = booleanStates.autoScrollChat,
            onToggle = {
                settingsRepository.update(
                    settings = settings.value.copy(
                        chat = settings.value.chat.copy(autoScrollChat = it)
                    )
                )
            },
        ),
        SettingNumberItemUio(
            icon = Res.drawable.ic_format_list_numbered_24dp,
            title = Res.string.settings__chat_log__line_count_title,
            description = Res.string.settings__chat_log__line_count_description,
            enable = mutableStateOf(true),
            value = intStates.maxLineCount,
            onValueChange = {
                if (it in 0..999) {
                    settingsRepository.update(
                        settings = settings.value.copy(
                            chat = settings.value.chat.copy(maxLineCount = it)
                        )
                    )
                }
            }
        ),
    )

    init {
        viewModelScope.launch {
            settingsRepository.settingsFlow().collect { settings ->
                booleanStates.dynamicDice.value = settings.portrait.dynamicDice
                intStates.dynamicDiceDelay.value = settings.portrait.dynamicDiceDelay
                booleanStates.autoScrollChat.value = settings.chat.autoScrollChat
                intStates.maxLineCount.value = settings.chat.maxLineCount
            }
        }
    }

    /**
     * Reset the current settings except the player name.
     */
    fun onReset() {
        val current = settingsRepository.settings()
        settingsRepository.update(
            settings = settingsUseCase.defaultSettings().copy(
                playerName = current.playerName,
            )
        )
    }

    private val HashMap<String, MutableState<Boolean>>.dynamicDice
        get() = getOrPut("DYNAMIC_DICE") { mutableStateOf(settings.value.portrait.dynamicDice) }

    private val HashMap<String, MutableState<Int>>.dynamicDiceDelay
        get() = getOrPut("DYNAMIC_DICE_DELAY") { mutableStateOf(settings.value.portrait.dynamicDiceDelay) }

    private val HashMap<String, MutableState<Boolean>>.autoScrollChat
        get() = getOrPut("AUTO_SCROLL_CHAT") { mutableStateOf(settings.value.chat.autoScrollChat) }

    private val HashMap<String, MutableState<Int>>.maxLineCount
        get() = getOrPut("MAX_LINE_COUNT") { mutableStateOf(settings.value.chat.maxLineCount) }
}