#!/usr/bin/env python3
"""
PDF合并脚本 - 使用pypdf，以文件名（不含扩展名）作为书签，通过系统通知提示结果。
用法: pdfmerge.sh 文件1.pdf 文件2.pdf ...   或   pdfmerge.sh 目录
依赖: pip install pypdf
"""

import sys
import os
import re
import subprocess
from datetime import datetime

from pypdf import PdfWriter, PdfReader


def natural_sort_key(path):
    """自然排序键：将文件名（不含后缀）中的数字部分转为整数进行比较"""
    name = os.path.splitext(os.path.basename(path))[0]
    return [int(c) if c.isdigit() else c.lower() for c in re.split(r'(\d+)', name)]


def notify(title, message, icon="emblem-checked"):
    """发送系统通知"""
    subprocess.run([
        "notify-send",
        "--app-name=PDF合并",
        title,
        message,
        f"--icon={icon}"
    ])


def merge_pdfs(output_dir, pdf_files):
    """合并PDF文件并添加书签"""
    timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
    output_file = os.path.join(output_dir, f"合并_{timestamp}.pdf")

    writer = PdfWriter()
    page_count = 0

    for filepath in pdf_files:
        try:
            reader = PdfReader(filepath)
        except Exception:
            continue

        # 文件名（不含扩展名）作为书签标题
        title = os.path.splitext(os.path.basename(filepath))[0]

        # 添加书签，指向该文件在合并文档中的起始页（从0开始）
        writer.add_outline_item(title, page_count)

        for page in reader.pages:
            writer.add_page(page)

        page_count = len(writer.pages)

    if page_count == 0:
        raise RuntimeError("没有有效的PDF文件可合并")

    writer.write(output_file)
    writer.close()

    return output_file


def main():
    try:
        if len(sys.argv) < 2:
            notify("", "失败", "dialog-error")
            sys.exit(1)

        arg = sys.argv[1]

        if os.path.isdir(arg):
            input_dir = arg
            pdf_files = sorted(
                (os.path.join(input_dir, f)
                 for f in os.listdir(input_dir)
                 if f.lower().endswith(".pdf")),
                key=natural_sort_key
            )
            if not pdf_files:
                notify("", "失败", "dialog-error")
                sys.exit(1)
            parent_dir = os.path.dirname(os.path.abspath(input_dir))
        else:
            pdf_files = [os.path.abspath(f) for f in sys.argv[1:]]
            pdf_files.sort(key=natural_sort_key)
            parent_dir = os.path.dirname(pdf_files[0])

        merge_pdfs(parent_dir, pdf_files)
        notify("", "成功", "emblem-checked")

    except Exception:
        notify("", "失败", "dialog-error")
        sys.exit(1)


if __name__ == "__main__":
    main()
