package com.recordatorios.app

import android.content.Context
import android.content.SharedPreferences
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken

class CategoryManager private constructor(context: Context) {

    private var prefs: SharedPreferences =
        context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
    private val gson = Gson()
    private var securityManager: SecurityManager? = null

    private var categories: MutableList<Category> = mutableListOf()

    fun setSecurityManager(securityManager: SecurityManager) {
        this.securityManager = securityManager
        val json = getPrefs().getString(KEY_CATEGORIES, null)
        if (json != null) {
            val type = object : TypeToken<MutableList<Category>>() {}.type
            val loadedCategories = gson.fromJson<MutableList<Category>>(json, type)
            if (loadedCategories != null && loadedCategories.isNotEmpty()) {
                categories = loadedCategories
                return
            }
        }
        if (categories.isEmpty()) {
            createDefaults()
        }
    }

    fun reload() {
        val json = getPrefs().getString(KEY_CATEGORIES, null)
        if (json != null) {
            val type = object : TypeToken<MutableList<Category>>() {}.type
            categories = gson.fromJson(json, type) ?: mutableListOf()
        }
        if (categories.isEmpty()) {
            createDefaults()
        }
    }

    private fun getPrefs(): SharedPreferences {
        return securityManager?.getEncryptedPrefs() ?: prefs
    }

    init {
        loadCategories()
        if (categories.isEmpty()) {
            createDefaults()
        }
    }

    private fun createDefaults() {
        val defaults = listOf(
            Category(name = "Personal", color = 0xFF2196F3.toInt()),
            Category(name = "Trabajo", color = 0xFFFF9800.toInt()),
            Category(name = "Estudio", color = 0xFF4CAF50.toInt()),
            Category(name = "Salud", color = 0xFFF44336.toInt()),
            Category(name = "Finanzas", color = 0xFF9C27B0.toInt()),
            Category(name = "Otros", color = 0xFF607D8B.toInt()),
        )
        categories.addAll(defaults)
        saveCategories()
    }

    private fun loadCategories() {
        val json = getPrefs().getString(KEY_CATEGORIES, null) ?: return
        val type = object : TypeToken<MutableList<Category>>() {}.type
        categories = gson.fromJson(json, type) ?: mutableListOf()
    }

    private fun saveCategories() {
        getPrefs().edit().putString(KEY_CATEGORIES, gson.toJson(categories)).apply()
    }

    fun getAllCategories(): List<Category> = categories.toList()

    fun getCategory(id: String): Category? = categories.find { it.id == id }

    fun addCategory(category: Category) {
        categories.add(category)
        saveCategories()
    }

    fun updateCategory(id: String, name: String, color: Int) {
        val cat = categories.find { it.id == id } ?: return
        cat.name = name
        cat.color = color
        saveCategories()
    }

    fun deleteCategory(id: String) {
        categories.removeAll { it.id == id }
        saveCategories()
    }

    fun getNoneCategoryId(): String? = categories.find { it.name == "Sin categoría" }?.id

    fun exportToJson(): String {
        return gson.toJson(categories)
    }

    fun importFromJson(json: String, merge: Boolean = true) {
        val type = object : TypeToken<List<Category>>() {}.type
        val importedCategories = gson.fromJson<List<Category>>(json, type) ?: return
        if (importedCategories.isEmpty()) return
        
        if (!merge) {
            categories.clear()
            categories.addAll(importedCategories)
        } else {
            for (category in importedCategories) {
                val existing = categories.indexOfFirst { it.id == category.id || it.name.equals(category.name, ignoreCase = true) }
                if (existing != -1) {
                    categories[existing] = category.copy(id = categories[existing].id)
                } else {
                    categories.add(category)
                }
            }
        }
        saveCategories()
    }

    companion object {
        private const val PREFS_NAME = "categories_prefs"
        private const val KEY_CATEGORIES = "categories"

        @Volatile
        private var instance: CategoryManager? = null

        fun getInstance(context: Context): CategoryManager {
            return instance ?: synchronized(this) {
                instance ?: CategoryManager(context.applicationContext).also { instance = it }
            }
        }
    }
}
