// nativeplugins/opencv/android/uts/BitmapUtils.uts

import Bitmap from 'android.graphics.Bitmap'
import Base64 from 'android.util.Base64'
import BitmapFactory from 'android.graphics.BitmapFactory'

// 定义类型接口
type ImageClarityScore = {
    score: number
    level: string
}

type ImageClarityResult = {
    score: number
    level: string
    isClear: boolean
}

/**
 * 图像清晰度检测工具类
 */
export class BitmapUtils {
    
    /**
     * 计算图像的亮度方差作为清晰度指标
     */
    static calculateBrightnessVariance(bitmap: Bitmap): number {
        try {
            const width = bitmap.getWidth()
            const height = bitmap.getHeight()
            
            // 根据原始尺寸动态计算采样尺寸
            // 目标采样区域的总像素数，控制在合理范围内
            const targetPixelCount = 2500 // 50x50 = 2500像素
            
            // 计算合适的采样尺寸，保持宽高比
            let sampleWidth: number
            let sampleHeight: number
            
            if (width > height) {
                // 宽图
                sampleWidth = Math.min(width, Math.sqrt(targetPixelCount * width / height).toInt())
                sampleHeight = Math.min(height, (sampleWidth * height / width).toInt())
            } else {
                // 高图或方图
                sampleHeight = Math.min(height, Math.sqrt(targetPixelCount * height / width).toInt())
                sampleWidth = Math.min(width, (sampleHeight * width / height).toInt())
            }
            
            // 确保最小尺寸
            sampleWidth = Math.max(sampleWidth, 32)
            sampleHeight = Math.max(sampleHeight, 32)
            
            const scaledBitmap = Bitmap.createScaledBitmap(
                bitmap, 
                sampleWidth.toInt(), 
                sampleHeight.toInt(), 
                false
            )
            
            let totalBrightness = 0.0
            let brightnessSquares = 0.0
            const pixelCount = sampleWidth * sampleHeight
            
            // 计算平均亮度
            for (let i: number = 0; i < sampleWidth; i++) {
                for (let j: number = 0; j < sampleHeight; j++) {
                    const pixel = scaledBitmap.getPixel(i.toInt(), j.toInt())
                    const brightness = this.getPixelBrightness(pixel)
                    totalBrightness += brightness
                }
            }
            
            const meanBrightness = totalBrightness / pixelCount
            
            // 计算亮度方差
            for (let i: number = 0; i < sampleWidth; i++) {
                for (let j: number = 0; j < sampleHeight; j++) {
                    const pixel = scaledBitmap.getPixel(i.toInt(), j.toInt())
                    const brightness = this.getPixelBrightness(pixel)
                    const diff = brightness - meanBrightness
                    brightnessSquares += diff * diff
                }
            }
            
            const variance = brightnessSquares / pixelCount
            
            // 回收临时Bitmap
            if (!scaledBitmap.isRecycled()) {
                scaledBitmap.recycle()
            }
            
            return variance
            
        } catch (error) {
            console.error('清晰度计算失败:', error)
            return -1
        }
    }
	
	// 在calculateBrightnessVariance方法中使用多尺度采样
	static calculateBrightnessVariance2(bitmap: Bitmap): number {
	    try {
	        const width = bitmap.getWidth()
	        const height = bitmap.getHeight()
	        
	        // 对2048×1536的图片，使用多个采样尺度
	        const scales = [
	            { width: 200, height: 150 },   // 约10%尺度
	            { width: 100, height: 75 },    // 约5%尺度  
	            { width: 50, height: 38 }      // 约2.5%尺度
	        ]
	        
	        let totalVariance = 0.0
	        let scaleCount = 0
	        
	        for (const scale of scales) {
	            const sampleWidth = Math.min(width, scale.width as number)
	            const sampleHeight = Math.min(height, scale.height as number)
	            
	            if (sampleWidth < 32 || sampleHeight < 32) continue
	            
	            const scaledBitmap = Bitmap.createScaledBitmap(
	                bitmap, 
	                sampleWidth.toInt(), 
	                sampleHeight.toInt(), 
	                false
	            )
	            
	            const variance = this.calculateVarianceForBitmap(scaledBitmap)
	            totalVariance += variance
	            scaleCount++
	            
	            if (!scaledBitmap.isRecycled()) {
	                scaledBitmap.recycle()
	            }
	        }
	        
	        return scaleCount > 0 ? totalVariance / scaleCount : -1
	        
	    } catch (error) {
	        console.error('多尺度清晰度计算失败:', error)
	        return -1
	    }
	}
	
	// 提取方差计算为独立方法
	private static calculateVarianceForBitmap(bitmap: Bitmap): number {
	    const width = bitmap.getWidth()
	    const height = bitmap.getHeight()
	    
	    let totalBrightness = 0.0
	    let brightnessSquares = 0.0
	    const pixelCount = width * height
	    
	    // 计算平均亮度
	    for (let i: number = 0; i < width; i++) {
	        for (let j: number = 0; j < height; j++) {
	            const pixel = bitmap.getPixel(i.toInt(), j.toInt())
	            const brightness = this.getPixelBrightness(pixel)
	            totalBrightness += brightness
	        }
	    }
	    
	    const meanBrightness = totalBrightness / pixelCount
	    
	    // 计算亮度方差
	    for (let i: number = 0; i < width; i++) {
	        for (let j: number = 0; j < height; j++) {
	            const pixel = bitmap.getPixel(i.toInt(), j.toInt())
	            const brightness = this.getPixelBrightness(pixel)
	            const diff = brightness - meanBrightness
	            brightnessSquares += diff * diff
	        }
	    }
	    
	    return brightnessSquares / pixelCount
	}
	
	/**
	 * 基于边缘梯度的清晰度检测（对模糊更敏感）
	 */
	static calculateEdgeGradientClarity(bitmap: Bitmap): number {
	    try {
	        const width = bitmap.getWidth()
	        const height = bitmap.getHeight()
	        
	        // 取中心区域
	        const centerRatio = 0.7
	        const centerWidth = (width * centerRatio).toInt()
	        const centerHeight = (height * centerRatio).toInt()
	        const startX = ((width - centerWidth) / 2).toInt()
	        const startY = ((height - centerHeight) / 2).toInt()
	        
	        const centerBitmap = Bitmap.createBitmap(
	            bitmap,
	            startX,
	            startY,
	            centerWidth,
	            centerHeight
	        )
	        
	        if (centerBitmap == null) {
	            return -1
	        }
	        
	        // 缩放以提高性能
	        const sampleWidth = Math.min(centerWidth, 300)
	        const sampleHeight = Math.min(centerHeight, (300 * centerHeight / centerWidth).toInt())
	        
	        const scaledBitmap = Bitmap.createScaledBitmap(
	            centerBitmap,
	            sampleWidth.toInt(),
	            sampleHeight.toInt(),
	            false
	        )
	        
	        let totalGradient = 0.0
	        let gradientCount = 0
	        
	        // 计算梯度（边缘强度）
	        for (let i: number = 1; i < sampleWidth - 1; i++) {
	            for (let j: number = 1; j < sampleHeight - 1; j++) {
	                const iInt = i.toInt()
	                const jInt = j.toInt()
	                
	                // 获取3x3区域的像素
	                const p00 = this.getPixelBrightness(scaledBitmap.getPixel(iInt - 1, jInt - 1))
	                const p01 = this.getPixelBrightness(scaledBitmap.getPixel(iInt, jInt - 1))
	                const p02 = this.getPixelBrightness(scaledBitmap.getPixel(iInt + 1, jInt - 1))
	                const p10 = this.getPixelBrightness(scaledBitmap.getPixel(iInt - 1, jInt))
	                const p12 = this.getPixelBrightness(scaledBitmap.getPixel(iInt + 1, jInt))
	                const p20 = this.getPixelBrightness(scaledBitmap.getPixel(iInt - 1, jInt + 1))
	                const p21 = this.getPixelBrightness(scaledBitmap.getPixel(iInt, jInt + 1))
	                const p22 = this.getPixelBrightness(scaledBitmap.getPixel(iInt + 1, jInt + 1))
	                
	                // 计算Sobel梯度
	                const gx = (p02 + 2 * p12 + p22) - (p00 + 2 * p10 + p20)
	                const gy = (p20 + 2 * p21 + p22) - (p00 + 2 * p01 + p02)
	                const gradient = Math.sqrt(gx * gx + gy * gy)
	                
	                // 只考虑明显的边缘（避免噪声）
	                if (gradient > 10) {
	                    totalGradient += gradient
	                    gradientCount++
	                }
	            }
	        }
	        
	        const avgGradient = gradientCount > 0 ? totalGradient / gradientCount : 0
	        
	        // 回收Bitmap
	        if (!scaledBitmap.isRecycled()) {
	            scaledBitmap.recycle()
	        }
	        if (!centerBitmap.isRecycled()) {
	            centerBitmap.recycle()
	        }
	        
	        return avgGradient
	        
	    } catch (error) {
	        console.error('边缘梯度清晰度计算失败:', error)
	        return -1
	    }
	}
	
	/**
	 * 快速拉普拉斯方差 - 对模糊敏感且计算效率高
	 */
	static calculateLaplacianVariance(bitmap: Bitmap): number {
	    try {
	        const width = bitmap.getWidth()
	        const height = bitmap.getHeight()
	        
	        // 取中心区域，但使用更小的采样
	        const centerRatio = 0.6
	        const centerWidth = (width * centerRatio).toInt()
	        const centerHeight = (height * centerRatio).toInt()
	        const startX = ((width - centerWidth) / 2).toInt()
	        const startY = ((height - centerHeight) / 2).toInt()
	        
	        const centerBitmap = Bitmap.createBitmap(
	            bitmap,
	            startX,
	            startY,
	            centerWidth,
	            centerHeight
	        )
	        
	        if (centerBitmap == null) {
	            return -1
	        }
	        
	        // 使用较小的采样尺寸
	        const sampleWidth = Math.min(centerWidth, 150)
	        const sampleHeight = Math.min(centerHeight, 100)
	        
	        const scaledBitmap = Bitmap.createScaledBitmap(
	            centerBitmap,
	            sampleWidth.toInt(),
	            sampleHeight.toInt(),
	            false
	        )
	        
	        let laplacianSum = 0.0
	        let pixelCount = 0
	        
	        // 简化的拉普拉斯算子 - 只计算中心与四邻域的差异
	        for (let i: number = 1; i < sampleWidth - 1; i++) {
	            for (let j: number = 1; j < sampleHeight - 1; j++) {
	                const iInt = i.toInt()
	                const jInt = j.toInt()
	                
	                const center = this.getPixelBrightness(scaledBitmap.getPixel(iInt, jInt))
	                const left = this.getPixelBrightness(scaledBitmap.getPixel(iInt - 1, jInt))
	                const right = this.getPixelBrightness(scaledBitmap.getPixel(iInt + 1, jInt))
	                const top = this.getPixelBrightness(scaledBitmap.getPixel(iInt, jInt - 1))
	                const bottom = this.getPixelBrightness(scaledBitmap.getPixel(iInt, jInt + 1))
	                
	                // 拉普拉斯值 = 4*中心 - 上下左右
	                const laplacianValue = Math.abs(4 * center - left - right - top - bottom)
	                
	                if (laplacianValue > 5) { // 忽略微小变化
	                    laplacianSum += laplacianValue
	                    pixelCount++
	                }
	            }
	        }
	        
	        const avgLaplacian = pixelCount > 0 ? laplacianSum / pixelCount : 0
	        
	        // 回收Bitmap
	        if (!scaledBitmap.isRecycled()) {
	            scaledBitmap.recycle()
	        }
	        if (!centerBitmap.isRecycled()) {
	            centerBitmap.recycle()
	        }
	        
	        return avgLaplacian
	        
	    } catch (error) {
	        console.error('拉普拉斯方差计算失败:', error)
	        return -1
	    }
	}
    
	/**
	 * 快速局部对比度检测 - 优化性能
	 */
	static calculateFastLocalContrast(bitmap: Bitmap): number {
	    try {
	        const width = bitmap.getWidth()
	        const height = bitmap.getHeight()
	        
	        // 直接使用缩放后的整个图像，不裁剪中心区域
	        const sampleWidth = Math.min(width, 200)
	        const sampleHeight = Math.min(height, 150)
	        
	        const scaledBitmap = Bitmap.createScaledBitmap(
	            bitmap,
	            sampleWidth.toInt(),
	            sampleHeight.toInt(),
	            false
	        )
	        
	        let contrastSum = 0.0
	        let sampleCount = 0
	        
	        // 使用步长采样，减少计算量
	        const step = 2
	        
	        for (let i: number = 1; i < sampleWidth - 1; i += step) {
	            for (let j: number = 1; j < sampleHeight - 1; j += step) {
	                const iInt = i.toInt()
	                const jInt = j.toInt()
	                
	                // 只检查水平和垂直方向的对比度
	                const center = this.getPixelBrightness(scaledBitmap.getPixel(iInt, jInt))
	                const left = this.getPixelBrightness(scaledBitmap.getPixel(iInt - 1, jInt))
	                const right = this.getPixelBrightness(scaledBitmap.getPixel(iInt + 1, jInt))
	                const top = this.getPixelBrightness(scaledBitmap.getPixel(iInt, jInt - 1))
	                const bottom = this.getPixelBrightness(scaledBitmap.getPixel(iInt, jInt + 1))
	                
	                // 计算最大相邻对比度
	                const horizontalContrast = Math.max(Math.abs(center - left), Math.abs(center - right))
	                const verticalContrast = Math.max(Math.abs(center - top), Math.abs(center - bottom))
	                const maxContrast = Math.max(horizontalContrast, verticalContrast)
	                
	                if (maxContrast > 15) { // 只考虑明显的对比度
	                    contrastSum += maxContrast
	                    sampleCount++
	                }
	            }
	        }
	        
	        const avgContrast = sampleCount > 0 ? contrastSum / sampleCount : 0
	        
	        if (!scaledBitmap.isRecycled()) {
	            scaledBitmap.recycle()
	        }
	        
	        return avgContrast
	        
	    } catch (error) {
	        console.error('快速局部对比度计算失败:', error)
	        return -1
	    }
	}
	
	/**
	 * 自适应阈值清晰度检测
	 * 根据图像内容动态调整判断标准
	 */
	static calculateAdaptiveClarity(bitmap: Bitmap): number {
	    try {
	        const width = bitmap.getWidth()
	        const height = bitmap.getHeight()
	        
	        // 使用小尺寸采样
	        const sampleWidth = Math.min(width, 150)
	        const sampleHeight = Math.min(height, 100)
	        
	        const scaledBitmap = Bitmap.createScaledBitmap(
	            bitmap,
	            sampleWidth.toInt(),
	            sampleHeight.toInt(),
	            false
	        )
	        
	        // 第一步：分析图像的整体对比度特征
	        let highContrastCount = 0
	        let totalSamples = 0
	        
	        for (let i: number = 2; i < sampleWidth - 2; i += 2) {
	            for (let j: number = 2; j < sampleHeight - 2; j += 2) {
	                const iInt = i.toInt()
	                const jInt = j.toInt()
	                
	                const center = this.getPixelBrightness(scaledBitmap.getPixel(iInt, jInt))
	                const neighbors = [
	                    this.getPixelBrightness(scaledBitmap.getPixel(iInt - 1, jInt)),
	                    this.getPixelBrightness(scaledBitmap.getPixel(iInt + 1, jInt)),
	                    this.getPixelBrightness(scaledBitmap.getPixel(iInt, jInt - 1)),
	                    this.getPixelBrightness(scaledBitmap.getPixel(iInt, jInt + 1))
	                ]
	                
	                // 检查是否有高对比度边缘
	                for (const neighbor of neighbors) {
	                    if (Math.abs(center - neighbor) > 25) {
	                        highContrastCount++
	                        break
	                    }
	                }
	                
	                totalSamples++
	            }
	        }
	        
	        const highContrastRatio = highContrastCount / totalSamples
	        
	        // 第二步：基于对比度特征调整清晰度评分
	        let clarityScore: number
	        
	        if (highContrastRatio < 0.05) {
	            // 低对比度图像 - 可能是模糊或单色
	            clarityScore = highContrastRatio * 500
	        } else if (highContrastRatio < 0.15) {
	            // 中等对比度
	            clarityScore = 25 + (highContrastRatio - 0.05) * 250
	        } else {
	            // 高对比度 - 可能是清晰图像
	            clarityScore = 50 + (highContrastRatio - 0.15) * 200
	        }
	        
	        if (!scaledBitmap.isRecycled()) {
	            scaledBitmap.recycle()
	        }
	        
	        return clarityScore
	        
	    } catch (error) {
	        console.error('自适应清晰度计算失败:', error)
	        return -1
	    }
	}
	
	
	/**
	 * 优化的快速清晰度检测方案
	 * 平衡准确性和性能
	 */
	static calculateOptimizedClarity(bitmap: Bitmap): number {
	    try {
	        // 使用两种快速方法，权重偏向对模糊更敏感的方法
	        const laplacianScore = this.calculateAdaptiveClarity(bitmap)
	        const contrastScore = this.calculateFastLocalContrast(bitmap)
	        
	        // 如果两种方法都返回有效结果，取加权平均
	        if (laplacianScore > 0 && contrastScore > 0) {
	            // 自适应阈值清晰度检测
	            return laplacianScore * 0.3 + contrastScore * 0.7
	        }
	        
	        // 如果只有一种方法有效，返回该结果
	        return Math.max(laplacianScore, contrastScore)
	        
	    } catch (error) {
	        console.error('优化清晰度计算失败:', error)
	        return -1
	    }
	}
	
	/**
	 * 超快速清晰度检测（最低计算量）
	 */
	static calculateUltraFastClarity(bitmap: Bitmap): number {
	    try {
	        const width = bitmap.getWidth()
	        const height = bitmap.getHeight()
	        
	        // 极小的采样尺寸
	        const sampleWidth = 80
	        const sampleHeight = 60
	        
	        const scaledBitmap = Bitmap.createScaledBitmap(
	            bitmap,
	            sampleWidth.toInt(),
	            sampleHeight.toInt(),
	            false
	        )
	        
	        let edgeStrength = 0.0
	        let sampleCount = 0
	        
	        // 极简的边缘检测 - 只检查少数关键点
	        const checkPoints = [
	            { x: 20, y: 15 }, { x: 40, y: 15 }, { x: 60, y: 15 },
	            { x: 20, y: 30 }, { x: 40, y: 30 }, { x: 60, y: 30 },
	            { x: 20, y: 45 }, { x: 40, y: 45 }, { x: 60, y: 45 }
	        ]
	        
	        for (const point of checkPoints) {
	            const x  = point.x as number
	            const y  = point.y as number
	            
	            if (x >= 1 && x < sampleWidth - 1 && y >= 1 && y < sampleHeight - 1) {
	                const center = this.getPixelBrightness(scaledBitmap.getPixel(x.toInt(), y.toInt()))
	                const right = this.getPixelBrightness(scaledBitmap.getPixel(x.toInt() + 1, y.toInt()))
	                const bottom = this.getPixelBrightness(scaledBitmap.getPixel(x.toInt(), y.toInt() + 1))
	                
	                const edgeValue = Math.abs(center - right) + Math.abs(center - bottom)
	                
	                if (edgeValue > 10) {
	                    edgeStrength += edgeValue
	                    sampleCount++
	                }
	            }
	        }
	        
	        const avgEdgeStrength = sampleCount > 0 ? edgeStrength / sampleCount : 0
	        
	        if (!scaledBitmap.isRecycled()) {
	            scaledBitmap.recycle()
	        }
	        
	        return avgEdgeStrength
	        
	    } catch (error) {
	        console.error('超快速清晰度计算失败:', error)
	        return -1
	    }
	}
	
    /**
     * 获取像素亮度
     */
    private static getPixelBrightness(pixel: number): number {
        const r = (pixel >> 16) & 0xff
        const g = (pixel >> 8) & 0xff
        const b = pixel & 0xff
        return (r + g + b) / 3.0
    }
    
    /**
     * 判断图像是否清晰
     */
    static isImageClear(bitmap: Bitmap, threshold: number = 500): boolean {
        const variance = this.calculateOptimizedClarity(bitmap)
        return variance > threshold
    }
    
    /**
     * 获取图像清晰度评分
     */
    static getImageClarityScore(bitmap: Bitmap): ImageClarityScore {
        const variance = this.calculateOptimizedClarity(bitmap)
        
        let level: string
        if (variance < 0) {
            level = "处理失败"
        } else if (variance < 15) {
            level = "非常模糊"
        } else if (variance < 35) {
            level = "模糊"
        } else if (variance < 45) {
            level = "一般"
        } else if (variance < 60) {
            level = "清晰"
        } else {
            level = "非常清晰"
        }
        
        return {
            score: Math.round(variance * 100) / 100,
            level: level
        }
    }
    
    /**
     * 从Base64数据检测清晰度
     */
    static checkImageClarityFromBase64(base64Data: string): ImageClarityResult {
        try {
            const bitmap = this.base64ToBitmap(base64Data)
            if (bitmap == null) {
                return { score: -1, level: "加载失败", isClear: false }
            }
            
            const clarityInfo = this.getImageClarityScore(bitmap)
            const isClear = this.isImageClear(bitmap)
            
            if (!bitmap.isRecycled()) {
                bitmap.recycle()
            }
            
            return {
                score: clarityInfo.score,
                level: clarityInfo.level,
                isClear: isClear
            }
            
        } catch (error) {
            console.error('图像清晰度检测失败:', error)
            return { score: -1, level: "检测失败", isClear: false }
        }
    }
    
    /**
     * 从文件路径检测清晰度
     */
    static checkImageClarityFromPath(imagePath: string): ImageClarityResult {
        try {
            const bitmap = BitmapFactory.decodeFile(imagePath)
            if (bitmap == null) {
                return { score: -1, level: "加载失败", isClear: false }
            }
            
            const clarityInfo = this.getImageClarityScore(bitmap)
            const isClear = this.isImageClear(bitmap)
            
            if (!bitmap.isRecycled()) {
                bitmap.recycle()
            }
            
            return {
                score: clarityInfo.score,
                level: clarityInfo.level,
                isClear: isClear
            }
            
        } catch (error) {
            console.error('图像清晰度检测失败:', error)
            return { score: -1, level: "检测失败", isClear: false }
        }
    }
    
    /**
     * 简化的Base64转Bitmap方法
     */
    private static base64ToBitmap(base64Data: string): Bitmap | null {
        try {
            // 移除Base64前缀
            let pureBase64 = base64Data
            if (base64Data.includes(',')) {
                pureBase64 = base64Data.split(',')[1]
            }
            
            // 解码Base64
            const decodedBytes = Base64.decode(pureBase64, Base64.DEFAULT)
            
            // 获取字节数组长度
            const bitmap = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size)
            
            return bitmap
            
        } catch (error) {
            console.error('Base64转Bitmap失败:', error)
            return null
        }
    }
    
    /**
     * 备用方法：直接返回清晰度分数（避免复杂对象类型）
     */
    static getSimpleClarityScore(bitmap: Bitmap): number {
        return this.calculateBrightnessVariance(bitmap)
    }
    
    /**
     * 从Base64获取简单清晰度分数
     */
    static getSimpleClarityScoreFromBase64(base64Data: string): number {
        try {
            const bitmap = this.base64ToBitmap(base64Data)
            if (bitmap == null) {
                return -1
            }
            
            const score = this.calculateBrightnessVariance(bitmap)
            
            if (!bitmap.isRecycled()) {
                bitmap.recycle()
            }
            
            return score
            
        } catch (error) {
            console.error('清晰度检测失败:', error)
            return -1
        }
    }
}