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

import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.core.content.edit
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.all.pdfreader.pro.app.R
import com.all.pdfreader.pro.app.databinding.ActivitySearchPdfBinding
import com.all.pdfreader.pro.app.model.PdfPickerSource
import com.all.pdfreader.pro.app.model.PrintResult
import com.all.pdfreader.pro.app.ui.adapter.SearchPdfAdapter
import com.all.pdfreader.pro.app.ui.dialog.ListMoreDialogFragment
import com.all.pdfreader.pro.app.ui.dialog.PdfRemovePasswordDialog
import com.all.pdfreader.pro.app.ui.dialog.PdfSetPasswordDialog
import com.all.pdfreader.pro.app.ui.dialog.PromptDialogFragment
import com.all.pdfreader.pro.app.util.AppUtils.printPdfFile
import com.all.pdfreader.pro.app.util.AppUtils.showKeyboard
import com.all.pdfreader.pro.app.util.ToastUtils
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.json.JSONArray
import java.io.File
import java.io.Serializable

class SearchActivity : BaseActivity() {
    override val TAG: String = "SearchActivity"

    companion object {
        const val FRAG_TAG = "SearchActivity"
        private const val PREF_SEARCH_HISTORY = "pref_search_history"
        private const val KEY_HISTORY_LIST = "key_history_list_json"
        private const val EXTRA_SOURCE = "extra_source"
        const val EXTRA_SELECTED_PATH = "extra_selected_path"

        fun createIntent(context: Context, source: PdfPickerSource): Intent {
            return Intent(context, SearchActivity::class.java).apply {
                putExtra(EXTRA_SOURCE, source)
            }
        }
    }

    private lateinit var binding: ActivitySearchPdfBinding
    private lateinit var adapter: SearchPdfAdapter
    private val pdfRepository = getRepository()
    private var searchJob: Job? = null

    private val searchHistory: MutableList<String> = mutableListOf()
    private lateinit var sp: SharedPreferences
    private lateinit var source: PdfPickerSource // 来源

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivitySearchPdfBinding.inflate(layoutInflater)
        setContentView(binding.root)
        source = getSerializableOrDefault(EXTRA_SOURCE, PdfPickerSource.NONE)
        sp = getSharedPreferences(PREF_SEARCH_HISTORY, MODE_PRIVATE)
        loadHistory()

        initView()
        setupClick()
        showHistory()
    }

    private fun setupClick() {
        binding.backBtn.setOnClickListener { finish() }

        binding.searchEdit.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
            override fun afterTextChanged(s: Editable?) {
                val query = s?.toString().orEmpty()
                binding.deleteIv.visibility = if (query.isEmpty()) View.GONE else View.VISIBLE
                binding.searchIv.visibility = if (query.isEmpty()) View.VISIBLE else View.GONE

                if (query.isEmpty()) {
                    showHistory()
                    adapter.updateData(emptyList())
                    binding.noFilesLayout.visibility = View.GONE
                    return
                } else {
                    binding.historyLayout.visibility = View.GONE
                }

                searchJob?.cancel()
                searchJob = lifecycleScope.launch {
                    delay(150)
                    pdfRepository.searchDocuments(query).collectLatest { list ->
                        if (list.isNotEmpty()) {
                            // 再根据来源过滤
                            val displayList = when (source) {
                                PdfPickerSource.LOCK -> list.filter { !it.isPassword }//只展示没有被加密的
                                PdfPickerSource.UNLOCK -> list.filter { it.isPassword }//只展示已经被加密的
                                else -> list
                            }
                            adapter.updateData(displayList) {
                                adapter.highlightItems(query.trim())
                            }
                            binding.noFilesLayout.visibility = View.GONE
                        } else {
                            adapter.updateData(emptyList())
                            binding.noFilesLayout.visibility = View.VISIBLE
                        }
                    }
                }
            }
        })

        binding.deleteIv.setOnClickListener {
            binding.searchEdit.apply {
                setText("")
                clearComposingText()
                setSelection(0)
            }
        }

        binding.clearHistory.setOnClickListener {
            PromptDialogFragment(
                getString(R.string.tip),
                getString(R.string.clear_history_desc),
                getString(R.string.clear),
                onOkClick = {
                    searchHistory.clear()
                    saveHistoryList() // 保存空列表
                    showHistory()
                }).show(supportFragmentManager, "clearHistory")
        }
    }

    private fun initView() {
        binding.searchEdit.showKeyboard()
        adapter = SearchPdfAdapter(onItemClick = { pdf ->
            when (source) {
                PdfPickerSource.NONE -> {
                    val intent = PdfViewActivity.createIntent(this, pdf.filePath)
                    startActivity(intent)
                    finish()
                    val query = binding.searchEdit.text.toString()
                    if (query.isNotEmpty()) saveHistory(query)
                }

                PdfPickerSource.MERGE -> {
                    val data = Intent().apply { putExtra(EXTRA_SELECTED_PATH, pdf.filePath) }
                    setResult(RESULT_OK, data)
                    finish()
                }

                PdfPickerSource.SPLIT -> {
                    val intent = SplitPdfActivity.createIntent(this, pdf.filePath)
                    startActivity(intent)
                    setResult(RESULT_OK)//通知选择界面关闭
                    finish()
                }

                PdfPickerSource.LOCK -> {
                    PdfSetPasswordDialog(onOkClick = { password ->
                        val intent = PdfResultActivity.createIntentLock(
                            this, pdf.filePath, password, PdfPickerSource.LOCK
                        )
                        startActivity(intent)
                        setResult(RESULT_OK)//通知选择界面关闭
                        finish()
                    }).show(supportFragmentManager, "PdfSetPasswordDialog")
                }

                PdfPickerSource.UNLOCK -> {
                    PdfRemovePasswordDialog(pdf.filePath, onOkClick = { password ->
                        val intent = PdfResultActivity.createIntentLock(
                            this, pdf.filePath, password, PdfPickerSource.UNLOCK
                        )
                        startActivity(intent)
                        setResult(RESULT_OK)
                        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.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 -> {

                        }
                    }
                }
            }
        }, onMoreClick = { pdf ->
            ListMoreDialogFragment(pdf.filePath).show(supportFragmentManager, FRAG_TAG)
        })

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

    /** 搜索历史逻辑 **/
    private fun loadHistory() {
        val json = sp.getString(KEY_HISTORY_LIST, "[]")
        val array = JSONArray(json)
        searchHistory.clear()
        for (i in 0 until array.length()) {
            searchHistory.add(array.getString(i))
        }
    }

    private fun saveHistory(query: String) {
        if (searchHistory.contains(query)) searchHistory.remove(query)
        searchHistory.add(0, query)
        if (searchHistory.size > 20) searchHistory.removeAt(searchHistory.size - 1)
        saveHistoryList()
    }

    private fun saveHistoryList() {
        val json = JSONArray(searchHistory).toString()
        sp.edit { putString(KEY_HISTORY_LIST, json) }
    }

    private fun showHistory() {
        binding.historyFlexLayout.removeAllViews()
        if (searchHistory.isEmpty()) {
            binding.historyLayout.visibility = View.GONE
            return
        }
        binding.historyLayout.visibility = View.VISIBLE
        val inflater = LayoutInflater.from(this)

        searchHistory.forEach { keyword ->
            val tagView = inflater.inflate(
                R.layout.item_history_tag, binding.historyFlexLayout, false
            ) as TextView
            tagView.text = keyword
            tagView.setOnClickListener {
                binding.searchEdit.setText(keyword)
                binding.searchEdit.setSelection(keyword.length)
            }

            binding.historyFlexLayout.addView(tagView)
        }
    }

    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
    }
}
