package com.base.pdfreaderallpdfreader.ui.pdf

import android.content.Context
import android.net.Uri
import android.os.Environment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.artifex.mupdfdemo.MuPDFCore
import com.artifex.mupdfdemo.OutlineActivityData
import com.base.pdfreaderallpdfreader.R
import com.base.pdfreaderallpdfreader.bean.ConstObject.MIME_TYPE_PDF
import com.base.pdfreaderallpdfreader.bean.PdfPageBean
import com.base.pdfreaderallpdfreader.ui.pdf.PdfMergeActivity.Companion.mergePdfList
import com.base.pdfreaderallpdfreader.utils.LogEx
import com.base.pdfreaderallpdfreader.utils.PdfBoxUtils
import com.base.pdfreaderallpdfreader.utils.UriUtils.readFileToByteArray
import com.tom_roush.pdfbox.multipdf.PDFMergerUtility
import com.tom_roush.pdfbox.pdmodel.PDDocument
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File

class PdfViewModel : ViewModel() {

    private val TAG = "PdfViewModel"

    var password: String? = null

    var initPdfPageRv: ((items: List<PdfPageBean>) -> Unit)? = null

    fun openFile(context: Context, 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(pageCount: Int) {
        val list = arrayListOf<PdfPageBean>()
        repeat(pageCount) {
            list.add(PdfPageBean(it))
        }
        initPdfPageRv?.invoke(list)
    }

    fun iniPdfPage(context: Context, filePath: String, uri: String? = null) = viewModelScope.launch(Dispatchers.IO) {
        val list = arrayListOf<PdfPageBean>()
        val number = PdfBoxUtils.getNumberOfPages(context, filePath, password, uri)
        repeat(number) {
            list.add(PdfPageBean(it))
        }
        initPdfPageRv?.invoke(list)
    }

    private fun createAppDocumentDir(context: Context): 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(context: Context, name: String): String {
        val appDir = createAppDocumentDir(context)
        val child = if (name.endsWith(".pdf")) name else "$name.pdf"
        val mergeFile = File(appDir, child)
        mergeFile.createNewFile()
        LogEx.logDebug(TAG, "mergeFile ${mergeFile.absolutePath}")
        return mergeFile.absolutePath
    }

    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 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()


}