package com.adealink.weparty.imageselect.comp

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.LifecycleOwner
import com.adealink.frame.base.Rlt
import com.adealink.frame.log.Log
import com.adealink.frame.mvvm.view.ViewComponent
import com.adealink.frame.util.AppUtil
import com.adealink.frame.util.FileProvider7
import com.adealink.weparty.App
import com.adealink.weparty.commonui.toast.util.showToast
import com.adealink.weparty.hardware.Hardware
import com.adealink.weparty.imageselect.ImageSelectActivity
import com.adealink.weparty.imageselect.clip.ClipImageLifecycleObserver
import com.adealink.weparty.imageselect.clip.ClipParamData
import com.adealink.weparty.imageselect.selectpreview.SelectPreviewLifecycleObserver
import com.adealink.weparty.imageselect.selectpreview.SelectPreviewResult
import com.adealink.weparty.imageselect.takePhoto.TakePhotoLifecycleObserver
import com.adealink.weparty.permission.PermissionUtils
import com.adealink.weparty.storage.file.FilePath.clipImagePath
import com.adealink.weparty.storage.file.FilePath.takePhotoImagePath
import java.io.File

class TakePhotoComp(
    lifecycleOwner: LifecycleOwner,
    val clipParamData: ClipParamData?,
    val onPhotoSelect: (path: String?, uri: String?) -> Unit
) : ViewComponent(lifecycleOwner) {
    private lateinit var takePhotoObserver: TakePhotoLifecycleObserver

    private lateinit var clipImageObserver: ClipImageLifecycleObserver
    private lateinit var selectPreviewObserver: SelectPreviewLifecycleObserver


    private var takePhotoTempFile: File? = null

    override fun onCreate() {
        super.onCreate()
        activity?.let { act ->
            takePhotoImagePath?.let {
                takePhotoTempFile = File(it, "${System.currentTimeMillis()}.jpg")
            }
            takePhotoObserver = object : TakePhotoLifecycleObserver(act.activityResultRegistry) {
                override fun onResult(resultCode: Int) {
                    Log.i(
                        ImageSelectActivity.Companion.TAG,
                        "takePhotoObserver onResult: $resultCode"
                    )
                    if (resultCode != Activity.RESULT_OK) {
                        return
                    }
                    handleTakePhotoResult()
                }
            }
            lifecycle.addObserver(takePhotoObserver)

            selectPreviewObserver =
                object : SelectPreviewLifecycleObserver(act.activityResultRegistry) {
                    override fun onResult(result: SelectPreviewResult) {
                        val resultCode = result.resultCode
                        val path = result.path
                        val uri = result.uri
                        if (resultCode != Activity.RESULT_OK) {
                            return
                        }

                        onPhotoSelect.invoke(path, uri)
                    }
                }
            lifecycle.addObserver(selectPreviewObserver)


            clipImageObserver =
                object :
                    ClipImageLifecycleObserver(act.activityResultRegistry, "TakePhoto_ClipImage") {
                    override fun onResult(resultCode: Int, inputPath: String, outputPath: String) {
                        if (resultCode != AppCompatActivity.RESULT_OK) {
                            return
                        }

                        onPhotoSelect.invoke(
                            outputPath,
                            FileProvider7.getUriForFile(AppUtil.appContext, File(outputPath))
                                ?.toString()
                        )
                    }
                }
            lifecycle.addObserver(clipImageObserver)
        }
    }

    @SuppressLint("CheckResult")
    fun takePhoto() {
        val activity = activity ?: return
        if (PermissionUtils.hasPermissions(activity, Manifest.permission.CAMERA)) {
            when (val rlt = App.instance.hardwareManager.checkHardwareAvailable(Hardware.CAMERA)) {
                is Rlt.Failed -> {
                    showToast(rlt.error.msg)
                }

                is Rlt.Success -> {
                    takePhotoTempFile?.let {
                        takePhotoObserver.launch(it)
                    }
                }
            }
        } else {
            PermissionUtils.getRxPermissions(activity)
                .request(Manifest.permission.CAMERA).subscribe { granted ->
                    if (granted) {
                        when (val rlt =
                            App.instance.hardwareManager.checkHardwareAvailable(Hardware.CAMERA)) {
                            is Rlt.Failed -> {
                                showToast(rlt.error.msg)
                            }

                            is Rlt.Success -> {
                                takePhotoTempFile?.let {
                                    takePhotoObserver.launch(it)
                                }
                            }
                        }
                    }
                }
        }
    }

    private fun handleTakePhotoResult() {
        val activity = activity ?: return
        val takePhotoFile = takePhotoTempFile ?: return
        if (takePhotoFile.exists()) {
            if (clipParamData == null) {
                selectPreviewObserver.launch(
                    takePhotoTempFile?.absolutePath,
                    FileProvider7.getUriForFile(activity, takePhotoTempFile)
                        ?.toString(),
                )
            } else {
                val outputFile = File(clipImagePath, "${System.currentTimeMillis()}.jpg")
                val outputFilePath = outputFile.absolutePath
                clipImageObserver.launch(
                    takePhotoFile.path,
                    outputFilePath,
                    clipParamData
                )
            }
        }
    }
}