package com.lazy.emulate.data

import android.content.Context
import android.content.SharedPreferences
import com.lazy.emulate.emulation.ConsoleType
import com.lazy.emulate.emulation.DisplayMode
import com.lazy.emulate.input.GamepadButton
import com.lazy.emulate.input.OverlayVisibility

class PreferencesManager(context: Context) {

    private val prefs: SharedPreferences =
        context.getSharedPreferences("emulate_prefs", Context.MODE_PRIVATE)

    var displayMode: DisplayMode
        get() = DisplayMode.entries.getOrElse(prefs.getInt(KEY_DISPLAY_MODE, 0)) { DisplayMode.STRETCH }
        set(value) = prefs.edit().putInt(KEY_DISPLAY_MODE, value.ordinal).apply()

    var overlayVisibility: OverlayVisibility
        get() = OverlayVisibility.entries.getOrElse(prefs.getInt(KEY_OVERLAY_VISIBILITY, 0)) { OverlayVisibility.AUTO }
        set(value) = prefs.edit().putInt(KEY_OVERLAY_VISIBILITY, value.ordinal).apply()

    fun getButtonMapping(consoleType: ConsoleType): Map<GamepadButton, Int> {
        val prefix = "${KEY_BUTTON_MAP_PREFIX}${consoleType.name}_"
        val result = mutableMapOf<GamepadButton, Int>()
        for (button in GamepadButton.entries) {
            val key = "$prefix${button.name}"
            if (prefs.contains(key)) {
                result[button] = prefs.getInt(key, -1)
            }
        }
        return result
    }

    fun setButtonMapping(consoleType: ConsoleType, button: GamepadButton, retroId: Int) {
        val key = "${KEY_BUTTON_MAP_PREFIX}${consoleType.name}_${button.name}"
        prefs.edit().putInt(key, retroId).apply()
    }

    fun clearButtonMappings(consoleType: ConsoleType) {
        val prefix = "${KEY_BUTTON_MAP_PREFIX}${consoleType.name}_"
        val editor = prefs.edit()
        for (button in GamepadButton.entries) {
            editor.remove("$prefix${button.name}")
        }
        editor.apply()
    }

    fun getControllerButtonRemap(): Map<GamepadButton, GamepadButton> {
        val result = mutableMapOf<GamepadButton, GamepadButton>()
        for (button in GamepadButton.entries) {
            val key = "${KEY_CONTROLLER_REMAP_PREFIX}${button.name}"
            if (prefs.contains(key)) {
                val targetName = prefs.getString(key, null)
                if (targetName != null) {
                    try {
                        result[button] = GamepadButton.valueOf(targetName)
                    } catch (_: IllegalArgumentException) {}
                }
            }
        }
        return result
    }

    fun setControllerButtonRemap(from: GamepadButton, to: GamepadButton) {
        prefs.edit().putString("${KEY_CONTROLLER_REMAP_PREFIX}${from.name}", to.name).apply()
    }

    fun clearControllerRemaps() {
        val editor = prefs.edit()
        for (button in GamepadButton.entries) {
            editor.remove("${KEY_CONTROLLER_REMAP_PREFIX}${button.name}")
        }
        editor.apply()
    }

    fun getFavorites(): Set<String> {
        return prefs.getStringSet(KEY_FAVORITES, emptySet()) ?: emptySet()
    }

    fun setFavorite(romPath: String, favorite: Boolean) {
        val favorites = getFavorites().toMutableSet()
        if (favorite) favorites.add(romPath) else favorites.remove(romPath)
        prefs.edit().putStringSet(KEY_FAVORITES, favorites).apply()
    }

    companion object {
        private const val KEY_DISPLAY_MODE = "display_mode"
        private const val KEY_OVERLAY_VISIBILITY = "overlay_visibility"
        private const val KEY_BUTTON_MAP_PREFIX = "button_map_"
        private const val KEY_CONTROLLER_REMAP_PREFIX = "controller_remap_"
        private const val KEY_FAVORITES = "favorite_roms"
    }
}
