package com.easy.clean.ui.photocompression

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.Paint
import android.media.MediaScannerConnection
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import androidx.core.graphics.createBitmap
import androidx.exifinterface.media.ExifInterface

object CompressionUtils {

    fun compressSave(context: Context, path: String, mode: Int, complete: (Boolean, Long) -> Unit) {
        compressPhoto(path, mode) { size, bitmap ->
            if (bitmap != null) {
                saveFile(context, path, bitmap, getQuality(mode), complete)
            } else {
                complete.invoke(false, 0)
            }
        }
    }

    fun compressPhoto(path: String, mode: Int, complete: (Long, Bitmap?) -> Unit) {
        Thread {
            try {
                // 读取照片信息和确定缩放比例
                val options = BitmapFactory.Options().apply {
                    inJustDecodeBounds = true
                    BitmapFactory.decodeFile(path, this)
                    inSampleSize = calculateInSampleSize(this, 1080, 1920)
                    inJustDecodeBounds = false
                }

                // 读取照片数据
                val bitmap = BitmapFactory.decodeFile(path, options)
                if (bitmap == null) {
                    complete(0, null)
                    return@Thread
                }

                // 旋转照片
                val orientation = getOrientation(path)
                val rotatedBitmap = rotateBitmap(bitmap, orientation)

                // 处理透明背景
                val transparentBitmap = handleTransparentBackground(rotatedBitmap)

                // 压缩照片
                val cacheFile = createTempFile(".jpg")
                compressBitmap(transparentBitmap, cacheFile, mode)
                complete(cacheFile.length(), BitmapFactory.decodeFile(cacheFile.path))
                cacheFile.delete()
            } catch (e: IOException) {
                complete(0, null)
            }
        }.start()
    }

    fun saveFile(context: Context, path: String, bitmap: Bitmap, quality: Int, complete: (Boolean, Long) -> Unit) {
        Thread {
            val file = File(path)
            if (file.exists()) {
                file.delete()
            }
            try {
                val outputStream = FileOutputStream(file)
                bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream)
                outputStream.flush()
                outputStream.close()
                updateMedia(context, path)
                val compressFile = File(path)
                complete.invoke(true, compressFile.length())
            } catch (e: IOException) {
                e.printStackTrace()
                complete.invoke(false, 0)
            }
        }.start()
    }

    private fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
        val width = options.outWidth
        val height = options.outHeight
        var inSampleSize = 1
        while (width / inSampleSize > reqWidth || height / inSampleSize > reqHeight) {
            inSampleSize *= 2
        }
        return inSampleSize
    }

    private fun rotateBitmap(bitmap: Bitmap, orientation: Int): Bitmap {
        val matrix = Matrix()
        when (orientation) {
            ExifInterface.ORIENTATION_ROTATE_90 -> matrix.postRotate(90f)
            ExifInterface.ORIENTATION_ROTATE_180 -> matrix.postRotate(180f)
            ExifInterface.ORIENTATION_ROTATE_270 -> matrix.postRotate(270f)
        }
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
    }

    private fun handleTransparentBackground(bitmap: Bitmap): Bitmap {
        val newBitmap = createBitmap(bitmap.width, bitmap.height)
        val canvas = Canvas(newBitmap)
        val paint = Paint().apply { isAntiAlias = true; color = 0xFFFFFFFF.toInt() }
        canvas.drawARGB(255, 255, 255, 255)
        canvas.drawBitmap(bitmap, 0f, 0f, paint)
        return newBitmap
    }

    private fun compressBitmap(bitmap: Bitmap, file: File, qualityMode: Int) {
        val outputStream = FileOutputStream(file)
        bitmap.compress(Bitmap.CompressFormat.JPEG, getQuality(qualityMode), outputStream)
        outputStream.flush()
        outputStream.close()
    }

    private fun getQuality(mode: Int): Int {
        return when (mode) {
            1 -> 90
            2 -> 85
            else -> 98
        }
    }


    private fun getOrientation(filePath: String): Int {
        return try {
            val exif = ExifInterface(filePath)
            exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)
        } catch (e: IOException) {
            ExifInterface.ORIENTATION_UNDEFINED
        }
    }

    private fun createTempFile(extension: String): File {
        return File.createTempFile(System.currentTimeMillis().toString(), extension)
    }

    private fun updateMedia(context:Context, filePath: String) {
        MediaScannerConnection.scanFile(context, arrayOf(filePath), null, null)
    }
}