#!/usr/bin/env python3
"""
图片转PDF脚本 - 使用img2pdf（无损）+ pypdf（书签），通过系统通知提示结果。
用法: img2pdf 图片1.png 图片2.jpg ...   或   img2pdf 目录
依赖: pip install img2pdf pypdf
"""

import sys
import os
import subprocess
from datetime import datetime
import tempfile

import re
import img2pdf
from pypdf import PdfWriter, PdfReader

SUPPORTED_EXTS = {".bmp", ".png", ".jpg", ".jpeg", ".tif", ".tiff", ".gif", ".webp"}


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 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
            image_files = sorted(
                (os.path.join(input_dir, f)
                 for f in os.listdir(input_dir)
                 if os.path.splitext(f)[1].lower() in SUPPORTED_EXTS),
                key=natural_sort_key
            )
            if not image_files:
                notify("", "失败", "dialog-error")
                sys.exit(1)
            parent_dir = os.path.dirname(os.path.abspath(input_dir))
        else:
            image_files = []
            for f in sys.argv[1:]:
                path = os.path.abspath(f)
                if os.path.isfile(path) and os.path.splitext(path)[1].lower() in SUPPORTED_EXTS:
                    image_files.append(path)
            image_files.sort(key=natural_sort_key)
            if not image_files:
                notify("", "失败", "dialog-error")
                sys.exit(1)
            parent_dir = os.path.dirname(image_files[0])

        images = []
        valid_files = []
        for filepath in image_files:
            # img2pdf 直接嵌入原始字节流，无损保留画质
            images.append(filepath)
            valid_files.append(filepath)

        if not images:
            notify("", "失败", "dialog-error")
            sys.exit(1)

        timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
        if len(valid_files) == 1:
            basename = os.path.splitext(os.path.basename(valid_files[0]))[0]
            output_pdf = os.path.join(parent_dir, f"{basename}_{timestamp}.pdf")
        else:
            output_pdf = os.path.join(parent_dir, f"图片转PDF_{timestamp}.pdf")

        # img2pdf 无损生成 PDF
        pdf_bytes = img2pdf.convert(images)

        # pypdf 添加书签
        with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as tmp:
            tmp.write(pdf_bytes)
            tmp_path = tmp.name

        reader = PdfReader(tmp_path)
        writer = PdfWriter()
        page_count = 0

        for i, filepath in enumerate(valid_files):
            writer.add_page(reader.pages[i])

            title = os.path.splitext(os.path.basename(filepath))[0]
            writer.add_outline_item(title, page_count)
            page_count += 1

        writer.write(output_pdf)
        writer.close()

        os.unlink(tmp_path)

        notify("", "成功", "emblem-checked")

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


if __name__ == "__main__":
    main()
