package com.base.pdfviewerscannerwhite.ui.document.pdf

import android.content.Context
import android.net.Uri
import android.os.Environment
import com.artifex.mupdfdemo.MuPDFCore
import com.artifex.mupdfdemo.OutlineActivityData
import com.base.pdfviewerscannerwhite.R
import com.base.pdfviewerscannerwhite.bean.ConstObject.MIME_TYPE_PDF
import com.base.pdfviewerscannerwhite.bean.PdfPageBean
import com.base.pdfviewerscannerwhite.ui.document.pdf.PdfMergeActivity.Companion.mergePdfList
import com.base.pdfviewerscannerwhite.utils.LogEx
import com.base.pdfviewerscannerwhite.utils.UriUtils.readFileToByteArray
import com.tom_roush.pdfbox.multipdf.PDFMergerUtility
import com.tom_roush.pdfbox.pdmodel.PDDocument
import java.io.File


class PdfPresenter(
    val context: Context,
    val pdfView: PdfView? = null
) {
    private val TAG = "PdfPresenter"
    var password: String? = null

    fun openFile(path: String, uri: String? = null): MuPDFCore? {
        var muPDFCore: MuPDFCore? = null
        try {
            muPDFCore = if (uri == null) MuPDFCore(context, path) else MuPDFCore(
                context,
                readFileToByteArray(context, Uri.parse(uri)),
                MIME_TYPE_PDF
            )
            // 新建：删除旧的目录数据
            OutlineActivityData.set(null)
        } catch (e: java.lang.Exception) {
            return null
        } catch (e: OutOfMemoryError) {
            return null
        }
        return muPDFCore
    }


    fun iniPdfPage(filePath: String, uri: String? = null) {
        val list = arrayListOf<PdfPageBean>()
        val number = PdfBoxUtils.getNumberOfPages(filePath, password, uri)
        repeat(number) {
            list.add(PdfPageBean(it))
        }
        pdfView?.initPdfPageRv(list)
    }

    fun iniPdfPage(pageCount: Int) {
        val list = arrayListOf<PdfPageBean>()
        repeat(pageCount) {
            list.add(PdfPageBean(it))
        }
        pdfView?.initPdfPageRv(list)
    }


    fun splitPdf(
        srcPath: String,
        newPath: String,
        splitIndex: List<Int>,
        finishAction: (newFile: File?) -> Unit
    ) = Thread {

        try {
            // 加载现有 PDF 文档
            val sourceDocument = PDDocument.load(File(srcPath), password)
            LogEx.logDebug(TAG, "sourceDocument open")

            // 创建新的 PDF 文档
            val newDocument = PDDocument()

            // 遍历指定的页面范围
            splitIndex.forEach { index ->
                val page = sourceDocument.getPage(index)
                newDocument.addPage(page)
            }
            // 保存新的 PDF 文档
            newDocument.save(newPath)
            newDocument.close()
            sourceDocument.close()
        } catch (e: Exception) {
            LogEx.logDebug(TAG, "splitPdf error")
            finishAction.invoke(null)
            return@Thread
        }
        finishAction.invoke(File(newPath))
    }.start()

    fun createAvoidDupNamePath(path: String): String {
        val file = File(path)
        var newName = file.name.split(".")[0]
        //aaaa_1.pdf
        if (isUnderscoreNumberSuffix(newName)) {
            val nameSplit = newName.split("_")
            val number = nameSplit[1].toInt() + 1
            newName = "${nameSplit[0]}_$number"
        } else {
            newName = "${newName}_1"
        }

        val newFile = File(file.parentFile, "$newName.pdf")
        if (!newFile.exists()) {
            newFile.createNewFile()
        }
        return newFile.absolutePath
    }

    private fun isUnderscoreNumberSuffix(input: String): Boolean {
        val pattern = "_\\d+$".toRegex()
        return pattern.matches(input)
    }

    private fun createAppDocumentDir(): File {
        val appName = context.resources.getString(R.string.app_name)
        val appDir = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), appName)
        if (!appDir.exists()) {
            appDir.mkdirs()
        }
        return appDir
    }

    fun createNewPdfPath(name: String): String {
        val appDir = createAppDocumentDir()
        val mergeFile = File(appDir, "$name.pdf")
        mergeFile.createNewFile()
        LogEx.logDebug(TAG, "mergeFile ${mergeFile.absolutePath}")
        return mergeFile.absolutePath
    }

    fun mergePdf(mergePath: String, finishAction: (success: Boolean) -> Unit) = Thread {

        var isSuccess: Boolean = false
        try {
            val mergerUtility = PDFMergerUtility()
            mergerUtility.destinationFileName = mergePath

            //解密
            PdfMergeActivity.mergePdfList.filter { it.state == 1 }.forEach {
                PdfBoxUtils.clearPassword(it.path, it.password)
            }

            LogEx.logDebug(TAG, "mergePdf ${mergePdfList.size}")
            PdfMergeActivity.mergePdfList.forEach { documentBean ->
                LogEx.logDebug(TAG, "mergePdf item= ${documentBean.path} ${documentBean.state}")

                //带密码  mergerUtility.addSource(inputStream) 不行
                mergerUtility.addSource(File(documentBean.path))

//                if (documentBean.state == 0) {
//                    mergerUtility.addSource(File(documentBean.path))
//                } else {
//                    LogEx.logDebug(TAG, "mergePdf password=${documentBean.password}")
//                    try {
//                        val pdfDocument = PDDocument.load(File(documentBean.path), documentBean.password)
//                        LogEx.logDebug(TAG, "mergePdf pdfDocument ${pdfDocument.numberOfPages}")
//                        val byteArrayOutputStream = ByteArrayOutputStream()
//                        pdfDocument.save(byteArrayOutputStream)
//                        LogEx.logDebug(TAG, "mergePdf byteArrayOutputStream ${byteArrayOutputStream.size()}")
//                        pdfDocument.close()
//                        val inputStream = ByteArrayInputStream(byteArrayOutputStream.toByteArray())
//                        LogEx.logDebug(TAG, "mergePdf  inputStream")
//                        mergerUtility.addSource(inputStream)
//                    } catch (e: Exception) {
//                        LogEx.logDebug(TAG, "mergePdf Exception ${e.printStackTrace()}")
//                    }
//                    LogEx.logDebug(TAG, "mergePdf inputStream")
//                }
            }
            mergerUtility.mergeDocuments(null)

            //重新加密
            PdfMergeActivity.mergePdfList.filter { it.state == 1 }.forEach {
                val flag = PdfBoxUtils.setPassword(it.path, it.password, it.password)
                LogEx.logDebug(TAG, "重新加密 flag=$flag ${it.path} ${it.password}")
            }

            mergePdfList.clear()
            LogEx.logDebug(TAG, "mergePdf finish")
            isSuccess = true
        } catch (e: Exception) {

        }


        finishAction.invoke(isSuccess)
    }.start()

}