package com.intergration.test

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.media.AudioManager
import android.media.CamcorderProfile
import android.os.Bundle
import android.os.Environment
import android.speech.tts.TextToSpeech
import android.util.Size
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.arcsoft.visdrive.sdk.ArcErrorInfo
import com.arcsoft.visdrive.sdk.ArcVisDriveEngine
import com.arcsoft.visdrive.sdk.constant.common.ArcModType
import com.arcsoft.visdrive.sdk.model.common.ArcActiveEnvParam
import com.blankj.utilcode.util.JsonUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.TimeUtils
import com.intergration.test.databinding.ActivityMainBinding
import com.intergration.test.dms.CAMERA_ID_DMS
import com.intergration.test.dms.COROUTINE_DMS
import com.intergration.test.dms.DmsCoroutineContext
import com.intergration.test.dms.DmsCoroutineScope
import com.intergration.test.dms.dmsEngine
import com.intergration.test.dms.initializeDms
import com.intergration.test.dms.setDmsAlarmParams
import com.intergration.test.dms.setDmsDistractScope
import com.intergration.test.dms.setDmsDrivingStatus
import com.intergration.test.dms.startDms
import com.intergration.test.utils.DOT_PREFACE_DURATION
import com.intergration.test.utils.TTS_ENGINE
import com.intergration.test.utils.VIDEO_FOLDER
import com.mediatek.smartplatform.PreviewSource
import com.mediatek.smartplatform.RecordConfiguration
import com.mediatek.smartplatform.RecordSource
import com.mediatek.smartplatform.SmartPlatformManager
import com.mediatek.smartplatform.SpmCameraDevice
import com.mediatek.smartplatform.SpmCameraDevice.VideoCallback
import com.mediatek.smartplatform.VideoInfoMap
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.Locale
import java.util.concurrent.CancellationException

class MainActivity : AppCompatActivity(),TextToSpeech.OnInitListener,VideoCallback{

    private var dmsCoroutineScope: DmsCoroutineScope? =null

    private lateinit var binding: ActivityMainBinding

    private val smartPlatformManager by lazy {
        SmartPlatformManager.get()
    }

    private val recordConfiguration = RecordConfiguration.get(RecordSource.GENERAL_CAMERA).apply {
        mCamcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P)
        mOutPutFilePath = VIDEO_FOLDER
        mVideoCycleDeleteFileNum = 3
    }

    private var dmsJob:Job? = null

    private val requestCameraPermission = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()){ granted->
        if (granted.values.any().not()) {
            Toast.makeText(this@MainActivity, "请开启权限", Toast.LENGTH_SHORT).show()
            finish()
        }
    }

    private val tts by lazy {
        val am = getSystemService(Context.AUDIO_SERVICE) as AudioManager
        val sb2value =am.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
        am.setStreamVolume(AudioManager.STREAM_MUSIC, sb2value, 0)
        val bundle = Bundle()
        bundle.putFloat(TextToSpeech.Engine.KEY_PARAM_VOLUME,1.0f)
        TextToSpeech(this,this, TTS_ENGINE)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        if (!allPermissionsGranted()) {
            requestCameraPermission.launch(REQUIRED_PERMISSIONS)
        }
        binding.startDms.setOnClickListener {
            if (dmsCoroutineScope == null) {
                dmsCoroutineScope = DmsCoroutineScope(DmsCoroutineContext(engine = dmsEngine,SmartPlatformManager.get().openCameraDevice(
                    CAMERA_ID_DMS
                )) + Dispatchers.IO + COROUTINE_DMS
                )
            }
            dmsJob = dmsCoroutineScope?.launch {
                LogUtils.d("startDms")
                try {
                    coroutineContext[DmsCoroutineContext]?.spmCameraDevice?.setPreviewSurface(binding.dmsPreview.holder.surface,
                        PreviewSource.GENERAL_CAMERA)
                    coroutineContext[DmsCoroutineContext]?.spmCameraDevice?.startPreview()
                    recordConfiguration.mLockFileNamePrefix = "dms"
                    recordConfiguration.mVideoCallback = this@MainActivity
                    coroutineContext[DmsCoroutineContext]?.spmCameraDevice?.startRecord(RecordSource.GENERAL_CAMERA,recordConfiguration)
                    var result = ArcVisDriveEngine.activate(APP_ID, APP_SECRET, arrayOf(ArcModType.TYPE_DMS,ArcModType.TYPE_FR),
                        ArcActiveEnvParam().apply {
                            this.IMEI = DEVICE_IMEI
                            this.storagePath = getExternalFilesDir("")?.path
                        })
                    if (result == ArcErrorInfo.ARC_ERROR_OK) {
                        LogUtils.d("DMS,FR激活成功")
                    } else {
                        LogUtils.e("DMS,FR激活失败")
                        return@launch
                    }
                    result = coroutineContext[DmsCoroutineContext]?.engine?.initializeDms()?:ArcErrorInfo.ARC_ERROR_NOT_ACTIVATED
                    if (result == ArcErrorInfo.ARC_ERROR_OK) {
                        LogUtils.d("DMS初始化成功")
                    } else {
                        LogUtils.e("DMS初始化失败")
                    }
                    coroutineContext[DmsCoroutineContext]?.engine?.let {engine->
                        engine.setDmsAlarmParams()
                        engine.setDmsDistractScope()
                        engine.setDmsDrivingStatus()
                    }
                    coroutineContext[DmsCoroutineContext]?.engine?.let {engine->
                        coroutineContext[DmsCoroutineContext]?.spmCameraDevice?.startDms(engine)?.collect{result->
                            binding.detectResult.text = result
                            tts.speak(result, TextToSpeech.QUEUE_ADD, null,null)
                            launch(Dispatchers.IO){
                                coroutineContext[DmsCoroutineContext]?.spmCameraDevice?.lockRecordingVideo(
                                    DOT_PREFACE_DURATION,"",RecordSource.GENERAL_CAMERA)
                            }
                            launch(Dispatchers.IO) {
                                repeat(3){
                                    coroutineContext[DmsCoroutineContext]?.spmCameraDevice?.takePicture(
                                        "${Environment.getExternalStorageDirectory().path}/waytous/alarm/dms-${TimeUtils.millis2String(System.currentTimeMillis(),"yyyyMMddHHmmss")}.jpg",
                                        {  }, { i, s, s2 ->  }
                                    )
                                    delay(1000)
                                }
                            }
                        }
                    }
                } catch (e: CancellationException) {
                    LogUtils.e("${e.message}")
                    coroutineContext[DmsCoroutineContext]?.spmCameraDevice?.stopPreview()
                    coroutineContext[DmsCoroutineContext]?.spmCameraDevice?.stopRecord(RecordSource.GENERAL_CAMERA)
                    smartPlatformManager.closeCameraDevice(coroutineContext[DmsCoroutineContext]?.spmCameraDevice)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
        binding.stopDms.setOnClickListener {
            if (dmsJob?.isActive == true) {
                dmsJob?.cancel(CancellationException("停止DMS检测"))
                dmsCoroutineScope = null
            } else {
                LogUtils.d("DMS协程已经执行完成")
            }

        }
    }

    override fun onVideoTaken(videoInfo: VideoInfoMap?) {
        when(videoInfo?.getInt(VideoInfoMap.KEY_RECORDER_EVENT_TYPE)){
            VideoCallback.VIDEO_EVENT_SDCARD_FULL-> {
                LogUtils.e("SDCard已满")
                smartPlatformManager.openCameraDevice(CAMERA_ID_DMS).stopRecord(RecordSource.GENERAL_CAMERA)
            }
            VideoCallback.VIDEO_EVENT_RECORD_SDCARD_DAMAGED-> {
                LogUtils.e("SDCard损坏")
                smartPlatformManager.openCameraDevice(CAMERA_ID_DMS).stopRecord(RecordSource.GENERAL_CAMERA)
            }
            VideoCallback.VIDEO_EVENT_RECORD_RECORDING_ERROR-> {
                LogUtils.e("录制视频过程中发生错误")
                smartPlatformManager.openCameraDevice(CAMERA_ID_DMS).stopRecord(RecordSource.GENERAL_CAMERA)
            }
            VideoCallback.VIDEO_EVENT_KEYPOINT_STOP ->{
                LogUtils.d("录制打点视频结束")
            }
        }
    }

    override fun onVideoFrame(p0: ByteArray?, p1: Int, p2: Int, p3: String?, p4: Int) {

    }

    override fun onInit(status: Int) {
        if (status == TextToSpeech.SUCCESS) {
            when (tts.setLanguage(Locale.CHINA)) {
                TextToSpeech.LANG_MISSING_DATA, TextToSpeech.LANG_NOT_SUPPORTED -> {
                    LogUtils.file("TTS暂时不支持这种语音朗读")
                    Toast.makeText(this, "TTS暂时不支持这种语音朗读", Toast.LENGTH_SHORT).show()
                }
                else -> {
                    LogUtils.d("tts初始化成功！")
                    tts.setPitch(1.0f)
                    tts.setSpeechRate(1.0f)
                }
            }
        } else {
            LogUtils.file("TTS初始化失败")
            Toast.makeText(this, "TTS初始化失败", Toast.LENGTH_SHORT).show()
        }
    }

    override fun onDestroy() {
        tts.stop()
        tts.shutdown()
        super.onDestroy()
    }

    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(
            baseContext, it) == PackageManager.PERMISSION_GRANTED
    }

    companion object{
        const val TAG = "dms"
        const val APP_ID = "vdpoYwdwW15s8seKveftWJfsarrre9"
        const val APP_SECRET = "dCdVvhH6tqgWuPMpsvuihPQDHkssWi"
        const val DEVICE_IMEI = "d5e2f07694f674c4"
        private val REQUIRED_PERMISSIONS =
            mutableListOf (
                Manifest.permission.CAMERA,
                Manifest.permission.RECORD_AUDIO,
                Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.ACCESS_WIFI_STATE,
                Manifest.permission.CHANGE_WIFI_STATE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
            ).toTypedArray()
    }

}