package com.atridad.openclimb.utils

import android.content.Context
import android.content.Intent
import android.graphics.*
import android.graphics.drawable.GradientDrawable
import androidx.core.content.FileProvider
import com.atridad.openclimb.data.model.*
import java.io.File
import java.io.FileOutputStream
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import kotlin.math.roundToInt

object SessionShareUtils {
    
    data class SessionStats(
        val totalAttempts: Int,
        val successfulAttempts: Int,
        val problems: List<Problem>,
        val uniqueProblemsAttempted: Int,
        val uniqueProblemsCompleted: Int,
        val averageGrade: String?,
        val sessionDuration: String,
        val topResult: AttemptResult?
    )
    
    fun calculateSessionStats(
        session: ClimbSession,
        attempts: List<Attempt>,
        problems: List<Problem>
    ): SessionStats {
        val successfulResults = listOf(
            AttemptResult.SUCCESS, 
            AttemptResult.FLASH, 
            AttemptResult.REDPOINT, 
            AttemptResult.ONSIGHT
        )
        
        val successfulAttempts = attempts.filter { it.result in successfulResults }
        val uniqueProblems = attempts.map { it.problemId }.distinct()
        val uniqueCompletedProblems = successfulAttempts.map { it.problemId }.distinct()
        
        val attemptedProblems = problems.filter { it.id in uniqueProblems }
        val averageGrade = if (attemptedProblems.isNotEmpty()) {
            // This is a simplified average - in reality you'd need proper grade conversion
            val gradeValues = attemptedProblems.mapNotNull { problem ->
                problem.difficulty.grade.filter { it.isDigit() }.toIntOrNull()
            }
            if (gradeValues.isNotEmpty()) {
                "V${gradeValues.average().roundToInt()}"
            } else null
        } else null
        
        val duration = if (session.duration != null) "${session.duration}m" else "Unknown"
        val topResult = attempts.maxByOrNull { 
            when (it.result) {
                AttemptResult.ONSIGHT -> 5
                AttemptResult.FLASH -> 4
                AttemptResult.REDPOINT -> 3
                AttemptResult.SUCCESS -> 2
                AttemptResult.FALL -> 1
                else -> 0
            }
        }?.result
        
        return SessionStats(
            totalAttempts = attempts.size,
            successfulAttempts = successfulAttempts.size,
            problems = attemptedProblems,
            uniqueProblemsAttempted = uniqueProblems.size,
            uniqueProblemsCompleted = uniqueCompletedProblems.size,
            averageGrade = averageGrade,
            sessionDuration = duration,
            topResult = topResult
        )
    }
    
    private fun calculateDuration(startTime: String?, endTime: String?): String {
        return try {
            if (startTime != null && endTime != null) {
                val formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME
                val start = LocalDateTime.parse(startTime, formatter)
                val end = LocalDateTime.parse(endTime, formatter)
                val duration = java.time.Duration.between(start, end)
                
                val hours = duration.toHours()
                val minutes = duration.toMinutes() % 60
                
                when {
                    hours > 0 -> "${hours}h ${minutes}m"
                    minutes > 0 -> "${minutes}m"
                    else -> "< 1m"
                }
            } else {
                "Unknown"
            }
        } catch (e: Exception) {
            "Unknown"
        }
    }
    
    fun generateShareCard(
        context: Context,
        session: ClimbSession,
        gym: Gym,
        stats: SessionStats
    ): File? {
        return try {
            val width = 1080
            val height = 1350
            
            val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
            val canvas = Canvas(bitmap)
            
            val gradientDrawable = GradientDrawable(
                GradientDrawable.Orientation.TOP_BOTTOM,
                intArrayOf(
                    Color.parseColor("#667eea"),
                    Color.parseColor("#764ba2")
                )
            )
            gradientDrawable.setBounds(0, 0, width, height)
            gradientDrawable.draw(canvas)
            
            // Setup paint objects
            val titlePaint = Paint().apply {
                color = Color.WHITE
                textSize = 72f
                typeface = Typeface.DEFAULT_BOLD
                isAntiAlias = true
                textAlign = Paint.Align.CENTER
            }
            
            val subtitlePaint = Paint().apply {
                color = Color.parseColor("#E8E8E8")
                textSize = 48f
                typeface = Typeface.DEFAULT
                isAntiAlias = true
                textAlign = Paint.Align.CENTER
            }
            
            val statLabelPaint = Paint().apply {
                color = Color.parseColor("#B8B8B8")
                textSize = 36f
                typeface = Typeface.DEFAULT
                isAntiAlias = true
                textAlign = Paint.Align.CENTER
            }
            
            val statValuePaint = Paint().apply {
                color = Color.WHITE
                textSize = 64f
                typeface = Typeface.DEFAULT_BOLD
                isAntiAlias = true
                textAlign = Paint.Align.CENTER
            }
            
            val cardPaint = Paint().apply {
                color = Color.parseColor("#40FFFFFF")
                isAntiAlias = true
            }
            
            // Draw main card background
            val cardRect = RectF(60f, 200f, width - 60f, height - 100f)
            canvas.drawRoundRect(cardRect, 40f, 40f, cardPaint)
            
            // Draw content
            var yPosition = 300f
            
            // Title
            canvas.drawText("Climbing Session", width / 2f, yPosition, titlePaint)
            yPosition += 80f
            
            // Gym and date
            canvas.drawText(gym.name, width / 2f, yPosition, subtitlePaint)
            yPosition += 60f
            
            val dateText = formatSessionDate(session.date)
            canvas.drawText(dateText, width / 2f, yPosition, subtitlePaint)
            yPosition += 120f
            
            // Stats grid
            val statsStartY = yPosition
            val columnWidth = width / 2f
            
            // Left column stats
            var leftY = statsStartY
            drawStatItem(canvas, columnWidth / 2f, leftY, "Attempts", stats.totalAttempts.toString(), statLabelPaint, statValuePaint)
            leftY += 140f
            drawStatItem(canvas, columnWidth / 2f, leftY, "Problems", stats.uniqueProblemsAttempted.toString(), statLabelPaint, statValuePaint)
            leftY += 140f
            drawStatItem(canvas, columnWidth / 2f, leftY, "Duration", stats.sessionDuration, statLabelPaint, statValuePaint)
            
            // Right column stats
            var rightY = statsStartY
            drawStatItem(canvas, width - columnWidth / 2f, rightY, "Successful", stats.successfulAttempts.toString(), statLabelPaint, statValuePaint)
            rightY += 140f
            drawStatItem(canvas, width - columnWidth / 2f, rightY, "Completed", stats.uniqueProblemsCompleted.toString(), statLabelPaint, statValuePaint)
            rightY += 140f
            
            stats.averageGrade?.let { grade ->
                drawStatItem(canvas, width - columnWidth / 2f, rightY, "Avg Grade", grade, statLabelPaint, statValuePaint)
            }
            
            // Success rate arc
            if (stats.totalAttempts > 0) {
                val successRate = (stats.successfulAttempts.toFloat() / stats.totalAttempts) * 100
                drawSuccessRateArc(canvas, width / 2f, height - 280f, successRate, statLabelPaint, statValuePaint)
            }
            
            // App branding
            val brandingPaint = Paint().apply {
                color = Color.parseColor("#80FFFFFF")
                textSize = 32f
                typeface = Typeface.DEFAULT
                isAntiAlias = true
                textAlign = Paint.Align.CENTER
            }
            canvas.drawText("OpenClimb", width / 2f, height - 40f, brandingPaint)
            
            // Save to file
            val shareDir = File(context.cacheDir, "shares")
            if (!shareDir.exists()) {
                shareDir.mkdirs()
            }
            
            val filename = "session_${session.id}_${System.currentTimeMillis()}.png"
            val file = File(shareDir, filename)
            
            val outputStream = FileOutputStream(file)
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
            outputStream.flush()
            outputStream.close()
            
            bitmap.recycle()
            
            file
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }
    
    private fun drawStatItem(
        canvas: Canvas,
        x: Float,
        y: Float,
        label: String,
        value: String,
        labelPaint: Paint,
        valuePaint: Paint
    ) {
        canvas.drawText(value, x, y, valuePaint)
        canvas.drawText(label, x, y + 50f, labelPaint)
    }
    
    private fun drawSuccessRateArc(
        canvas: Canvas,
        centerX: Float,
        centerY: Float,
        successRate: Float,
        labelPaint: Paint,
        valuePaint: Paint
    ) {
        val radius = 80f
        val strokeWidth = 16f
        
        // Background arc
        val bgPaint = Paint().apply {
            color = Color.parseColor("#40FFFFFF")
            style = Paint.Style.STROKE
            this.strokeWidth = strokeWidth
            isAntiAlias = true
            strokeCap = Paint.Cap.ROUND
        }
        
        // Success arc
        val successPaint = Paint().apply {
            color = Color.parseColor("#4CAF50")
            style = Paint.Style.STROKE
            this.strokeWidth = strokeWidth
            isAntiAlias = true
            strokeCap = Paint.Cap.ROUND
        }
        
        val rect = RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius)
        
        // Draw background arc (full circle)
        canvas.drawArc(rect, -90f, 360f, false, bgPaint)
        
        // Draw success arc
        val sweepAngle = (successRate / 100f) * 360f
        canvas.drawArc(rect, -90f, sweepAngle, false, successPaint)
        
        // Draw percentage text
        val percentText = "${successRate.roundToInt()}%"
        canvas.drawText(percentText, centerX, centerY + 10f, valuePaint)
        canvas.drawText("Success Rate", centerX, centerY + 60f, labelPaint)
    }
    
    private fun formatSessionDate(dateString: String): String {
        return try {
            val formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME
            val date = LocalDateTime.parse(dateString, formatter)
            val displayFormatter = DateTimeFormatter.ofPattern("MMMM dd, yyyy")
            date.format(displayFormatter)
        } catch (e: Exception) {
            dateString.take(10)
        }
    }
    
    fun shareSessionCard(context: Context, imageFile: File) {
        try {
            val uri = FileProvider.getUriForFile(
                context,
                "${context.packageName}.fileprovider",
                imageFile
            )
            
            val shareIntent = Intent().apply {
                action = Intent.ACTION_SEND
                type = "image/png"
                putExtra(Intent.EXTRA_STREAM, uri)
                putExtra(Intent.EXTRA_TEXT, "Check out my climbing session! 🧗‍♀️ #OpenClimb")
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            }
            
            val chooser = Intent.createChooser(shareIntent, "Share Session")
            chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            context.startActivity(chooser)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}
