package com.pixelmintdrop.ui

import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import android.widget.GridLayout
import android.widget.TextView
import androidx.cardview.widget.CardView
import com.pixelmintdrop.R
import com.pixelmintdrop.model.PlayerProgressionManager
import android.graphics.drawable.GradientDrawable
import android.util.Log

/**
 * UI component for selecting game themes
 */
class ThemeSelector @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    private val themesGrid: GridLayout
    private val availableThemesLabel: TextView
    
    // Callback when a theme is selected
    var onThemeSelected: ((String) -> Unit)? = null
    
    // Currently selected theme (persisted)
    private var selectedTheme: String = PlayerProgressionManager.THEME_CLASSIC
    
    // Theme cards map (themeId -> CardView)
    private val themeCards = mutableMapOf<String, CardView>()
    // Ordered list of theme IDs for navigation
    private val themeIdList = mutableListOf<String>() 
    // Currently focused theme ID (for gamepad navigation within the selector)
    private var focusedThemeId: String? = null
    // Index of the currently focused theme in themeIdList
    private var focusedIndex: Int = -1
    // Flag indicating if the entire selector component has focus from the main menu
    private var hasComponentFocus: Boolean = false
    
    init {
        // Inflate the layout
        LayoutInflater.from(context).inflate(R.layout.theme_selector, this, true)
        
        // Get references to views
        themesGrid = findViewById(R.id.themes_grid)
        availableThemesLabel = findViewById(R.id.available_themes_label)
    }
    
    /**
     * Update the theme selector with unlocked themes
     */
    fun updateThemes(unlockedThemes: Set<String>, currentTheme: String) {
        // Clear existing theme cards and ID list
        themesGrid.removeAllViews()
        themeCards.clear()
        themeIdList.clear()
        
        // Update selected theme
        selectedTheme = currentTheme
        focusedThemeId = currentTheme // Initially focus the selected theme
        focusedIndex = -1 // Reset index
        
        // Get all possible themes and their details, sorted for consistent order
        val allThemes = getThemes().entries.sortedWith(compareBy({ it.value.unlockLevel }, { it.value.displayName })).associate { it.key to it.value }
        
        // Add theme cards to the grid and build the ID list
        allThemes.forEach { (themeId, themeInfo) ->
            val isUnlocked = unlockedThemes.contains(themeId)
            val isSelected = themeId == selectedTheme
            
            // Only add unlocked themes to the navigable list
            if (isUnlocked) {
                themeIdList.add(themeId)
            }

            val themeCard = createThemeCard(themeId, themeInfo, isUnlocked, isSelected)
            themeCards[themeId] = themeCard
            themesGrid.addView(themeCard)

            // Update focused index if this is the currently selected/focused theme
            if (isUnlocked && themeId == focusedThemeId) {
                 focusedIndex = themeIdList.indexOf(themeId)
            }
        }
        
        // Ensure focus index is valid if the previously focused theme is no longer available/unlocked
        if (focusedIndex == -1 && themeIdList.isNotEmpty()) {
            focusedIndex = 0
            focusedThemeId = themeIdList[0]
        }

        // Apply initial focus highlight if the component has focus
        highlightFocusedCard()
    }
    
    /**
     * Create a card for a theme
     */
    private fun createThemeCard(
        themeId: String,
        themeInfo: ThemeInfo,
        isUnlocked: Boolean,
        isSelected: Boolean
    ): CardView {
        // Create the card
        val card = CardView(context).apply {
            id = View.generateViewId()
            radius = 12f
            cardElevation = if (isSelected) 8f else 2f
            useCompatPadding = true
            
            // Set card background color based on theme
            setCardBackgroundColor(themeInfo.primaryColor)
            
            // Set card dimensions
            val cardSize = resources.getDimensionPixelSize(R.dimen.theme_card_size)
            layoutParams = GridLayout.LayoutParams().apply {
                width = cardSize
                height = cardSize
                columnSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f)
                rowSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f)
                setMargins(8, 8, 8, 8)
            }
            
            // Apply locked/selected state visuals
            alpha = if (isUnlocked) 1.0f else 0.5f
        }
        
        // Create theme content container
        val container = FrameLayout(context).apply {
            layoutParams = FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT
            )
        }
        
        // Create the theme preview
        val themePreview = View(context).apply {
            layoutParams = FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT
            )
            
            // Set the background color
            setBackgroundColor(themeInfo.primaryColor)
        }
        
        // Add a label with the theme name
        val themeLabel = TextView(context).apply {
            text = themeInfo.displayName
            setTextColor(themeInfo.textColor)
            textSize = 14f
            textAlignment = View.TEXT_ALIGNMENT_CENTER
            
            // Position at the bottom of the card
            layoutParams = FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.WRAP_CONTENT
            ).apply {
                gravity = android.view.Gravity.BOTTOM or android.view.Gravity.CENTER_HORIZONTAL
                setMargins(4, 4, 4, 8)
            }
        }
        
        // Add level requirement for locked themes
        val levelRequirement = TextView(context).apply {
            text = "Level ${themeInfo.unlockLevel}"
            setTextColor(Color.WHITE)
            textSize = 12f
            textAlignment = View.TEXT_ALIGNMENT_CENTER
            visibility = if (isUnlocked) View.GONE else View.VISIBLE
            
            // Position at the center of the card
            layoutParams = FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.WRAP_CONTENT,
                FrameLayout.LayoutParams.WRAP_CONTENT
            ).apply {
                gravity = android.view.Gravity.CENTER
            }
            // Make text bold and more visible for better readability
            typeface = android.graphics.Typeface.DEFAULT_BOLD
            setShadowLayer(3f, 1f, 1f, Color.BLACK)
        }
        
        // Add a lock icon if the theme is locked
        val lockOverlay = View(context).apply {
            layoutParams = FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT
            )
            
            // Add lock icon or visual indicator
            setBackgroundResource(R.drawable.lock_overlay)
            visibility = if (isUnlocked) View.GONE else View.VISIBLE
        }
        
        // Add all elements to container
        container.addView(themePreview)
        container.addView(themeLabel)
        container.addView(lockOverlay)
        container.addView(levelRequirement)
        
        // Add container to card
        card.addView(container)
        
        // Set up click listener only for unlocked themes
        if (isUnlocked) {
            card.setOnClickListener {
                // Clicking directly selects the theme
                Log.d("ThemeSelector", "Theme card clicked: $themeId (isUnlocked=$isUnlocked)")
                focusedThemeId = themeId
                focusedIndex = themeIdList.indexOf(themeId)
                confirmSelection() // Directly confirm click selection
            }
        }
        
        return card
    }
    
    /**
     * Data class for theme information
     */
    data class ThemeInfo(
        val displayName: String,
        val primaryColor: Int,
        val secondaryColor: Int,
        val textColor: Int,
        val unlockLevel: Int
    )
    
    /**
     * Get all available themes with their details
     */
    private fun getThemes(): Map<String, ThemeInfo> {
        return mapOf(
            PlayerProgressionManager.THEME_CLASSIC to ThemeInfo(
                displayName = "Classic",
                primaryColor = Color.parseColor("#000000"),
                secondaryColor = Color.parseColor("#1F1F1F"),
                textColor = Color.WHITE,
                unlockLevel = 1
            ),
            PlayerProgressionManager.THEME_NEON to ThemeInfo(
                displayName = "Neon",
                primaryColor = Color.parseColor("#0D0221"),
                secondaryColor = Color.parseColor("#650D89"),
                textColor = Color.parseColor("#FF00FF"),
                unlockLevel = 5
            ),
            PlayerProgressionManager.THEME_MONOCHROME to ThemeInfo(
                displayName = "Monochrome",
                primaryColor = Color.parseColor("#1A1A1A"),
                secondaryColor = Color.parseColor("#333333"),
                textColor = Color.LTGRAY,
                unlockLevel = 10
            ),
            PlayerProgressionManager.THEME_RETRO to ThemeInfo(
                displayName = "Retro",
                primaryColor = Color.parseColor("#3F2832"),
                secondaryColor = Color.parseColor("#087E8B"),
                textColor = Color.parseColor("#FF5A5F"),
                unlockLevel = 15
            ),
            PlayerProgressionManager.THEME_MINIMALIST to ThemeInfo(
                displayName = "Minimalist",
                primaryColor = Color.parseColor("#FFFFFF"),
                secondaryColor = Color.parseColor("#F0F0F0"),
                textColor = Color.BLACK,
                unlockLevel = 20
            ),
            PlayerProgressionManager.THEME_GALAXY to ThemeInfo(
                displayName = "Galaxy",
                primaryColor = Color.parseColor("#0B0C10"),
                secondaryColor = Color.parseColor("#1F2833"),
                textColor = Color.parseColor("#66FCF1"),
                unlockLevel = 25
            )
        )
    }
    
    /**
     * Sets whether the entire component has focus (from the parent menu).
     * Controls the outer border visibility.
     */
    fun setHasFocus(hasFocus: Boolean) {
        hasComponentFocus = hasFocus
        // Update visual state based on component focus
        highlightFocusedCard() // Re-apply highlights
    }

    /**
     * Moves the internal focus to the next available theme.
     */
    fun focusNextItem() {
        if (!hasComponentFocus || themeIdList.isEmpty()) return // Only navigate if component has focus

        focusedIndex = (focusedIndex + 1) % themeIdList.size
        focusedThemeId = themeIdList[focusedIndex]
        highlightFocusedCard()
    }

    /**
     * Moves the internal focus to the previous available theme.
     */
    fun focusPreviousItem() {
        if (!hasComponentFocus || themeIdList.isEmpty()) return // Only navigate if component has focus

        focusedIndex = (focusedIndex - 1 + themeIdList.size) % themeIdList.size
        focusedThemeId = themeIdList[focusedIndex]
        highlightFocusedCard()
    }

    /**
     * Confirms the currently focused theme as the selected theme.
     * Triggers the onThemeSelected callback.
     */
    fun confirmSelection() {
        Log.d("ThemeSelector", "confirmSelection called. Focused theme: $focusedThemeId")
        if (focusedThemeId == null || focusedThemeId == selectedTheme) {
             // No change needed if nothing is focused,
             // or the focused item is already selected
            return
        }

        // Update the selected theme
        selectedTheme = focusedThemeId!!
        
        // Update visual states for all cards
        highlightFocusedCard() // This will now mark the new theme as selected

        // Trigger the callback
        onThemeSelected?.invoke(selectedTheme)
    }

     /**
     * Updates the visual highlight state of the theme cards based on
     * selection and internal focus.
     */
    private fun highlightFocusedCard() {
        if (themeCards.isEmpty()) return

        val focusColor = Color.YELLOW // Color for the focused-but-not-selected item
        val selectedColor = Color.WHITE // Color for the selected item (might be focused or not)

        themeCards.forEach { (themeId, card) ->
            val themeInfo = getThemes()[themeId] ?: return@forEach
            val isUnlocked = themeIdList.contains(themeId) // Check if it's in the navigable list

            if (!isUnlocked) {
                 // Keep locked themes visually distinct
                 card.alpha = 0.5f
                 card.cardElevation = 2f
                 card.background = null // Remove any border/background
                 card.setCardBackgroundColor(themeInfo.primaryColor)
                 return@forEach // Skip further styling for locked themes
            }

            // Reset unlocked cards first
            card.alpha = 1.0f
            card.cardElevation = 4f // Default elevation for unlocked cards
            card.background = null
            card.setCardBackgroundColor(themeInfo.primaryColor)
            card.scaleX = 1.0f
            card.scaleY = 1.0f

            val isSelected = (themeId == selectedTheme)
            val isFocused = (hasComponentFocus && themeId == focusedThemeId)

            var borderColor = Color.TRANSPARENT
            var borderWidth = 0
            var elevation = 4f
            var scale = 1.0f

            if (isSelected) {
                borderColor = selectedColor
                borderWidth = 6 // Thick border for selected
                elevation = 12f // Higher elevation for selected
            }

            if (isFocused) {
                 // Focused item gets a distinct border (unless it's also selected)
                 if (!isSelected) {
                     borderColor = focusColor
                     borderWidth = 4 // Slightly thinner border for focused
                 }
                 elevation = 12f // Use high elevation for focus too
                 scale = 1.1f // Scale up the focused item
            }
            
            // Apply scale
            card.scaleX = scale
            card.scaleY = scale

            // Apply border and elevation
            if (borderWidth > 0) {
                val gradientDrawable = GradientDrawable().apply {
                    setColor(themeInfo.primaryColor)
                    setStroke(borderWidth, borderColor)
                    cornerRadius = 12f // Keep consistent corner radius
                }
                card.background = gradientDrawable
            } else {
                 card.background = null // Ensure no border if not selected/focused
            }
            card.cardElevation = elevation
        }
    }
} 