package com.rosetta.messenger.ui.components.metaball

import android.content.Context
import android.graphics.Path
import android.graphics.RectF
import android.os.Build
import android.view.Gravity
import android.view.View
import androidx.core.graphics.PathParser

/**
 * Utility to get notch/camera cutout information - ported from Telegram's NotchInfoUtils.java
 */
object NotchInfoUtils {
    
    data class NotchInfo(
        val gravity: Int = Gravity.CENTER,
        val isAccurate: Boolean = false,
        val isLikelyCircle: Boolean = false,
        val path: Path? = null,
        val bounds: RectF = RectF(),
        val rawPath: String = ""
    )
    
    private const val BOTTOM_MARKER = "@bottom"
    private const val DP_MARKER = "@dp"
    private const val RIGHT_MARKER = "@right"
    private const val LEFT_MARKER = "@left"
    
    /**
     * Get notch/cutout information from system resources
     * Returns null if no notout found or Android < P
     */
    fun getInfo(context: Context): NotchInfo? {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            return null
        }
        
        try {
            val res = context.resources
            val resId = res.getIdentifier("config_mainBuiltInDisplayCutout", "string", "android")
            if (resId == 0) return null
            
            var spec = context.getString(resId)
            if (spec.isEmpty()) return null
            spec = spec.trim()
            
            val metrics = res.displayMetrics
            val displayWidth = metrics.widthPixels
            val density = metrics.density
            
            // Determine gravity and offset
            var gravity: Int
            val offsetX: Float
            
            when {
                spec.endsWith(RIGHT_MARKER) -> {
                    offsetX = displayWidth.toFloat()
                    spec = spec.substring(0, spec.length - RIGHT_MARKER.length).trim()
                    gravity = Gravity.END
                }
                spec.endsWith(LEFT_MARKER) -> {
                    offsetX = 0f
                    spec = spec.substring(0, spec.length - LEFT_MARKER.length).trim()
                    gravity = Gravity.START
                }
                else -> {
                    offsetX = displayWidth / 2f
                    gravity = Gravity.CENTER
                }
            }
            
            // Check if in dp
            val inDp = spec.endsWith(DP_MARKER)
            if (inDp) {
                spec = spec.substring(0, spec.length - DP_MARKER.length)
            }
            
            // Remove bottom marker if present
            if (spec.contains(BOTTOM_MARKER)) {
                spec = spec.split(BOTTOM_MARKER)[0].trim()
            }
            
            // Parse path
            val path = try {
                val nodes = PathParser.createNodesFromPathData(spec)
                Path().also { PathParser.PathDataNode.nodesToPath(nodes, it) }
            } catch (e: Exception) {
                return null
            }
            
            // Transform path
            val matrix = android.graphics.Matrix()
            if (inDp) {
                matrix.postScale(density, density)
            }
            matrix.postTranslate(offsetX, 0f)
            path.transform(matrix)
            
            // Compute bounds
            val bounds = RectF()
            path.computeBounds(bounds, true)
            
            // Adjust gravity based on position
            val dp2 = 2 * density
            if (gravity != Gravity.CENTER && kotlin.math.abs(bounds.centerX() - displayWidth / 2f) <= dp2) {
                gravity = Gravity.CENTER
            }
            if (gravity == Gravity.CENTER && bounds.left < displayWidth / 4f) {
                gravity = Gravity.START
            }
            if (gravity == Gravity.CENTER && bounds.right > displayWidth / 4f * 3f) {
                gravity = Gravity.END
            }
            
            val dp32 = 32 * density
            val isLikelyCircle = bounds.width() <= dp32 || bounds.width() <= bounds.height()
            val isAccurate = spec.contains("C") || spec.contains("S") || spec.contains("Q")
            
            return NotchInfo(
                gravity = gravity,
                isAccurate = isAccurate,
                isLikelyCircle = isLikelyCircle,
                path = path,
                bounds = bounds,
                rawPath = spec
            )
        } catch (e: Exception) {
            return null
        }
    }

    /**
     * Fallback: get notch info from DisplayCutout API (Android P+).
     * Works on Pixel 7 Pro and other devices that don't expose config_mainBuiltInDisplayCutout.
     * Requires a View that is attached to the window.
     */
    fun getInfoFromCutout(view: View): NotchInfo? {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) return null
        try {
            val insets = view.rootWindowInsets ?: return null
            val cutout = insets.displayCutout ?: return null
            val rects = cutout.boundingRects
            if (rects.isEmpty()) return null

            val displayWidth = view.resources.displayMetrics.widthPixels
            val density = view.resources.displayMetrics.density

            // Find the top cutout (front camera / punch-hole)
            val topRect = rects.firstOrNull { it.top == 0 || it.top < it.height() * 2 }
                ?: rects.first()

            val bounds = RectF(
                topRect.left.toFloat(),
                topRect.top.toFloat(),
                topRect.right.toFloat(),
                topRect.bottom.toFloat()
            )

            // Determine gravity
            val centerX = bounds.centerX()
            val gravity = when {
                kotlin.math.abs(centerX - displayWidth / 2f) <= 4 * density -> Gravity.CENTER
                centerX < displayWidth / 4f -> Gravity.START
                centerX > displayWidth * 3f / 4f -> Gravity.END
                else -> Gravity.CENTER // punch-hole near center
            }

            val dp32 = 32 * density
            val isLikelyCircle = bounds.width() <= dp32 || bounds.width() <= bounds.height()

            return NotchInfo(
                gravity = gravity,
                isAccurate = false, // no path data, just bounding rect
                isLikelyCircle = isLikelyCircle,
                path = null,
                bounds = bounds,
                rawPath = "cutout:${topRect}"
            )
        } catch (e: Exception) {
            return null
        }
    }
}
