package com.example.livingai.utils

import android.graphics.Bitmap
import kotlin.math.sqrt

fun calculateHammingDistance(mask1: Bitmap, mask2: Bitmap, thresholdPercent: Int): Boolean {
    if (mask1.width != mask2.width || mask1.height != mask2.height) return false

    val width = mask1.width
    val height = mask1.height
    val p1 = IntArray(width * height)
    val p2 = IntArray(width * height)

    mask1.getPixels(p1, 0, width, 0, 0, width, height)
    mask2.getPixels(p2, 0, width, 0, 0, width, height)

    var distance = 0

    for (i in p1.indices) {
        val a = (p1[i] ushr 24) > 0
        val b = (p2[i] ushr 24) > 0
        if (a != b) distance++
    }

    val total = width * height
    val allowed = total * (100 - thresholdPercent) / 100

    return distance <= allowed
}

fun calculateEuclideanDistance(mask1: Bitmap, mask2: Bitmap, thresholdPercent: Int): Boolean {
    if (mask1.width != mask2.width || mask1.height != mask2.height) return false

    val width = mask1.width
    val height = mask1.height
    val p1 = IntArray(width * height)
    val p2 = IntArray(width * height)

    mask1.getPixels(p1, 0, width, 0, 0, width, height)
    mask2.getPixels(p2, 0, width, 0, 0, width, height)

    var sum = 0L
    for (i in p1.indices) {
        val v1 = if ((p1[i] ushr 24) > 0) 255 else 0
        val v2 = if ((p2[i] ushr 24) > 0) 255 else 0
        val diff = v1 - v2
        sum += diff * diff
    }

    val dist = sqrt(sum.toDouble())
    val max = sqrt((width * height).toDouble()) * 255.0
    val allowed = max * (100 - thresholdPercent) / 100.0

    return dist <= allowed
}

fun calculateJaccardSimilarity(mask1: Bitmap, mask2: Bitmap, thresholdPercent: Int): Boolean {
    if (mask1.width != mask2.width || mask1.height != mask2.height) return false

    val width = mask1.width
    val height = mask1.height
    val p1 = IntArray(width * height)
    val p2 = IntArray(width * height)

    mask1.getPixels(p1, 0, width, 0, 0, width, height)
    mask2.getPixels(p2, 0, width, 0, 0, width, height)

    var intersection = 0
    var union = 0

    for (i in p1.indices) {
        val a = ((p1[i] ushr 24) and 0xFF) > 0
        val b = ((p2[i] ushr 24) and 0xFF) > 0

        if (a && b) intersection++
        if (a || b) union++
    }

    if (union == 0) return false

    val score = (intersection.toDouble() / union.toDouble()) * 100.0

    return score >= thresholdPercent
}

fun calculateDistance(
    method: String,
    mask1: Bitmap,
    mask2: Bitmap,
    thresholdPercent: Int
): Boolean {
    return when (method) {
        "Hamming" -> calculateHammingDistance(mask1, mask2, thresholdPercent)
        "Euclidean" -> calculateEuclideanDistance(mask1, mask2, thresholdPercent)
        "Jaccard" -> calculateJaccardSimilarity(mask1, mask2, thresholdPercent)
        else -> false
    }
}