package com.base.browserwhite.ui.activity.scanqrc

import android.Manifest
import android.content.pm.PackageManager
import android.graphics.Color
import android.hardware.camera2.CameraAccessException
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import androidx.activity.addCallback
import androidx.camera.core.AspectRatio
import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import com.base.browserwhite.databinding.ActivityScanQrcBinding
import com.base.browserwhite.ui.activity.BaseActivity
import com.base.browserwhite.ui.views.DialogViews.showGerPermission
import com.base.browserwhite.utils.BarUtils
import com.base.browserwhite.utils.LogEx
import com.base.browserwhite.utils.PermissionHelp.checkCameraPermission
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min


class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() {

    private val TAG = "ScanQRCActivity"

    override val binding: ActivityScanQrcBinding by lazy {
        ActivityScanQrcBinding.inflate(layoutInflater)
    }


    //相机
    private var camera: Camera? = null
    private var preview: Preview? = null
    private var lensFacing: Int = CameraSelector.LENS_FACING_BACK
    private var cameraProvider: ProcessCameraProvider? = null
    private lateinit var cameraExecutor: ExecutorService


    override fun initView() {
        BarUtils.setStatusBarLightMode(this, true)
        BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
        binding.root.updatePadding(top = BarUtils.getStatusBarHeight())

        val hasFlash = this.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)
        binding.ivShoudian.isVisible = hasFlash
        if (hasFlash) {
            binding.ivShoudian.isSelected = false
        }

        if (checkCameraPermission()) {
            initCamera()
        } else {
            showGerPermission(desc = "") {
                launcher.launch(arrayOf(Manifest.permission.CAMERA)) { map ->
                    if (map.values.all { it }) {
                        initCamera()
                    } else {
                        finishToMain()
                    }
                }
            }

        }
    }

    override fun initListener() {
        super.initListener()
        onBackPressedDispatcher.addCallback {
            finishToMain()
        }
        binding.ivGuanbi.setOnClickListener {
            onBackPressedDispatcher.onBackPressed()
        }

        binding.ivShoudian.setOnClickListener {
            try {
                if (binding.ivShoudian.isSelected) {
                    closeFlash()
                } else {
                    openFlash()
                }
            } catch (e: Exception) {
                LogEx.logDebug(TAG, "flash $e")
                return@setOnClickListener
            }
            binding.ivShoudian.isSelected = !binding.ivShoudian.isSelected
        }
        binding.ivPhoto.setOnClickListener { }
    }

    private fun initCamera() {

        cameraExecutor = Executors.newSingleThreadExecutor()

        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        cameraProviderFuture.addListener({
            //初始化相机
            cameraProvider = cameraProviderFuture.get()

            bindCameraUseCases(lensFacing)

        }, ContextCompat.getMainExecutor(this))

    }

    //绑定设置和相机实例
    private fun bindCameraUseCases(lensFacing: Int) {

        val aspectRation = aspectRatio(
            binding.previewView.width,
            binding.previewView.height
        )
        val rotation = binding.previewView.display.rotation

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

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

        //构建图片捕捉类
//        imageCapture = buildImageCapture(aspectRation, rotation)

        //构建图片分析器
//        imageAnalyzer = buildImageAnalysis(aspectRation, rotation) {
//            it.setAnalyzer(cameraExecutor, LuminosityAnalyzer())
//        }

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

        try {
            camera = cameraProvider?.bindToLifecycle(
                this, cameraSelector, preview
            )
            preview?.setSurfaceProvider(binding.previewView.surfaceProvider)
        } catch (exc: Exception) {
            exc.printStackTrace()
        }
    }

    /**
     * 构建横纵比
     */
    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
    }

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

    override fun onDestroy() {
        super.onDestroy()
        cameraExecutor.shutdown()
    }

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


    private fun openFlash() {
        val cameraManager = getSystemService(CAMERA_SERVICE) as CameraManager
        cameraManager.setTorchMode(getBackCameraId(), true)
    }

    private fun closeFlash() {
        val cameraManager = getSystemService(CAMERA_SERVICE) as CameraManager
        cameraManager.setTorchMode(getBackCameraId(), false)
    }

    private fun getBackCameraId(): String {
        var cameraId: String? = null
        try {
            val cameraManager = getSystemService(CAMERA_SERVICE) as CameraManager
            for (id in cameraManager.cameraIdList) {
                val characteristics: CameraCharacteristics = cameraManager.getCameraCharacteristics(id)
                if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK) {
                    cameraId = id
                    break
                }
            }
        } catch (e: CameraAccessException) {
            e.printStackTrace()
        }
        return cameraId ?: ""
    }

}