package com.base.scanqr.qr

import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.AspectRatio
import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.Preview
import androidx.camera.core.ZoomState
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.content.ContextCompat
import androidx.lifecycle.LiveData
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min


class CameraUtils(
    val activity: AppCompatActivity,
) {
    private val TAG = "CameraUtils"

    private var cameraExecutor: ExecutorService? = null//activity销毁时销毁

    //每次暂停都可暂停和赋空
    private var imageAnalyzer: ImageAnalysis? = null
    private var preview: Preview? = null
    private var camera: Camera? = null
    private var cameraProvider: ProcessCameraProvider? = null

    private var lensFacing: Int = CameraSelector.LENS_FACING_BACK

    var cameraReadyCallBack: (() -> Unit)? = null

    init {
        cameraExecutor = Executors.newSingleThreadExecutor()
    }

    /**
     * 绑定
     */
    fun startBind(previewView: PreviewView, qrImageAnalyzer: QRImageAnalyzer) {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(activity)
        cameraProviderFuture.addListener({
            //初始化相机
            cameraProvider = cameraProviderFuture.get()

            bindCameraUseCases(lensFacing, previewView, qrImageAnalyzer)

        }, ContextCompat.getMainExecutor(activity))
    }


    /**
     *解绑
     */
    fun unBind() {
        cameraProvider?.unbindAll()
        imageAnalyzer?.clearAnalyzer()

        cameraProvider = null
        imageAnalyzer = null
        preview = null
        camera = null
    }

    /**
     * 销毁时调用
     */
    fun onDestroy() {
        unBind()

        cameraExecutor?.shutdown()
        cameraExecutor = null
    }

    //绑定设置和相机实例
    private fun bindCameraUseCases(lensFacing: Int, previewView: PreviewView, qrImageAnalyzer: QRImageAnalyzer) {

        val aspectRation = aspectRatio(
            previewView.width,
            previewView.height
        )

        //这里反正有概率为空,不清楚如何处理
        val display = previewView.display ?: return
        val rotation = display.rotation


        // 选择相机
        val cameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()

        //构建预览
        preview = buildPreview(aspectRation, rotation)


        //构建图片分析器
        imageAnalyzer = buildImageAnalysis(aspectRation, rotation) { imageAnalyzer ->
            cameraExecutor?.let { executor ->
                imageAnalyzer.setAnalyzer(executor, qrImageAnalyzer)
            }
        }

        //每次绑定需先解绑
        cameraProvider?.unbindAll()

        try {
            camera = cameraProvider?.bindToLifecycle(
                activity, cameraSelector, imageAnalyzer, preview
            )
            preview?.setSurfaceProvider(previewView.surfaceProvider)
        } catch (exc: Exception) {
            exc.printStackTrace()
        }
        cameraReadyCallBack?.invoke()
    }

    /**
     * 绑定图像分析器
     */
    private fun buildImageAnalysis(
        aspectRatio: Int,
        rotation: Int,
        analysisAction: (imageAnalysis: ImageAnalysis) -> Unit
    ): ImageAnalysis {

        return ImageAnalysis.Builder()
            .setTargetAspectRatio(aspectRatio)
            .setTargetRotation(rotation)
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .build()
            // The analyzer can then be assigned to the instance
            .also {
                analysisAction(it)
            }
    }

    /**
     * 构建预览图
     * @param aspectRatio 宽高比
     * @param rotation 预览图方向
     */
    private fun buildPreview(aspectRatio: Int, rotation: Int): Preview {
        return Preview.Builder()
            .setTargetAspectRatio(aspectRatio)
            .setTargetRotation(rotation)
            .build()
    }

    /**
     * 构建横纵比
     */
    private fun aspectRatio(width: Int, height: Int): Int {
        val previewRatio = max(width, height).toDouble() / min(width, height)
        if (abs(previewRatio - RATIO_4_3_VALUE) <= abs(previewRatio - RATIO_16_9_VALUE)) {
            return AspectRatio.RATIO_4_3
        }
        return AspectRatio.RATIO_16_9
    }

    /**
     * 打开闪光灯
     */
    fun turnOnFlash() {
        val cameraControl = camera?.cameraControl
        cameraControl?.enableTorch(true)
    }

    /**
     * 关闭闪光
     */
    fun turnOffFlash() {
        val cameraControl = camera?.cameraControl
        cameraControl?.enableTorch(false)
    }

    /**
     * 获取闪光状态
     */
    fun getFlashState(): LiveData<Int>? {
        return camera?.cameraInfo?.torchState
    }

    /**
     * 是否支持变焦
     */
    fun isZoomSupported(): Boolean {
        val zoomState: ZoomState? = camera?.cameraInfo?.zoomState?.getValue()
        if (zoomState != null && !java.lang.Float.isNaN(zoomState.minZoomRatio) && !java.lang.Float.isNaN(zoomState.maxZoomRatio)) {
            // 相机支持变焦
            return true
        }
        return false
    }

    /**
     * 获取变焦范围
     */
    fun getZoomRange(): Pair<Float, Float> {
        val zoomState: ZoomState? = camera?.cameraInfo?.zoomState?.getValue()
        if (zoomState != null) {
            val minZoomRatio = zoomState.minZoomRatio
            val maxZoomRatio = zoomState.maxZoomRatio
            return Pair(minZoomRatio, maxZoomRatio)
        }
        return Pair(0f, 100f)
    }

    /**
     * 设置变焦值
     */
    fun setZoomRate(ratio: Float) {
        val cameraControl = camera?.cameraControl
        cameraControl?.setZoomRatio(ratio)
    }

    companion object {
        private const val RATIO_4_3_VALUE = 4.0 / 3.0
        private const val RATIO_16_9_VALUE = 16.0 / 9.0
    }
}