package com.all.pdfreader.pro.app.ui.act

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import androidx.activity.OnBackPressedCallback
import androidx.activity.result.contract.ActivityResultContract
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.all.pdfreader.pro.app.R
import com.all.pdfreader.pro.app.databinding.ActivityPdfMergeBinding
import com.all.pdfreader.pro.app.model.PdfPickerSource
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
import com.all.pdfreader.pro.app.ui.adapter.PdfAdapter
import com.all.pdfreader.pro.app.ui.dialog.PdfPasswordProtectionDialogFragment
import com.all.pdfreader.pro.app.ui.dialog.PromptDialogFragment
import com.all.pdfreader.pro.app.util.AppUtils.setClickWithAnimation
import com.all.pdfreader.pro.app.util.AppUtils.setOnSingleClickListener
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import java.io.File

class MergePdfActivity : BaseActivity() {
    override val TAG: String = "MergePdfActivity"
    private lateinit var binding: ActivityPdfMergeBinding
    private var selectedList: ArrayList<PdfDocumentEntity> = arrayListOf()
    private lateinit var adapter: PdfAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityPdfMergeBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setupBackPressedCallback()
        val list: ArrayList<PdfDocumentEntity> = requireParcelableArrayList(EXTRA_PDF_LIST)
        updateContinueNowBtnState(list.size >= 2)
        lifecycleScope.launch {
            handlePasswordProtectedPdfs(list) {
                list.forEach {
                    logDebug("onCreate password->${it.password}")
                    logDebug("onCreate isPassword->${it.isPassword}")
                }
                selectedList.clear()
                selectedList.addAll(list)
                initView()
                setupClick()
            }
        }
    }

    /**
     * 遍历集合，弹出密码对话框并更新 password 字段
     */
    private suspend fun handlePasswordProtectedPdfs(
        pdfList: ArrayList<PdfDocumentEntity>,
        onAllPasswordsReady: (ArrayList<PdfDocumentEntity>) -> Unit
    ) {
        for (pdf in pdfList) {
            if (pdf.isPassword && pdf.password.isNullOrEmpty()) {
                val pwd = showPasswordDialogSuspend(File(pdf.filePath)) ?: run {
                    finish()
                    return
                }
                pdf.password = pwd
            }
        }
        onAllPasswordsReady(pdfList)
    }

    /**
     * 将 DialogFragment 封装成 suspend 函数
     */
    private suspend fun showPasswordDialogSuspend(file: File): String? =
        suspendCancellableCoroutine { cont ->
            PdfPasswordProtectionDialogFragment(
                file,
                onOkClick = { password ->
                    if (cont.isActive) {
                        cont.resumeWith(Result.success(password))
                    }
                },
                onCancelClick = {
                    if (cont.isActive) {
                        cont.resumeWith(Result.success(null))
                    }
                }, isPrompt = true
            ).show(supportFragmentManager, TAG)
        }

    private fun initView() {
        adapter = PdfAdapter(
            pdfList = selectedList,
            onDeleteItemClick = { item, position ->
                adapter.removeItem(position)
                selectedList.remove(item)
                updateContinueNowBtnState(selectedList.size >= 2)
            },
            enableLongClick = false,
            showMoreButton = false,
            showCheckButton = false,
            isMultiSelectMode = false,
            showDeleteButton = true
        )
        binding.recyclerView.layoutManager = LinearLayoutManager(this)
        binding.recyclerView.adapter = adapter
    }

    private fun setupClick() {
        binding.backBtn.setOnSingleClickListener { onBackPressedDispatcher.onBackPressed() }
        binding.addBtn.setClickWithAnimation {
            openPicker()
        }
        binding.continueNowBtn.setOnSingleClickListener {
            val intent = PdfResultActivity.createIntentMergePdfActivityToResult(
                this, selectedList, PdfPickerSource.MERGE
            )
            startActivity(intent)
            finish()
        }
    }

    private val pickPdfLauncher =
        registerForActivityResult(PickPdfContract(Companion.TAG)) { list ->
            if (list.isNotEmpty()) {
                handleSelectedPdfs(list as ArrayList<PdfDocumentEntity>)
            }
        }

    private fun openPicker() {
        pickPdfLauncher.launch(PdfPickerSource.MERGE to selectedList)
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun handleSelectedPdfs(list: ArrayList<PdfDocumentEntity>) {
        lifecycleScope.launch {
            handlePasswordProtectedPdfs(list) {
                list.forEach {
                    logDebug("handleSelectedPdfs password->${it.password}")
                    logDebug("handleSelectedPdfs isPassword->${it.isPassword}")
                }
                selectedList.clear()
                selectedList.addAll(list)
                adapter.notifyDataSetChanged()
                updateContinueNowBtnState(selectedList.size >= 2)
            }
        }
    }

    private fun updateContinueNowBtnState(b: Boolean) {
        binding.continueNowBtn.setBackgroundResource(
            if (b) R.drawable.dr_click_btn_bg
            else R.drawable.dr_btn_not_clickable_bg
        )
        binding.continueNowBtn.isEnabled = b
    }

    private fun setupBackPressedCallback() {
        onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                PromptDialogFragment(
                    getString(R.string.exit_merge),
                    getString(R.string.confirm_discard_changes),
                    getString(R.string.discard),
                    onOkClick = {
                        isEnabled = false
                        onBackPressedDispatcher.onBackPressed()
                    }).show(supportFragmentManager, getString(R.string.exit_split))
            }
        })
    }


    companion object {
        const val EXTRA_SELECTED_LIST = "extra_selected_list"
        const val EXTRA_PDF_LIST = "extra_pdf_list"
        const val TAG = "MergePdfActivity"
        const val TAG_TOW = "MergePdfActivity_DIALOG"//标记从dialog进入

        fun createIntent(context: Context, list: ArrayList<PdfDocumentEntity>): Intent {
            return Intent(context, MergePdfActivity::class.java).apply {
                putParcelableArrayListExtra(EXTRA_PDF_LIST, list)
            }
        }
    }

    /**
     * 通用方法：读取必传参数，如果为 null 直接 finish
     */
    @Suppress("DEPRECATION")
    private inline fun <reified T : Parcelable> requireParcelableArrayList(key: String): ArrayList<T> {
        val result: ArrayList<T>? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            intent.getParcelableArrayListExtra(key, T::class.java)
        } else {
            intent.getParcelableArrayListExtra(key)
        }

        if (result.isNullOrEmpty()) {
            showToast(getString(R.string.pdf_loading_failed))
            finish()
        }
        return result ?: arrayListOf()
    }

    class PickPdfContract(
        private val from: String
    ) : ActivityResultContract<Pair<PdfPickerSource, ArrayList<PdfDocumentEntity>>, List<PdfDocumentEntity>>() {

        override fun createIntent(
            context: Context, input: Pair<PdfPickerSource, ArrayList<PdfDocumentEntity>>
        ): Intent {
            val (source, historyList) = input
            return PdfPickerActivity.createIntent(context, source, from, historyList)
        }

        override fun parseResult(resultCode: Int, intent: Intent?): List<PdfDocumentEntity> {
            if (resultCode != RESULT_OK || intent == null) return emptyList()
            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                intent.getParcelableArrayListExtra(
                    EXTRA_SELECTED_LIST, PdfDocumentEntity::class.java
                ) ?: emptyList()
            } else {
                @Suppress("DEPRECATION") intent.getParcelableArrayListExtra<PdfDocumentEntity>(
                    EXTRA_SELECTED_LIST
                ) ?: emptyList()
            }
        }
    }


}
