package com.all.pdfreader.pro.app.util

import android.graphics.pdf.PdfDocument
import com.all.pdfreader.pro.app.PRApp
import com.all.pdfreader.pro.app.room.repository.PdfRepository
import com.all.pdfreader.pro.app.util.AppUtils.generateFastThumbnail
import com.tom_roush.pdfbox.pdmodel.PDDocument
import com.tom_roush.pdfbox.pdmodel.encryption.AccessPermission
import com.tom_roush.pdfbox.pdmodel.encryption.StandardProtectionPolicy
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File

object PdfSecurityUtils {

    fun setPasswordToPdf(
        inputFilePath: String, userPassword: String, ownerPassword: String
    ): Boolean {
        return try {
            PDDocument.load(File(inputFilePath)).use { document ->
                val accessPermission = AccessPermission()
                val protectionPolicy =
                    StandardProtectionPolicy(ownerPassword, userPassword, accessPermission)
                protectionPolicy.encryptionKeyLength = 128
                protectionPolicy.permissions = accessPermission
                document.protect(protectionPolicy)
                document.save(inputFilePath)
                true
            }
        } catch (e: Exception) {
            e.printStackTrace()
            false
        }
    }

    suspend fun setPasswordToPdfWithProgress(
        inputFilePath: String,
        userPassword: String,
        ownerPassword: String,
        onProgress: (Int) -> Unit
    ): Boolean = withContext(Dispatchers.IO) {
        var success = false
        // 假进度变量
        var progress = 0
        val job = launch {
            while (isActive && progress < 98) {
                delay(50)
                progress += when {
                    progress < 80 -> 1  // 前 80% 每次 +1
                    progress < 90 -> 2  // 80~90% 每次 +2
                    else -> 3           // 90~98% 每次 +3
                }
                if (progress > 98) progress = 98
                withContext(Dispatchers.Main) {
                    onProgress(progress)
                }
            }
        }

        success = setPasswordToPdf(inputFilePath, userPassword, ownerPassword)

        // 停止假进度
        job.cancel()

        // 最后 98 -> 100 有一个 1 秒左右的平滑视觉过渡
        val finalStart = progress
        val finalEnd = 100
        val steps = (finalEnd - finalStart).coerceAtLeast(2) // 至少两步
        val delayPerStep = 1000L / steps

        for (p in finalStart..finalEnd) {
            withContext(Dispatchers.Main) {
                onProgress(p)
            }
            delay(delayPerStep)
        }
        success
    }


    fun removePasswordFromPdf(inputFilePath: String, password: String): Boolean {
        return try {
            PDDocument.load(File(inputFilePath), password).use { document ->
                document.isAllSecurityToBeRemoved = true // 移除所有安全设置，包括密码
                document.save(inputFilePath)
            }
            true // 返回成功解密的标志
        } catch (e: Exception) {
            e.printStackTrace()
            false // 返回解密失败的标志
        }
    }

    suspend fun removePasswordFromPdfWithProgress(
        inputFilePath: String,
        password: String,
        onProgress: (Int) -> Unit
    ): String? = withContext(Dispatchers.IO) {
        var newThumbnail: String? = null
        var success = false
        var progress = 0

        // 启动假进度
        val job = launch {
            while (isActive && progress < 98) {
                delay(50)
                progress += when {
                    progress < 80 -> 1  // 前 80% 每次 +1
                    progress < 90 -> 2  // 80~90% 每次 +2
                    else -> 3           // 90~98% 每次 +3
                }
                if (progress > 98) progress = 98
                withContext(Dispatchers.Main) {
                    onProgress(progress)
                }
            }
        }

        // 执行移除密码操作
        success = removePasswordFromPdf(inputFilePath, password)
        if (success) {
            val pdfRepository = PdfRepository.getInstance()
            pdfRepository.updateIsPassword(inputFilePath, false)
            newThumbnail = generateFastThumbnail(PRApp.getContext(), File(inputFilePath))
            val document = pdfRepository.getDocumentByPath(inputFilePath)
            if (document?.thumbnailPath.isNullOrEmpty()) {
                if (!newThumbnail.isNullOrEmpty() && inputFilePath != newThumbnail) {
                    pdfRepository.updateThumbnailPath(inputFilePath, newThumbnail)
                }
            }
        }
        // 停止假进度
        job.cancel()

        // 最后 98 -> 100 平滑过渡 1 秒
        val finalStart = progress
        val finalEnd = 100
        val steps = (finalEnd - finalStart).coerceAtLeast(2)
        val delayPerStep = 1000L / steps

        for (p in finalStart..finalEnd) {
            withContext(Dispatchers.Main) {
                onProgress(p)
            }
            delay(delayPerStep)
        }

        newThumbnail
    }

}
