import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from pypdf import PdfReader, PdfWriter, Transformation
import math
import os


class PDFPageCombinerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("PDF Page Combiner")
        self.root.geometry("700x420")
        self.root.configure(bg="#f5f5f5")

        self.input_pdf = tk.StringVar()
        self.output_pdf = tk.StringVar()
        self.pages_per_sheet = tk.IntVar(value=5)

        self.build_ui()

    def build_ui(self):
        title = tk.Label(
            self.root,
            text="איחוד עמודי PDF לעמודים ארוכים",
            font=("Arial", 20, "bold"),
            bg="#f5f5f5"
        )
        title.pack(pady=20)

        main_frame = tk.Frame(self.root, bg="#f5f5f5")
        main_frame.pack(fill="both", expand=True, padx=20)

        # קובץ מקור
        tk.Label(
            main_frame,
            text="קובץ PDF מקור:",
            font=("Arial", 11),
            bg="#f5f5f5"
        ).grid(row=0, column=0, sticky="w", pady=10)

        self.input_label = tk.Label(
            main_frame,
            text="לא נבחר קובץ",
            width=50,
            anchor="w",
            relief="sunken",
            bg="white"
        )
        self.input_label.grid(row=0, column=1, padx=10)

        tk.Button(
            main_frame,
            text="בחר קובץ",
            width=15,
            command=self.select_input
        ).grid(row=0, column=2)

        # קובץ יעד
        tk.Label(
            main_frame,
            text="קובץ יעד:",
            font=("Arial", 11),
            bg="#f5f5f5"
        ).grid(row=1, column=0, sticky="w", pady=10)

        self.output_label = tk.Label(
            main_frame,
            text="לא נבחר יעד",
            width=50,
            anchor="w",
            relief="sunken",
            bg="white"
        )
        self.output_label.grid(row=1, column=1, padx=10)

        tk.Button(
            main_frame,
            text="בחר יעד",
            width=15,
            command=self.select_output
        ).grid(row=1, column=2)

        # מספר עמודים
        tk.Label(
            main_frame,
            text="כמה עמודים לאחד:",
            font=("Arial", 11),
            bg="#f5f5f5"
        ).grid(row=2, column=0, sticky="w", pady=20)

        tk.Spinbox(
            main_frame,
            from_=2,
            to=50,
            textvariable=self.pages_per_sheet,
            width=10,
            font=("Arial", 11)
        ).grid(row=2, column=1, sticky="w")

        # כפתור התחלה
        self.start_button = tk.Button(
            self.root,
            text="התחל המרה",
            font=("Arial", 14, "bold"),
            bg="#4CAF50",
            fg="white",
            padx=20,
            pady=10,
            command=self.combine_pages
        )
        self.start_button.pack(pady=15)

        # Progress bar
        self.progress = ttk.Progressbar(
            self.root,
            orient="horizontal",
            length=600,
            mode="determinate"
        )
        self.progress.pack(pady=10)

        self.status_label = tk.Label(
            self.root,
            text="",
            font=("Arial", 10),
            bg="#f5f5f5"
        )
        self.status_label.pack()

    def select_input(self):
        path = filedialog.askopenfilename(
            title="בחר קובץ PDF",
            filetypes=[("PDF Files", "*.pdf")]
        )

        if path:
            self.input_pdf.set(path)
            self.input_label.config(text=os.path.basename(path))

            if not self.output_pdf.get():
                output_path = os.path.splitext(path)[0] + "_combined.pdf"
                self.output_pdf.set(output_path)
                self.output_label.config(text=os.path.basename(output_path))

    def select_output(self):
        path = filedialog.asksaveasfilename(
            title="בחר יעד לשמירה",
            defaultextension=".pdf",
            filetypes=[("PDF Files", "*.pdf")]
        )

        if path:
            self.output_pdf.set(path)
            self.output_label.config(text=os.path.basename(path))

    def combine_pages(self):
        input_path = self.input_pdf.get()
        output_path = self.output_pdf.get()

        if not input_path:
            messagebox.showerror("שגיאה", "לא נבחר קובץ מקור")
            return

        if not output_path:
            messagebox.showerror("שגיאה", "לא נבחר יעד לשמירה")
            return

        try:
            pages_per_sheet = int(self.pages_per_sheet.get())

            reader = PdfReader(input_path)
            writer = PdfWriter()

            total_pages = len(reader.pages)
            total_groups = math.ceil(total_pages / pages_per_sheet)

            self.progress["maximum"] = total_groups
            self.progress["value"] = 0

            for group_index in range(total_groups):
                start = group_index * pages_per_sheet
                end = min(start + pages_per_sheet, total_pages)

                group_pages = reader.pages[start:end]

                max_width = max(float(p.mediabox.width) for p in group_pages)
                total_height = sum(float(p.mediabox.height) for p in group_pages)

                new_page = writer.add_blank_page(
                    width=max_width,
                    height=total_height
                )

                current_y = total_height

                for p in group_pages:
                    page_width = float(p.mediabox.width)
                    page_height = float(p.mediabox.height)

                    current_y -= page_height

                    x_offset = (max_width - page_width) / 2

                    new_page.merge_transformed_page(
                        p,
                        Transformation().translate(
                            tx=x_offset,
                            ty=current_y
                        )
                    )

                self.progress["value"] = group_index + 1

                self.status_label.config(
                    text=f"מעבד {group_index + 1} מתוך {total_groups}"
                )

                self.root.update_idletasks()

            with open(output_path, "wb") as f:
                writer.write(f)

            self.status_label.config(text="ההמרה הושלמה בהצלחה!")

            messagebox.showinfo(
                "הצלחה",
                "הקובץ נוצר בהצלחה!"
            )

        except Exception as e:
            messagebox.showerror("שגיאה", str(e))


if __name__ == "__main__":
    root = tk.Tk()
    app = PDFPageCombinerApp(root)
    root.mainloop()
