package com.pixelmintdrop.ui

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator

/**
 * Custom progress bar for displaying player XP with animation capabilities
 */
class XPProgressBar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    // Paints for drawing
    private val backgroundPaint = Paint().apply {
        color = Color.BLACK
        isAntiAlias = true
    }
    
    private val progressPaint = Paint().apply {
        color = Color.WHITE
        isAntiAlias = true
    }
    
    private val textPaint = Paint().apply {
        color = Color.WHITE
        isAntiAlias = true
        textAlign = Paint.Align.CENTER
        textSize = 40f
    }
    
    private val levelBadgePaint = Paint().apply {
        color = Color.WHITE
        isAntiAlias = true
    }
    
    private val levelBadgeTextPaint = Paint().apply {
        color = Color.BLACK
        isAntiAlias = true
        textAlign = Paint.Align.CENTER
        textSize = 36f
        isFakeBoldText = true
    }
    
    // Progress bar dimensions
    private val progressRect = RectF()
    private val backgroundRect = RectF()
    private val cornerRadius = 25f
    
    // Progress animation state
    private var progressAnimator: ValueAnimator? = null
    private var currentProgress = 0f // Current visual progress percentage (0-100)
    private var startProgress = 0f   // Progress percentage at animation start
    private var targetProgress = 0f  // Progress percentage at animation end
    
    // XP values state
    private var currentXP = 0L          // Final XP value for the current level after gain
    private var xpForNextLevel = 100L   // XP needed for the next level (can change on level up)
    private var playerLevel = 1         // Final player level after gain
    private var animatingStartXP = 0L   // XP value when animation started
    
    // Level up animation state
    private var isLevelingUp = false
    private var levelUpAnimator: ValueAnimator? = null
    private var levelBadgeScale = 1f

    // Theme-related properties
    private var themeColor = Color.WHITE
    
    /**
     * Set the player's current level and XP values (typically called for initial state)
     */
    fun setXPValues(level: Int, currentXP: Long, xpForNextLevel: Long) {
        this.playerLevel = level
        this.currentXP = currentXP
        this.xpForNextLevel = xpForNextLevel
        this.animatingStartXP = currentXP // Assume start XP is current XP if not animating
        
        // Calculate progress based on these initial values
        this.targetProgress = calculateProgressPercentage(currentXP, xpForNextLevel)
        
        // If not animating, set current progress immediately
        if (progressAnimator == null || !progressAnimator!!.isRunning) {
            this.currentProgress = this.targetProgress
            this.startProgress = this.targetProgress // Ensure start=target if not animating
        }
        
        invalidate()
    }

    /**
     * Set theme color for elements
     */
    fun setThemeColor(color: Int) {
        themeColor = color
        progressPaint.color = color
        textPaint.color = color
        levelBadgePaint.color = color
        invalidate()
    }
    
    /**
     * Animate adding XP to the bar
     */
    fun animateXPGain(xpGained: Long, newLevel: Int, newCurrentXP: Long, newXPForNextLevel: Long) {
        // Store values *before* the gain for animation reference
        val initialXP = this.currentXP
        val initialXPForNext = this.xpForNextLevel
        val initialLevel = this.playerLevel
        
        // Calculate start and target percentages
        this.startProgress = calculateProgressPercentage(initialXP, initialXPForNext)
        this.targetProgress = calculateProgressPercentage(newCurrentXP, newXPForNextLevel)
        
        // Store the starting XP for text interpolation
        this.animatingStartXP = initialXP
        
        // Update member variables to the *final* state
        this.playerLevel = newLevel
        this.currentXP = newCurrentXP
        this.xpForNextLevel = newXPForNextLevel
        
        // Determine if level up occurred
        isLevelingUp = initialLevel < newLevel
        
        // Animate progress bar percentage
        progressAnimator?.cancel()
        progressAnimator = ValueAnimator.ofFloat(startProgress, targetProgress).apply {
            duration = 1500 // 1.5 seconds animation
            interpolator = AccelerateDecelerateInterpolator()
            
            addUpdateListener { animation ->
                // Update the visual progress percentage
                currentProgress = animation.animatedValue as Float
                invalidate() // Trigger redraw on each frame
            }
            
            // Add listener to handle animation end and level up effect
            addListener(object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator) {
                    // Ensure final state is precise
                    currentProgress = targetProgress
                    // Trigger level up visual pulse *after* bar animation completes
                    if (isLevelingUp) {
                        levelUpAnimation()
                    }
                    invalidate()
                }
            })
            
            start()
        }
        // Set the currentProgress to startProgress before starting animation
        // (ValueAnimator starts from its current value, ensure it starts from startProgress)
        // currentProgress = startProgress // REMOVED
        // invalidate() // Initial draw at start state // REMOVED
    }
    
    /**
     * Create a level up animation effect (pulse the level badge)
     */
    private fun levelUpAnimation() {
        levelUpAnimator?.cancel()
        levelUpAnimator = ValueAnimator.ofFloat(1f, 1.5f, 1f).apply {
            duration = 1000 // 1 second pulse animation
            interpolator = AccelerateDecelerateInterpolator()
            
            addUpdateListener { animation ->
                levelBadgeScale = animation.animatedValue as Float
                invalidate()
            }
            start()
        }
    }
    
    /**
     * Calculate the progress percentage given specific XP values
     */
    private fun calculateProgressPercentage(xp: Long, maxXP: Long): Float {
        return if (maxXP > 0) {
            (xp.toFloat() / maxXP.toFloat()) * 100f
        } else {
            0f // Avoid division by zero, return 0%
        }.coerceIn(0f, 100f) // Ensure percentage is always between 0 and 100
    }
    
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        
        // Update progress bar dimensions based on view size
        val verticalPadding = h * 0.2f
        backgroundRect.set(
            h * 0.6f,
            verticalPadding,
            w - paddingRight.toFloat(),
            h - verticalPadding
        )
        
        // Adjust text size based on height
        textPaint.textSize = h * 0.35f
        levelBadgeTextPaint.textSize = h * 0.3f
    }
    
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        
        // Draw level badge (pulses on level up)
        val badgeRadius = height * 0.3f * levelBadgeScale
        val badgeCenterX = height * 0.35f
        val badgeCenterY = height * 0.5f
        
        canvas.drawCircle(badgeCenterX, badgeCenterY, badgeRadius, levelBadgePaint)
        canvas.drawText(
            playerLevel.toString(), // Always show the final level
            badgeCenterX,
            badgeCenterY + (levelBadgeTextPaint.textSize / 3),
            levelBadgeTextPaint
        )
        
        // Draw background bar
        canvas.drawRoundRect(backgroundRect, cornerRadius, cornerRadius, backgroundPaint)
        
        // Calculate progress bar width based on animated currentProgress
        val progressBarWidth = backgroundRect.width() * currentProgress / 100f
        progressRect.set(
            backgroundRect.left,
            backgroundRect.top,
            backgroundRect.left + progressBarWidth,
            backgroundRect.bottom
        )
        
        // Draw the actual progress portion
        if (progressRect.width() > 0) {
            canvas.drawRoundRect(progressRect, cornerRadius, cornerRadius, progressPaint)
        }
        
        // --- Draw Progress Text ---
        val isAnimating = progressAnimator?.isRunning ?: false
        val displayedXP: Long
        val displayedMaxXP = this.xpForNextLevel // Denominator always shows the target max XP

        if (isAnimating) {
            // Calculate displayed XP based on the visual progress percentage (0-100)
            // relative to the max XP for the current/new level.
            displayedXP = (currentProgress / 100.0 * displayedMaxXP).toLong()
        } else {
            // When not animating, use the final accurate values
            displayedXP = this.currentXP
        }

        // Clamp displayed XP to be between 0 and the max for the level visually
        val safeDisplayedXP = displayedXP.coerceIn(0L, displayedMaxXP)

        val progressText = "${safeDisplayedXP}/${displayedMaxXP} XP"
        canvas.drawText(
            progressText,
            backgroundRect.centerX(),
            backgroundRect.centerY() + (textPaint.textSize / 3),
            textPaint
        )
        // --- End Progress Text ---
    }
    
    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        // Clean up animators to prevent leaks
        progressAnimator?.cancel()
        levelUpAnimator?.cancel()
    }
} 