package com.assimilate.alltrans.viewui


import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.util.Pair
import android.view.View
import android.view.ViewTreeObserver
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R
import com.assimilate.alltrans.adapters.LanguageAdapter
import com.assimilate.alltrans.common.BitmapUtils
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.common.LolAdWrapper
import com.assimilate.alltrans.common.TextGraphic
import com.assimilate.alltrans.model.Language
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.assimilate.alltrans.common.TextRecognitionProcessor
import com.assimilate.alltrans.common.VisionImageProcessor
import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.curview.GraphicOverlay
import com.assimilate.alltrans.databinding.ActivityStillImageBinding
import com.google.android.gms.common.annotation.KeepName
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.common.util.concurrent.ListenableFuture
import com.google.mlkit.vision.text.Text
import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions
import com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions
import com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions
import com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions
import com.google.mlkit.vision.text.latin.TextRecognizerOptions
import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Locale
import kotlin.math.max
import kotlin.math.min

@KeepName
class PhotoImageActivity : AppCompatActivity(), TextRecognitionProcessor.TextRecognitionCallback {

    private var selectedMode = TEXT_RECOGNITION_CHINESE
    private var selectedSize: String? = SIZE_SCREEN
    private var isLandScape = false
    private var imageUri: Uri? = null
    private var imageMaxWidth = 0
    private var imageMaxHeight = 0
    private var imageProcessor: VisionImageProcessor? = null
    private lateinit var imageCapture: ImageCapture
    private lateinit var outputDirectory: File
    private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>

    private var isFlashOn = false
    private var fbFrom = "photo"
    private var needReshoot = false

    private val REQUEST_CAMERA_PERMISSION = 100
    private lateinit var bottomSheetDialog: BottomSheetDialog
    private var chooseLanguage: Boolean = false
    private lateinit var binding: ActivityStillImageBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        binding = ActivityStillImageBinding.inflate(layoutInflater)
        setContentView(binding.root)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.root)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(0, systemBars.top + 26, 0, systemBars.bottom)
            insets
        }
        firebaseEvent()

        Widget.makeSnackbar(this, getString(R.string.ph_toast))

        isLandScape = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
        savedInstanceState?.let {
            imageUri = it.getParcelable(KEY_IMAGE_URI)
            imageMaxWidth = it.getInt(KEY_IMAGE_MAX_WIDTH)
            imageMaxHeight = it.getInt(KEY_IMAGE_MAX_HEIGHT)
            selectedSize = it.getString(KEY_SELECTED_SIZE)
        }

        val rootView = findViewById<View>(R.id.root)
        rootView.viewTreeObserver.addOnGlobalLayoutListener(object :
            ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                rootView.viewTreeObserver.removeOnGlobalLayoutListener(this)
                imageMaxWidth = rootView.width
                imageMaxHeight = rootView.height - findViewById<View>(R.id.control).height
                if (SIZE_SCREEN == selectedSize) {
                    tryReloadAndDetectInImage()
                }
            }
        })

        outputDirectory = getOutputDirectory()
        // 检查并启动相机
        checkCameraPermission()
        initView()
        adLoad(MyApp.Config.image_camera_int_auto)
        backPressedCall()
        initClick()
    }

    private fun firebaseEvent() {
        // 获取意图中的数据
        val eventKey = intent.getStringExtra("key_start_ph")
        // 记录Firebase Analytics事件
        if (eventKey != null) {
            FirebaseAnalyticsHelper.imageClickEvent(MyApp.Config.CLICK_FROM, eventKey)
        }
    }

    private fun checkCameraPermission() {
        if (ContextCompat.checkSelfPermission(
                this, Manifest.permission.CAMERA
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.CAMERA),
                REQUEST_CAMERA_PERMISSION
            )
        } else {
            startCamera()
        }
    }


    private fun initView() {

        binding.photoPreview.visibility = View.VISIBLE

        binding.stillSourceLanguage.text =
            PreferenceLanguageUtils.getString("language_source")
        binding.stillTargetLanguage.text =
            PreferenceLanguageUtils.getString("language_target")

        bottomSheetDialog = BottomSheetDialog(this, R.style.CustomBottomSheetDialogTheme)
        bottomSheetDialog.setContentView(R.layout.bottomsheet_still_lan)
        bottomSheetDialog.dismissWithAnimation = true

        bottomSheetDialog.findViewById<androidx.appcompat.widget.SearchView>(R.id.ph_search)
            ?.let { searchView ->
                // 设置关闭按钮一直显示
                searchView.isIconified = false
                searchView.clearFocus()

                // 设置点击事件
                searchView.setOnClickListener {
                    // 清空搜索框
                    searchView.setQuery("", false)
                    // 清除焦点
                    searchView.clearFocus()

                    // 隐藏软件盘
                    val imm =
                        this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                    imm.hideSoftInputFromWindow(searchView.windowToken, 0)

                    // 保持关闭按钮显示
                    searchView.isIconified = false
                }

                // 设置查询文本监听器
                searchView.setOnQueryTextListener(object :
                    androidx.appcompat.widget.SearchView.OnQueryTextListener {
                    override fun onQueryTextSubmit(query: String?): Boolean {
                        return false
                    }

                    override fun onQueryTextChange(newText: String?): Boolean {
                        (bottomSheetDialog.findViewById<RecyclerView>(R.id.list_languages)?.adapter as LanguageAdapter).filter.filter(
                            newText
                        )
                        return true
                    }
                })

                // 设置关闭按钮点击事件
                searchView.findViewById<View>(androidx.appcompat.R.id.search_close_btn)
                    ?.setOnClickListener {
                        searchView.setQuery("", false)
                        searchView.clearFocus()
                        searchView.isIconified = false // 保持关闭按钮显示
                    }
            }

        initList()
    }

    private fun initList() {
        val languages: ArrayList<Language> = LanguagesConstants.getInstance().getList(this)
        if (languages.isNotEmpty()) {
            val myAdapter = LanguageAdapter(this, languages) { _, language ->
                if (!chooseLanguage) {

                    PreferenceLanguageUtils.putString("language_source", language.language)
                    selectedMode = PreferenceLanguageUtils.getString("language_source")
                    FirebaseAnalyticsHelper.languageFromEvent(
                        MyApp.Config.CLICK_FROM,
                        "photo_source"
                    )

                    tryReloadAndDetectInImage()
                    bottomSheetDialog.dismiss()
                } else {
                    FirebaseAnalyticsHelper.languageFromEvent(
                        MyApp.Config.CLICK_FROM,
                        "photo_target"
                    )

                    PreferenceLanguageUtils.putString("language_target", language.language)
                    tryReloadAndDetectInImage()
                    bottomSheetDialog.dismiss()

                }

                binding.stillSourceLanguage.text =
                    PreferenceLanguageUtils.getString("language_source")
                binding.stillTargetLanguage.text =
                    PreferenceLanguageUtils.getString("language_target")
            }
            bottomSheetDialog.findViewById<RecyclerView>(R.id.list_languages)?.apply {
                layoutManager =
                    LinearLayoutManager(
                        this@PhotoImageActivity,
                        LinearLayoutManager.VERTICAL,
                        false
                    )
                adapter = myAdapter
            }

        }
    }

    private fun initClick() {
        binding.ivStillPic.setOnClickListener {
            binding.photoPreview.visibility = View.INVISIBLE
            startChooseImageIntentForResult()
            FirebaseAnalyticsHelper.imageTransPhotoEvent()
        }
        binding.ivReshoot.setOnClickListener {
            needReshoot = false

            binding.photoPreview.visibility = View.VISIBLE
            binding.preview.setImageBitmap(null)
            binding.graphicOverlay.clear()

        }
        binding.ivStillTake.setOnClickListener {

            if (needReshoot) return@setOnClickListener
            binding.photoPreview.visibility = View.VISIBLE
            takePhoto()
            FirebaseAnalyticsHelper.imageTransCameraEvent()
            needReshoot = true
        }
        binding.ivStillBack.setOnClickListener {
            showInstAdFromCache(MyApp.Config.image_camera_int_auto)
            finish()
        }
        binding.ivStillBuling.setOnClickListener {
            toggleFlash()
            updateFlashButtonUI()
        }
        binding.stillSourceLanguage.setOnClickListener {
            chooseLanguage = false
            bottomSheetDialog.show()
        }
        binding.stillTargetLanguage.setOnClickListener {
            chooseLanguage = true
            bottomSheetDialog.show()
        }
        binding.stillExChange.setOnClickListener {

            val currentSourceLanguage = PreferenceLanguageUtils.getString("language_source")
            val currentTargetLanguage = PreferenceLanguageUtils.getString("language_target")
            // 交换源语言和目标语言
            PreferenceLanguageUtils.putString("language_source", currentTargetLanguage)
            PreferenceLanguageUtils.putString("language_target", currentSourceLanguage)
            // 更新界面显示
            binding.stillSourceLanguage.text = currentTargetLanguage
            binding.stillTargetLanguage.text = currentSourceLanguage
            FirebaseAnalyticsHelper.textTransSwitchEvent(MyApp.Config.CLICK_FROM, "photo")

        }
    }

    private fun toggleFlash() {
        if (!::imageCapture.isInitialized) {
            Log.e(TAG, "ImageCapture is not initialized")
            return
        }

        imageCapture.flashMode =
            if (isFlashOn) ImageCapture.FLASH_MODE_OFF else ImageCapture.FLASH_MODE_ON
        isFlashOn = !isFlashOn
    }

    private fun updateFlashButtonUI() {
        binding.ivStillBuling.setImageResource(if (isFlashOn) R.drawable.ic_still_bulibuli else R.drawable.ic_still_notbuli)
    }

    private fun startCamera() {
        val previewView = findViewById<PreviewView>(R.id.photo_preview)
        cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        cameraProviderFuture.addListener(Runnable {
            val cameraProvider = cameraProviderFuture.get()
            val preview = Preview.Builder().build().also {
                it.setSurfaceProvider(previewView.surfaceProvider)
            }

            imageCapture = ImageCapture.Builder().setFlashMode(ImageCapture.FLASH_MODE_OFF).build()
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            try {
                cameraProvider.unbindAll()
                cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture)
            } catch (exc: Exception) {
                Log.e(TAG, "Use case binding failed", exc)
            }
        }, ContextCompat.getMainExecutor(this))
    }

    private fun takePhoto() {
        if (!::imageCapture.isInitialized) {
            Log.e(TAG, "ImageCapture is not initialized")
            return
        }
        fbFrom = "photo"
        val photoFile = File(
            outputDirectory,
            SimpleDateFormat(FILENAME_FORMAT, Locale.US).format(System.currentTimeMillis()) + ".jpg"
        )
        val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()

        imageCapture.takePicture(
            outputOptions,
            ContextCompat.getMainExecutor(this),
            object : ImageCapture.OnImageSavedCallback {
                override fun onError(exc: ImageCaptureException) {
                    Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
                }

                override fun onImageSaved(output: ImageCapture.OutputFileResults) {
                    imageUri = Uri.fromFile(photoFile)
                    Log.d(TAG, "Photo capture succeeded: $imageUri")
                    tryReloadAndDetectInImage()
                }
            })
    }

    private fun getOutputDirectory(): File {
        val mediaDir = externalMediaDirs.firstOrNull()?.let {
            File(it, resources.getString(R.string.app_name)).apply { mkdirs() }
        }
        return if (mediaDir != null && mediaDir.exists()) mediaDir else filesDir
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            REQUEST_CAMERA_PERMISSION -> {
                if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    startCamera()
                } else {
                    Toast.makeText(
                        this,
                        "Camera permission is required to use the camera",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        }
    }

    override fun onResume() {
        super.onResume()
        Log.d(TAG, "onResume")


        createImageProcessor()
        tryReloadAndDetectInImage()


    }

    override fun onPause() {
        super.onPause()
        imageProcessor?.stop()
    }

    override fun onDestroy() {
        super.onDestroy()
        imageProcessor?.stop()
        if (::cameraProviderFuture.isInitialized) {
            cameraProviderFuture.get().unbindAll()
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putParcelable(KEY_IMAGE_URI, imageUri)
        outState.putInt(KEY_IMAGE_MAX_WIDTH, imageMaxWidth)
        outState.putInt(KEY_IMAGE_MAX_HEIGHT, imageMaxHeight)
        outState.putString(KEY_SELECTED_SIZE, selectedSize)
    }

    private fun createImageProcessor() {
        imageProcessor?.stop()
        try {
            imageProcessor = when (selectedMode) {
                TEXT_RECOGNITION_CHINESE -> TextRecognitionProcessor(
                    this,
                    ChineseTextRecognizerOptions.Builder().build(), this
                )

                "Hindi", "Marathi", "Nepali", "Sanskrit" -> TextRecognitionProcessor(
                    this,
                    DevanagariTextRecognizerOptions.Builder().build(), this
                )

                TEXT_RECOGNITION_JAPANESE -> TextRecognitionProcessor(
                    this,
                    JapaneseTextRecognizerOptions.Builder().build(), this
                )

                TEXT_RECOGNITION_KOREAN -> TextRecognitionProcessor(
                    this,
                    KoreanTextRecognizerOptions.Builder().build(), this
                )

                else -> TextRecognitionProcessor(
                    this,
                    TextRecognizerOptions.Builder().build(), this
                )

            }
        } catch (e: Exception) {
            Log.e(TAG, "Can not create image processor: $selectedMode", e)
            Toast.makeText(
                applicationContext,
                "Can not create image processor: " + e.message,
                Toast.LENGTH_LONG
            ).show()
        }
    }

    private fun tryReloadAndDetectInImage() {
        try {
            if (imageUri == null) return
            if (SIZE_SCREEN == selectedSize && imageMaxWidth == 0) return

            val imageBitmap =
                BitmapUtils.getBitmapFromContentUri(contentResolver, imageUri) ?: return

            if (selectedSize == SIZE_SCREEN) {
                val targetedSize = targetedWidthHeight
                val scaleFactor = max(
                    imageBitmap.width.toFloat() / targetedSize.first.toFloat(),
                    imageBitmap.height.toFloat() / targetedSize.second.toFloat()
                )
                val resizedBitmap = Bitmap.createScaledBitmap(
                    imageBitmap,
                    (imageBitmap.width / scaleFactor).toInt(),
                    (imageBitmap.height / scaleFactor).toInt(),
                    true
                )
                binding.preview.setImageBitmap(resizedBitmap)
                processImage(resizedBitmap)
            } else {
                binding.preview.setImageBitmap(imageBitmap)
                processImage(imageBitmap)
            }
        } catch (e: IOException) {
            Log.e(TAG, "Error retrieving saved image")
            imageUri = null
        }
    }

    private val targetedWidthHeight: Pair<Int, Int>
        get() {
            val targetWidth = if (isLandScape) max(imageMaxWidth, imageMaxHeight) else min(
                imageMaxWidth,
                imageMaxHeight
            )
            val targetHeight = if (isLandScape) min(imageMaxWidth, imageMaxHeight) else max(
                imageMaxWidth,
                imageMaxHeight
            )
            return Pair(targetWidth, targetHeight)
        }

    private fun processImage(bitmap: Bitmap) {
        binding.graphicOverlay.clear()
        imageProcessor?.processBitmap(bitmap, binding.graphicOverlay)
    }

    private fun startChooseImageIntentForResult() {
        val intent = Intent().apply {
            type = "image/*"
            action = Intent.ACTION_GET_CONTENT
        }
        startActivityForResult(Intent.createChooser(intent, "Select Picture"), REQUEST_CHOOSE_IMAGE)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_CHOOSE_IMAGE && resultCode == Activity.RESULT_OK && data != null && data.data != null) {
            imageUri = data.data
            tryReloadAndDetectInImage()
        }
    }

    private fun backPressedCall() {
        val callback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                showInstAdFromCache(MyApp.Config.image_camera_int_auto)
                finish()
            }
        }
        onBackPressedDispatcher.addCallback(this, callback)
    }


    private fun adLoad(place: String) {
        // 加载广告
        LolAdWrapper.shared.loadAdIfNotCached(
            this,
            place,
            object : LolAdWrapper.LoLLoadListener {
                override fun loadFailed(error: LolLoadError?) {
                    // Log.d("dsas",error.toString())

                }

                override fun loaded() {
                    // 处理加载成功
                    //   Log.d("dsas","backSucc")
                }
            })

    }

    private fun showInstAdFromCache(place: String) {
        // 如果需要立刻展示广告，可以调用展示方法
        LolAdWrapper.shared.showAdIfCached(
            this,
            place,
            object : LolAdWrapper.LolShowListener {
                override fun shown() {
                    // 处理广告展示成功
                }

                override fun showFailed(error: LolShowError?) {
                    // 处理广告展示失败
                    finish()
                }

                override fun closed() {
                    // 处理广告关闭
                    finish()
                }
            })
    }


    companion object {
        private const val TAG = "StillImageActivity"
        private const val KEY_IMAGE_URI = "com.google.mlkit.demo.stillImage.KEY_IMAGE_URI"
        private const val KEY_IMAGE_MAX_WIDTH =
            "com.google.mlkit.demo.stillImage.KEY_IMAGE_MAX_WIDTH"
        private const val KEY_IMAGE_MAX_HEIGHT =
            "com.google.mlkit.demo.stillImage.KEY_IMAGE_MAX_HEIGHT"
        private const val KEY_SELECTED_SIZE = "com.google.mlkit.demo.stillImage.KEY_SELECTED_SIZE"
        private const val SIZE_SCREEN = "w:screen"
        private const val TEXT_RECOGNITION_CHINESE = "Chinese, Simplified"
        private const val TEXT_RECOGNITION_JAPANESE = "Japanese"
        private const val TEXT_RECOGNITION_KOREAN = "Korean"
        private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
        private const val REQUEST_CHOOSE_IMAGE = 1001
    }

    override fun onTextRecognized(text: Text, graphicOverlay: GraphicOverlay) {
        graphicOverlay.add(
            TextGraphic(
                graphicOverlay,
                text,
                true, true,
                fbFrom
            )
        )

    }

    override fun onTextFailure(e: Exception) {

    }


}

