package com.cpm.india.cameraai.utils

import android.content.Context
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.util.Log
import androidx.exifinterface.media.ExifInterface
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import com.google.mlkit.vision.face.Face
import kotlin.math.absoluteValue

object GetProperImageRotation {
    fun getRotatedImageFile(photoFile: File?, filePath: String?, context: Context?): File? {
        val option = BitmapFactory.Options()
        option.inSampleSize = 4
        val convertedBitmap: Bitmap =
            modifyOrientation(
                BitmapFactory.decodeFile(photoFile!!.absolutePath, option),
                photoFile.absolutePath, context
            )
        return saveImage(convertedBitmap, filePath)

    }

    private fun saveImage(image: Bitmap, filePath: String?): File? {
        // Get the file object
        val file = filePath?.let { File(it) }
        val os = BufferedOutputStream(FileOutputStream(file))
        image.compress(Bitmap.CompressFormat.JPEG, 100, os)
        os.close()
        return file
    }

    private fun modifyOrientation(
        bitmap: Bitmap,
        image_absolute_path: String,
        context: Context?
    ): Bitmap {
        val ei = ExifInterface(image_absolute_path)
        val orientation: Int =
            ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
        Log.e("orintation", "" + getScreenOrientation(context))
        when (orientation) {
            ExifInterface.ORIENTATION_ROTATE_90 -> {
                return rotate(bitmap, 90f)
            }
            ExifInterface.ORIENTATION_ROTATE_180 -> {
                return rotate(bitmap, 180f)
            }

            ExifInterface.ORIENTATION_TRANSVERSE -> {
                return rotate(bitmap, 270f)
            }

            ExifInterface.ORIENTATION_ROTATE_270 -> {
                return rotate(bitmap, 270f)
            }

            ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> {
                return flip(bitmap, true, vertical = false)
            }

            ExifInterface.ORIENTATION_FLIP_VERTICAL -> {
                return flip(bitmap, false, vertical = true)
            }

            else -> {
                return bitmap
            }
        }
    }

    private fun rotate(bitmap: Bitmap, degrees: Float): Bitmap {
        val matrix = Matrix()
        matrix.postRotate(degrees)
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
    }

    private fun flip(bitmap: Bitmap, horizontal: Boolean, vertical: Boolean): Bitmap {
        val matrix = Matrix()
        matrix.preScale(if (horizontal) (-1f) else 1f, if (vertical) (-1f) else 1f)
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true);
    }

    // Function to check for blink and movement
    fun checkBlinkAndMovement(face: Face): Boolean {
        // Step 1: Check blink detection
        val leftEyeOpenProbability = face.leftEyeOpenProbability ?: -1f
        val rightEyeOpenProbability = face.rightEyeOpenProbability ?: -1f
        // If both eyes are open or closed, consider it a blink detection scenario
        val isBlinking = leftEyeOpenProbability < 0.3 && rightEyeOpenProbability < 0.3
        // Step 2: Check for facial movement (pose detection)
        val headEulerAngleX = face.headEulerAngleX  // Head tilt up/down
        val headEulerAngleY = face.headEulerAngleY  // Head turn left/right
        val headEulerAngleZ = face.headEulerAngleZ  // Head tilt sideways
        // If the face poses (angles) change significantly between frames, consider it as movement
        val isMoving =
            headEulerAngleX.absoluteValue > 10 || headEulerAngleY.absoluteValue > 10 || headEulerAngleZ.absoluteValue > 10
        // Return true if either blinking or movement is detected
        return isBlinking && isMoving
    }

    fun getScreenOrientation(context: Context?): Int {
        val configuration = context?.resources!!.configuration
        // If the configuration returns ORIENTATION_UNDEFINED, manually check width/height
        if (configuration.orientation == Configuration.ORIENTATION_UNDEFINED) {
            val displayMetrics = context.resources!!.displayMetrics
            return if (displayMetrics.widthPixels > displayMetrics.heightPixels) {
                Configuration.ORIENTATION_LANDSCAPE
            } else {
                Configuration.ORIENTATION_PORTRAIT
            }
        }

        return configuration.orientation
    }

}