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

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.all.pdfreader.pro.app.R
import com.all.pdfreader.pro.app.databinding.ActivityPdfPickerBinding
import com.all.pdfreader.pro.app.model.PdfPickerSource
import com.all.pdfreader.pro.app.model.PrintResult
import com.all.pdfreader.pro.app.model.SortConfig
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
import com.all.pdfreader.pro.app.room.repository.PdfRepository
import com.all.pdfreader.pro.app.ui.adapter.PdfAdapter
import com.all.pdfreader.pro.app.ui.dialog.PdfRemovePasswordDialog
import com.all.pdfreader.pro.app.ui.dialog.PdfSetPasswordDialog
import com.all.pdfreader.pro.app.util.AppUtils.printPdfFile
import com.all.pdfreader.pro.app.util.AppUtils.setClickWithAnimation
import com.all.pdfreader.pro.app.util.AppUtils.setOnSingleClickListener
import com.all.pdfreader.pro.app.util.ToastUtils
import kotlinx.coroutines.launch
import java.io.File
import java.io.Serializable

class PdfPickerActivity : BaseActivity() {
    override val TAG: String = "PdfPickerActivity"
    private lateinit var binding: ActivityPdfPickerBinding
    private lateinit var adapter: PdfAdapter
    private lateinit var source: PdfPickerSource // 保存来源
    private var showCheckButton = false
    private var isMultiSelectMode = false
    private var fromActivityResult: String = ""
    private lateinit var historyList: ArrayList<PdfDocumentEntity>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityPdfPickerBinding.inflate(layoutInflater)
        setContentView(binding.root)
        source = getSerializableOrDefault(EXTRA_SOURCE, PdfPickerSource.NONE)
        if (source == PdfPickerSource.NONE) {
            showToast(getString(R.string.unknown_source))
            finish()
        }
        fromActivityResult = intent.getStringExtra(EXTRA_FROM) ?: ""
        historyList = requireParcelableArrayList(EXTRA_HISTORY_LIST)
        updateViewAndState()
        initView()
        setupClick()
        initData()
    }

    private fun updateViewAndState(number: Int = 0) {
        if (source == PdfPickerSource.MERGE) {
            binding.title.text = getString(R.string.selected_page, number)
            binding.continueNowBtn.visibility = View.VISIBLE
            updateContinueNowBtnState(number >= 2)
        } else {
            binding.title.text = getString(R.string.please_select_a_file)
            binding.continueNowBtn.visibility = View.GONE
        }
    }

    private fun initView() {
        if (source == PdfPickerSource.MERGE) {
            showCheckButton = true
            isMultiSelectMode = true
        } else {
            showCheckButton = false
            isMultiSelectMode = false
        }
        adapter = PdfAdapter(
            pdfList = mutableListOf(),
            onItemClick = { pdf ->
                when (source) {
                    PdfPickerSource.MERGE -> {}
                    PdfPickerSource.SPLIT -> {
                        val intent = SplitPdfActivity.createIntent(this, pdf.filePath)
                        startActivity(intent)
                        finish()
                    }

                    PdfPickerSource.LOCK -> {
                        PdfSetPasswordDialog(onOkClick = { password ->
                            val intent = PdfResultActivity.createIntentLock(
                                this, pdf.filePath, password,
                                PdfPickerSource.LOCK
                            )
                            startActivity(intent)
                            finish()
                        }).show(supportFragmentManager, "PdfSetPasswordDialog")
                    }

                    PdfPickerSource.UNLOCK -> {
                        PdfRemovePasswordDialog(pdf.filePath, onOkClick = { password ->
                            val intent = PdfResultActivity.createIntentLock(
                                this, pdf.filePath, password,
                                PdfPickerSource.UNLOCK
                            )
                            startActivity(intent)
                            finish()
                        }).show(supportFragmentManager, "PdfRemovePasswordDialog")
                    }

                    PdfPickerSource.IMAGES_TO_PDF -> {}
                    PdfPickerSource.TO_LONG_IMAGE -> {
                        val intent = PdfToImageActivity.createIntent(this, pdf.filePath,
                            PdfPickerSource.TO_LONG_IMAGE)
                        startActivity(intent)
                        finish()
                    }
                    PdfPickerSource.NONE -> {}
                    PdfPickerSource.PDF_TO_IMAGES -> {
                        val intent = PdfToImageActivity.createIntent(this, pdf.filePath,
                            PdfPickerSource.PDF_TO_IMAGES)
                        startActivity(intent)
                        finish()
                    }

                    PdfPickerSource.PRINT ->{
                        val result = printPdfFile(this, Uri.fromFile(File(pdf.filePath)))
                        when (result) {
                            PrintResult.DeviceNotSupported -> {
                                ToastUtils.show(this,getString(R.string.device_does_not_support_printing))
                            }

                            is PrintResult.Error -> {
                                ToastUtils.show(this,getString(R.string.pdf_cannot_print_error))
                            }

                            PrintResult.MalformedPdf -> {
                                ToastUtils.show(this,getString(R.string.cannot_print_malformed_pdf))
                            }

                            PrintResult.PasswordRequired -> {
                                ToastUtils.show(this,getString(R.string.pdf_cant_print_password_protected))
                            }

                            PrintResult.Success -> {

                            }
                        }
                    }
                }
            },
            onSelectModelItemClick = {
                if (source == PdfPickerSource.MERGE) {
                    val selectedItems = adapter.getSelectedItems()
                    updateViewAndState(selectedItems.size)
                }
            },
            enableLongClick = false,
            showMoreButton = false,
            showCheckButton = showCheckButton,
            isMultiSelectMode = isMultiSelectMode
        )

        binding.recyclerView.layoutManager = LinearLayoutManager(this)
        binding.recyclerView.adapter = adapter
    }

    private fun initData() {
        lifecycleScope.launch {
            PdfRepository.getInstance().getAllDocuments().collect { list ->
                if (list.isEmpty()) {
                    binding.noFilesLayout.visibility = View.VISIBLE
                    return@collect
                }
                val sortedList = sortDocuments(list)
                // 标记已选择项，从合并界面进入到选择进行合并选项，从外部dialog进入也进行合并选项
                if (fromActivityResult == MergePdfActivity.TAG || fromActivityResult == MergePdfActivity.TAG_TOW) {
                    markSelectedItems(sortedList, historyList)
                }
                // 再根据来源过滤
                val displayList = when (source) {
                    PdfPickerSource.LOCK -> sortedList.filter { !it.isPassword }//只展示没有被加密的
                    PdfPickerSource.UNLOCK -> sortedList.filter { it.isPassword }//只展示已经被加密的
                    else -> sortedList
                }

                adapter.updateData(displayList)
                binding.noFilesLayout.visibility =
                    if (displayList.isEmpty()) View.VISIBLE else View.GONE
                val selectedItems = adapter.getSelectedItems()
                updateViewAndState(selectedItems.size)
            }
        }
    }

    private fun markSelectedItems(
        sortedList: List<PdfDocumentEntity>, historyList: List<PdfDocumentEntity>
    ) {
        val historyMap = historyList.associateBy { it.filePath }
        sortedList.forEach { item ->
            val historyItem = historyMap[item.filePath]
            if (historyItem != null) {
                item.isSelected = true
                // 同步历史密码
                item.password = historyItem.password
            } else {
                item.isSelected = false
            }
        }
    }

    private val searchLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            if (result.resultCode == RESULT_OK) {
                if (source == PdfPickerSource.MERGE) {
                    val selectedPath =
                        result.data?.getStringExtra(SearchActivity.EXTRA_SELECTED_PATH)
                    val currentList = adapter.getCurrentList().toMutableList()
                    val selectedItemIndex = currentList.indexOfFirst { it.filePath == selectedPath }
                    if (selectedItemIndex != -1) {
                        // 找到选中项
                        val selectedItem = currentList[selectedItemIndex]
                        selectedItem.isSelected = true
                        // 移动到第一位
                        currentList.removeAt(selectedItemIndex)
                        currentList.add(0, selectedItem)

                        adapter.updateData(currentList)
                    }
                    val selectedItems = adapter.getSelectedItems()
                    updateViewAndState(selectedItems.size)
                } else {
                    // 只有非多选的情况才关闭
                    // 这里主要是为了只有通过这边进入搜索界面后，在搜索界面点击了item后finish前面这个act
                    finish()
                }
            }
        }

    private fun openSearch() {
        val intent = SearchActivity.createIntent(this, source)
        searchLauncher.launch(intent)
    }

    private fun setupClick() {
        binding.backBtn.setOnSingleClickListener { finish() }
        binding.searchBtn.setClickWithAnimation {
            openSearch()
        }
        binding.continueNowBtn.setOnSingleClickListener {
            val selectedItems = adapter.getSelectedItems()
            if (selectedItems.size >= 2) {
                //从dialog点击进来的，就不进行result了。直接进入合并界面
                if (fromActivityResult == MergePdfActivity.TAG) {
                    returnSelectedResult(ArrayList(selectedItems))
                } else {
                    val intent = MergePdfActivity.createIntent(this, ArrayList(selectedItems))
                    startActivity(intent)
                    finish()
                }
            }
        }

    }

    private fun returnSelectedResult(selectedList: ArrayList<PdfDocumentEntity>) {
        val intent = Intent().apply {
            putParcelableArrayListExtra(MergePdfActivity.EXTRA_SELECTED_LIST, selectedList)
        }
        setResult(RESULT_OK, intent)
        finish()
    }

    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 sortDocuments(documents: List<PdfDocumentEntity>): List<PdfDocumentEntity> {
        val sortConfig = SortConfig.fromPreferenceString(appStore.documentSortType)
        return sortConfig.applySort(documents)
    }

    companion object {
        private const val EXTRA_SOURCE = "extra_source"
        private const val EXTRA_FROM = "extra_from"//从哪儿来
        private const val EXTRA_HISTORY_LIST = "extra_history_list"//已经有选中的数据

        fun createIntent(
            context: Context,
            source: PdfPickerSource,
            from: String = "",
            list: ArrayList<PdfDocumentEntity> = arrayListOf()
        ): Intent {
            return Intent(context, PdfPickerActivity::class.java).apply {
                putExtra(EXTRA_SOURCE, source)
                putExtra(EXTRA_FROM, from)
                putParcelableArrayListExtra(EXTRA_HISTORY_LIST, list)
            }
        }
    }

    @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)
        }
        return result ?: arrayListOf()
    }

    private inline fun <reified T : Serializable> getSerializableOrDefault(
        key: String, default: T
    ): T {
        val result: T? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            intent.getSerializableExtra(key, T::class.java)
        } else {
            @Suppress("DEPRECATION") intent.getSerializableExtra(key) as? T
        }
        return result ?: default
    }

}
