package com.base.pdfviewerscannerwhite.ui.view

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.core.widget.addTextChangedListener
import com.base.pdfviewerscannerwhite.R
import com.base.pdfviewerscannerwhite.ads.admob.AdmobNativeUtils
import com.base.pdfviewerscannerwhite.bean.ConstObject.UI_SORT_FINAL_MODIFIED
import com.base.pdfviewerscannerwhite.bean.ConstObject.UI_SORT_LAST_MODIFIED
import com.base.pdfviewerscannerwhite.bean.ConstObject.UI_SORT_NAME_A_Z
import com.base.pdfviewerscannerwhite.bean.ConstObject.UI_SORT_NAME_Z_A
import com.base.pdfviewerscannerwhite.bean.ConstObject.setDefault
import com.base.pdfviewerscannerwhite.bean.DocumentBean
import com.base.pdfviewerscannerwhite.bean.DocumentBean.Companion.TYPE_EXCEL
import com.base.pdfviewerscannerwhite.bean.DocumentBean.Companion.TYPE_PPT
import com.base.pdfviewerscannerwhite.bean.DocumentBean.Companion.TYPE_WORD
import com.base.pdfviewerscannerwhite.databinding.DialogAppExitBinding
import com.base.pdfviewerscannerwhite.databinding.DialogCommonTipBinding
import com.base.pdfviewerscannerwhite.databinding.DialogDefaultBottomBinding
import com.base.pdfviewerscannerwhite.databinding.DialogDefaultUpBinding
import com.base.pdfviewerscannerwhite.databinding.DialogDeleteBinding
import com.base.pdfviewerscannerwhite.databinding.DialogDocumentDetailBinding
import com.base.pdfviewerscannerwhite.databinding.DialogDocumentHomeMoreBinding
import com.base.pdfviewerscannerwhite.databinding.DialogDocumentMoreBinding
import com.base.pdfviewerscannerwhite.databinding.DialogDocumentRenameBinding
import com.base.pdfviewerscannerwhite.databinding.DialogNotificationEnableBinding
import com.base.pdfviewerscannerwhite.databinding.DialogPageNumberBinding
import com.base.pdfviewerscannerwhite.databinding.DialogSortBinding
import com.base.pdfviewerscannerwhite.databinding.DialogStoragePermissionBinding
import com.base.pdfviewerscannerwhite.ui.main.DocumentFragment
import com.base.pdfviewerscannerwhite.ui.main.DocumentPageFragment
import com.base.pdfviewerscannerwhite.ui.main.MainActivity
import com.base.pdfviewerscannerwhite.ui.view.DialogView.showNotificationDialog
import com.base.pdfviewerscannerwhite.utils.ActivityLauncher
import com.base.pdfviewerscannerwhite.utils.IntentShareUtils.documentShare
import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatSize
import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatTime2
import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatTime3
import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatTime4
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkNotificationPermission
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkStorePermission
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.requestStoragePermission
import com.base.pdfviewerscannerwhite.utils.SpStringUtils
import com.base.pdfviewerscannerwhite.utils.SpStringUtils.LAST_VIEW_KEY
import com.base.pdfviewerscannerwhite.utils.ToastUtils.toast
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import java.io.File

object DialogView {

    fun Context.showStoragePermission(
        launcher: ActivityLauncher,
        launcherAction: ((flag: Boolean) -> Unit)? = null,
        noLauncherAction: (() -> Unit)? = null,
        dismissAction: (() -> Unit)? = null,
    ): BottomSheetDialog {
        val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
        val binding = DialogStoragePermissionBinding.inflate(LayoutInflater.from(this))
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)

        dialog.show()

        val parentView = binding.root.parent as View
        val behavior = BottomSheetBehavior.from(parentView)
        //展开
        behavior.state = BottomSheetBehavior.STATE_EXPANDED

        binding.tvSet.setOnClickListener {
            dialog.dismiss()
            requestStoragePermission(launcher) {
                launcherAction?.invoke(it)
            }
        }
        binding.tvContinue.setOnClickListener {
            dialog.dismiss()
            noLauncherAction?.invoke()
        }
        dialog.setOnDismissListener {
            dismissAction?.invoke()
        }
        return dialog
    }

    var SortMode = UI_SORT_LAST_MODIFIED
    fun Context.showSortDialog(okAction: () -> Unit) {
        val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
        val binding = DialogSortBinding.inflate(LayoutInflater.from(this))
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)

        dialog.show()

        val parentView = binding.root.parent as View
        val behavior = BottomSheetBehavior.from(parentView)
        //展开
        behavior.state = BottomSheetBehavior.STATE_EXPANDED

        val showSortUI: (mode: String) -> Unit = { mode ->
            when (mode) {
                UI_SORT_LAST_MODIFIED -> {
                    binding.iv1.visibility = View.VISIBLE
                    binding.tv1.setTextColor(Color.parseColor("#00B8DE"))
                }

                UI_SORT_FINAL_MODIFIED -> {
                    binding.iv2.visibility = View.VISIBLE
                    binding.tv2.setTextColor(Color.parseColor("#00B8DE"))
                }

                UI_SORT_NAME_A_Z -> {
                    binding.iv3.visibility = View.VISIBLE
                    binding.tv3.setTextColor(Color.parseColor("#00B8DE"))
                }

                UI_SORT_NAME_Z_A -> {
                    binding.iv4.visibility = View.VISIBLE
                    binding.tv4.setTextColor(Color.parseColor("#00B8DE"))
                }
            }
        }
        val resetUI = {
            binding.iv1.visibility = View.INVISIBLE
            binding.iv2.visibility = View.INVISIBLE
            binding.iv3.visibility = View.INVISIBLE
            binding.iv4.visibility = View.INVISIBLE

            binding.tv1.setTextColor(Color.parseColor("#333333"))
            binding.tv2.setTextColor(Color.parseColor("#333333"))
            binding.tv3.setTextColor(Color.parseColor("#333333"))
            binding.tv4.setTextColor(Color.parseColor("#333333"))
        }

        showSortUI.invoke(SortMode)

        var temp: String = SortMode
        binding.llLastModified.setOnClickListener {
            temp = UI_SORT_LAST_MODIFIED
            resetUI.invoke()
            showSortUI.invoke(temp)
        }
        binding.llFinalModified.setOnClickListener {
            temp = UI_SORT_FINAL_MODIFIED
            resetUI.invoke()
            showSortUI.invoke(temp)
        }
        binding.llNameAZ.setOnClickListener {
            temp = UI_SORT_NAME_A_Z
            resetUI.invoke()
            showSortUI.invoke(temp)
        }
        binding.llNameZA.setOnClickListener {
            temp = UI_SORT_NAME_Z_A
            resetUI.invoke()
            showSortUI.invoke(temp)
        }
        binding.tvCancel.setOnClickListener {
            dialog.dismiss()
        }
        binding.tvOk.setOnClickListener {
            dialog.dismiss()
            SortMode = temp
            okAction.invoke()
        }
    }

    fun Context.showDocumentDetail(path: String) {
        val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
        val binding = DialogDocumentDetailBinding.inflate(LayoutInflater.from(this))
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)

        dialog.show()

        val parentView = binding.root.parent as View
        val behavior = BottomSheetBehavior.from(parentView)
        //展开
        behavior.state = BottomSheetBehavior.STATE_EXPANDED

        val file = File(path)
        binding.tvName.text = file.name
        binding.tvPath.text = file.absolutePath
        val lastView = SpStringUtils.getSpStringList(LAST_VIEW_KEY).find { it.contains(file.absolutePath) }
        if (lastView != null) {
            val lastTime = lastView.split("_/_")[1]
            binding.tvLastView.text = lastTime.toLong().toFormatTime3()
        } else {
            binding.tvLastView.text = file.lastModified().toFormatTime3()
        }
        binding.tvLastChange.text = file.lastModified().toFormatTime3()
        binding.tvFileSize.text = file.length().toFormatSize()

        binding.tvBtnOk.setOnClickListener {
            dialog.dismiss()
        }

    }

    @SuppressLint("SetTextI18n", "NotifyDataSetChanged")
    fun Context.showDocumentHomeMoreDialog(
        item: DocumentBean,
        mainActivity: MainActivity,
        documentFragment: DocumentFragment,
        documentPageFragment: DocumentPageFragment,
    ): BottomSheetDialog {
        val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
        val binding = DialogDocumentHomeMoreBinding.inflate(LayoutInflater.from(this))
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)

        dialog.show()

        val parentView = binding.root.parent as View
        val behavior = BottomSheetBehavior.from(parentView)
        //展开
        behavior.state = BottomSheetBehavior.STATE_EXPANDED

        val file = File(item.path)
        binding.tvName.text = file.name
        binding.tvInfo.text = file.lastModified().toFormatTime4() + " " + file.length().toFormatSize()
        if (item.isBookmarked) {
            binding.ivBookmark.setImageResource(R.mipmap.h_soucang_s)
        } else {
            binding.ivBookmark.setImageResource(R.mipmap.h_soucang_n)
        }
        when (item.type) {
            TYPE_WORD -> {
                binding.ivDocument.setImageResource(R.mipmap.h_wordfiocn)
            }

            TYPE_EXCEL -> {
                binding.ivDocument.setImageResource(R.mipmap.h_exceliocn)
            }

            TYPE_PPT -> {
                binding.ivDocument.setImageResource(R.mipmap.h_pptfiocn)
            }
        }
        binding.llRename.setOnClickListener {
            showDocumentRenameDialog(file.name, okAction = { newName ->
                dialog.dismiss()
                mainActivity.mainPresenter.renameDocumentBean(file, newName, documentPageFragment)
            })
        }
        binding.llDetail.setOnClickListener {
            showDocumentDetail(item.path)
        }
        binding.llShare.setOnClickListener {
            documentShare(item)
        }
        binding.llDelete.setOnClickListener {
            dialog.dismiss()
            showDeleteDialog {
                mainActivity.mainPresenter.deleteDocument(item.path, documentPageFragment)
                documentFragment.searchDeleteDocument(item)
            }
        }
        return dialog
    }


    fun Activity.showDocumentMore(
        documentBean: DocumentBean,
        pageNumber: Int = 0,
        jumpAction: ((pageIndex: Int) -> Unit)? = null
    ) {
        val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
        val binding = DialogDocumentMoreBinding.inflate(LayoutInflater.from(this))
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)

        dialog.show()

        val parentView = binding.root.parent as View
        val behavior = BottomSheetBehavior.from(parentView)
        //展开
        behavior.state = BottomSheetBehavior.STATE_EXPANDED

        if (documentBean.type == TYPE_EXCEL) {
            binding.llJump.visibility = View.GONE
        }

        if (documentBean.isBookmarked) {
            binding.ivBookmark.setImageResource(R.mipmap.h_soucang_s)
        } else {
            binding.ivBookmark.setImageResource(R.mipmap.h_soucang_n)
        }

        binding.ivBookmark.setOnClickListener {
            binding.ivBookmark.isSelected = !binding.ivBookmark.isSelected

            if (binding.ivBookmark.isSelected) {
                binding.ivBookmark.setImageResource(R.mipmap.h_soucang_s)
                SpStringUtils.addSpString(SpStringUtils.BOOKMARK_KEY, documentBean.path)
            } else {
                binding.ivBookmark.setImageResource(R.mipmap.h_soucang_n)
                SpStringUtils.deleteSpString(SpStringUtils.BOOKMARK_KEY, documentBean.path)
            }
        }
        binding.llDetail.setOnClickListener {
            showDocumentDetail(documentBean.path)
        }
        binding.llShare.setOnClickListener {
            documentShare(documentBean)
        }
        binding.llJump.setOnClickListener {
            showJumpPageNumberDialog(pageNumber) { pageIndex ->
                dialog.dismiss()
                jumpAction?.invoke(pageIndex)
            }
        }

    }


    fun Context.showJumpPageNumberDialog(pageNumber: Int, okAction: ((pageIndex: Int) -> Unit)?) {
        val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
        val binding = DialogPageNumberBinding.inflate(LayoutInflater.from(this))
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)

        val window = dialog.window
        window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)

        dialog.show()

        val parentView = binding.root.parent as View
        val behavior = BottomSheetBehavior.from(parentView)
        //展开
        behavior.state = BottomSheetBehavior.STATE_EXPANDED

        binding.edit.filters = arrayOf(NumberRangeFilter(1, pageNumber + 1))
        binding.edit.hint = "1 - ${pageNumber + 1}"
        binding.edit.addTextChangedListener {
            binding.tvOk.isEnabled = !it.isNullOrEmpty()
        }
        binding.edit.requestFocus()
        binding.tvOk.setOnClickListener {
            val number = binding.edit.text.toString()
            if (number.isEmpty()) {
                toast("number can't be empty!")
                return@setOnClickListener
            }
            dialog.dismiss()
            okAction?.invoke(number.toInt() - 1)
        }
    }

    fun Context.showDocumentRenameDialog(
        name: String? = null,
        okAction: ((newName: String) -> Unit)? = null,
        dismissAction: (() -> Unit)? = null
    ) {
        val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
        val binding = DialogDocumentRenameBinding.inflate(LayoutInflater.from(this))
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)

        val window = dialog.window
        window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)

        dialog.show()

        val parentView = binding.root.parent as View
        val behavior = BottomSheetBehavior.from(parentView)
        //展开
        behavior.state = BottomSheetBehavior.STATE_EXPANDED

        binding.edit.addTextChangedListener {
            binding.tvOk.isEnabled = !it.isNullOrEmpty()
        }

        val tempName = "Split_" + System.currentTimeMillis().toFormatTime2()
        binding.edit.setText(name ?: tempName)
        if (name == null) {
            binding.edit.selectAll()
        } else {
            val nameS = name.split(".")[0]
            binding.edit.setSelection(0, nameS.length)
        }
        binding.edit.requestFocus()

        binding.tvCancel.setOnClickListener {
            dialog.dismiss()
        }
        binding.tvOk.setOnClickListener {
            dialog.dismiss()

            val newName = binding.edit.text.toString()
            if (newName.isEmpty()) {
                toast("name can't be empty!")
                return@setOnClickListener
            }
            okAction?.invoke(newName)
        }
        dialog.setOnDismissListener {
            dismissAction?.invoke()
        }
    }

    fun Context.showDeleteDialog(deleteAction: () -> Unit) {
        val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
        val binding = DialogDeleteBinding.inflate(LayoutInflater.from(this))
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)

        dialog.show()

        val parentView = binding.root.parent as View
        val behavior = BottomSheetBehavior.from(parentView)
        //展开
        behavior.state = BottomSheetBehavior.STATE_EXPANDED

        binding.tvCancel.setOnClickListener {
            dialog.dismiss()
        }
        binding.tvDelete.setOnClickListener {
            dialog.dismiss()
            deleteAction.invoke()
        }
    }

    fun Context.showCommonTipDialog(
        title: String = "",
        tip: String = "",
        noBtn: String = "Cancel",
        yesBtn: String = "Ok"
    ) {
        val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
        val binding = DialogCommonTipBinding.inflate(LayoutInflater.from(this))
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)

        dialog.show()

        val parentView = binding.root.parent as View
        val behavior = BottomSheetBehavior.from(parentView)
        //展开
        behavior.state = BottomSheetBehavior.STATE_EXPANDED

        binding.tvTittle.text = title
        binding.tvTips.text = tip
        binding.tvNo.text = noBtn
        binding.tvYes.text = yesBtn

        binding.tvNo.setOnClickListener {
            dialog.dismiss()
        }
        binding.tvYes.setOnClickListener {
            dialog.dismiss()
        }
    }

    fun Activity.showAppExitDialog() {
        val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
        val binding = DialogAppExitBinding.inflate(LayoutInflater.from(this))
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)

        dialog.show()

        val parentView = binding.root.parent as View
        val behavior = BottomSheetBehavior.from(parentView)
        //展开
        behavior.state = BottomSheetBehavior.STATE_EXPANDED

        AdmobNativeUtils.showNativeAd(this, binding.flAd, R.layout.layout_admob_app_exit)

        binding.cardNo.setOnClickListener {
            finish()
        }
        binding.cardYes.setOnClickListener {
            dialog.dismiss()
        }
    }


    fun Activity.showNotificationDialog(launcher: ActivityLauncher) {
        if (checkNotificationPermission()) return

        val dialog = AlertDialog.Builder(this).create()
        val binding = DialogNotificationEnableBinding.inflate(LayoutInflater.from(this))
        dialog.setView(binding.root)
        dialog.setCanceledOnTouchOutside(true)

        dialog.show()

        val params = dialog.window?.attributes
        params?.width = resources.getDimensionPixelOffset(R.dimen.dp_345)
        params?.height = LinearLayout.LayoutParams.WRAP_CONTENT
        params?.gravity = Gravity.CENTER
        dialog.window?.attributes = params
        dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)


        binding.tvOk.setOnClickListener {
            dialog.dismiss()
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                launcher.launch(arrayOf(Manifest.permission.POST_NOTIFICATIONS)) {

                }
            }
        }

        binding.tvNo.setOnClickListener {
            dialog.dismiss()
        }
        binding.flClose.setOnClickListener {
            dialog.dismiss()
        }

    }

    @SuppressLint("SetTextI18n")
    fun Activity.showDefaultBottomDialog() {
        if (!checkStorePermission()) return
        if (setDefault) return
        setDefault = true

        val dialog = AlertDialog.Builder(this).create()
        val binding = DialogDefaultBottomBinding.inflate(LayoutInflater.from(this))
        dialog.setView(binding.root)
        dialog.setCanceledOnTouchOutside(true)

        val window = dialog.window
        window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)

        dialog.show()

        val params = dialog.window?.attributes
        params?.gravity = Gravity.BOTTOM
        dialog.window?.attributes = params
        dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)

        val appName = resources.getString(R.string.app_name)

        binding.tvTittle.text = getString(R.string.set_as_default) + " " + appName
        binding.tvDesc.text =
            getString(R.string.set_this_app_as_your_default) + " " + appName + " " + getString(R.string.for_a_better_reading_experience)

        binding.tvConfirm.setOnClickListener {
            dialog.dismiss()
            showDefaultTopDialog()
        }


    }

    fun Activity.showDefaultTopDialog() {
        val dialog = AlertDialog.Builder(this).create()
        val binding = DialogDefaultUpBinding.inflate(LayoutInflater.from(this))
        dialog.setView(binding.root)
        dialog.setCanceledOnTouchOutside(true)

        dialog.show()

        val params = dialog.window?.attributes
//        params?.width = resources.getDimensionPixelOffset(R.dimen.dp_345)
//        params?.height = LinearLayout.LayoutParams.WRAP_CONTENT
        params?.gravity = Gravity.TOP
        dialog.window?.attributes = params
        dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)


        val select = getString(R.string.select)
        val spannableStringBuilder = SpannableStringBuilder()
        spannableStringBuilder.append(select)
        spannableStringBuilder.append(" ")

        val app = getString(R.string.app_name)
        val appString = SpannableString(app)
        appString.setSpan(
            ForegroundColorSpan(ContextCompat.getColor(this, R.color.colo_00b8de)),
            0,
            appString.length,
            SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        spannableStringBuilder.append(appString)

        val andClick = getString(R.string._and_click)
        spannableStringBuilder.append(andClick)
        spannableStringBuilder.append(" ")

        val always = getString(R.string.always)
        val alwaysString = SpannableString(always)
        alwaysString.setSpan(
            ForegroundColorSpan(ContextCompat.getColor(this, R.color.colo_00b8de)),
            0,
            always.length,
            SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        spannableStringBuilder.append(alwaysString)
        spannableStringBuilder.append(" ")

        val ss = getString(R.string.as_the_default_reader)
        spannableStringBuilder.append(ss)

        binding.tvTittle.text = spannableStringBuilder

        binding.tvOk.setOnClickListener {
            dialog.dismiss()
            val intent = Intent(Intent.ACTION_VIEW)
            intent.setDataAndType(Uri.parse(""), "application/pdf")
            intent.addCategory(Intent.CATEGORY_DEFAULT)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

            val chooser: Intent = Intent.createChooser(intent, null)

            if (intent.resolveActivity(packageManager) != null) {
                startActivityForResult(chooser, 111)
            }
        }
    }

}