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

import android.content.Context
import android.net.Uri
import android.os.Bundle
import android.os.CancellationSignal
import android.os.ParcelFileDescriptor
import android.print.PageRange
import android.print.PrintAttributes
import android.print.PrintDocumentAdapter
import android.print.PrintDocumentInfo
import java.io.FileOutputStream
import java.io.InputStream

/**
 * 自定义的 PrintDocumentAdapter，用于告诉系统如何布局和写入 PDF 内容
 *
 * @param context 上下文
 * @param uri 需要打印的 PDF 文件 Uri
 */
class PrintPdfAdapter(private val context: Context, private val uri: Uri) : PrintDocumentAdapter() {

    /**
     * 打印布局阶段调用的方法
     *
     * @param printAttributes 打印属性（如纸张大小、方向等）
     * @param printAttributes2 可能更新后的打印属性
     * @param cancellationSignal 取消信号，可以用来判断用户是否取消了打印
     * @param layoutResultCallback 用于通知系统布局结果
     * @param bundle 额外参数，一般为空
     */
    override fun onLayout(
        printAttributes: PrintAttributes?,
        printAttributes2: PrintAttributes?,
        cancellationSignal: CancellationSignal,
        layoutResultCallback: LayoutResultCallback,
        bundle: Bundle?
    ) {
        if (cancellationSignal.isCanceled) {
            // 如果用户取消了打印，通知系统取消布局
            layoutResultCallback.onLayoutCancelled()
        } else {
            // 布局完成，告知系统文档信息
            layoutResultCallback.onLayoutFinished(
                PrintDocumentInfo.Builder("AllPDF") // 设置文档名称
                    .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT) // 设置文档类型
                    .build(),
                true // 表示布局内容有变化
            )
        }
    }

    /**
     * 实际写入 PDF 数据到打印系统的方法
     *
     * @param pageRangeArr 需要打印的页码范围
     * @param parcelFileDescriptor 系统提供的文件描述符，打印内容要写入这里
     * @param cancellationSignal 用户取消打印时会触发，用于提前终止写入
     * @param writeResultCallback 用于通知系统写入结果
     */
    override fun onWrite(
        pageRangeArr: Array<PageRange?>?,
        parcelFileDescriptor: ParcelFileDescriptor,
        cancellationSignal: CancellationSignal?,
        writeResultCallback: WriteResultCallback
    ) {
        try {
            // 打开输入流读取 PDF 文件
            val openInputStream: InputStream? = context.contentResolver.openInputStream(uri)

            // 打开输出流，将 PDF 内容写入到系统提供的文件描述符
            val fileOutputStream = FileOutputStream(parcelFileDescriptor.fileDescriptor)

            val bArr = ByteArray(1024) // 1KB 缓冲区
            while (true) {
                // 循环读取文件内容
                val read = openInputStream?.read(bArr)
                if (read != null) {
                    if (read > 0) {
                        // 写入到输出流
                        fileOutputStream.write(bArr, 0, read)
                    } else {
                        // 读取完成，通知系统写入成功
                        writeResultCallback.onWriteFinished(arrayOf(PageRange.ALL_PAGES))
                        // 关闭流，释放资源
                        openInputStream.close()
                        fileOutputStream.close()
                        return
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            // 如果出错，可以考虑调用 writeResultCallback.onWriteFailed()
        }
    }
}
