def apply_ab_imposition(self, input_pdf_path, output_pdf_path):
        """Applies AB Imposition to arrange odd and even pages on separate sheets, with back side reversed and rotated."""
        # Get parameters from the UI
        new_page_width = self.new_page_width_var.get()
        new_page_height = self.new_page_height_var.get()
        margin_top = self.margin_top_var.get()
        margin_bottom = self.margin_bottom_var.get()
        margin_left = self.margin_left_var.get()
        margin_right = self.margin_right_var.get()
        cropmark_offset = self.cropmark_offset_var.get()
        cropmark_length = self.cropmark_length_var.get()

        # Convert units from mm to points
        new_page_width_pt = self.mm_to_points(new_page_width)
        new_page_height_pt = self.mm_to_points(new_page_height)
        margin_top_pt = self.mm_to_points(margin_top)
        margin_bottom_pt = self.mm_to_points(margin_bottom)
        margin_left_pt = self.mm_to_points(margin_left)
        margin_right_pt = self.mm_to_points(margin_right)
        cropmark_offset_pt = self.mm_to_points(cropmark_offset)
        crop_length_pt = self.mm_to_points(cropmark_length)

        # Độ dày của crop marks
        crop_thickness = 0.5  # Bạn có thể thay đổi giá trị này

        # Calculate available area
        available_width = new_page_width_pt - margin_left_pt - margin_right_pt
        available_height = new_page_height_pt - margin_top_pt - margin_bottom_pt

        # Read the input PDF
        doc = fitz.open(input_pdf_path)
        total_pages = len(doc)

        # Get the size of the input page
        input_page = doc.load_page(0)
        bbox = input_page.rect
        entry_width_orig = bbox.width
        entry_height_orig = bbox.height

        # Options for rotation and non-rotation
        options = [
            {'rotate': False, 'entry_width': entry_width_orig, 'entry_height': entry_height_orig},
            {'rotate': True, 'entry_width': entry_height_orig, 'entry_height': entry_width_orig},
        ]

        # Determine the best arrangement
        best_arrangement = None
        max_total_entries = 0
        for option in options:
            entries_per_row = int(available_width // option['entry_width'])
            entries_per_column = int(available_height // option['entry_height'])
            total_entries = entries_per_row * entries_per_column
            if total_entries > max_total_entries:
                max_total_entries = total_entries
                best_arrangement = option.copy()
                best_arrangement['entries_per_row'] = entries_per_row
                best_arrangement['entries_per_column'] = entries_per_column

        if not best_arrangement or best_arrangement['entries_per_row'] == 0 or best_arrangement['entries_per_column'] == 0:
            messagebox.showerror("Error", "Page size or margins are too small to fit any content.")
            return

        # Separate odd and even pages
        odd_pages = [i for i in range(total_pages) if i % 2 == 0]  # Trang lẻ (theo chỉ số 0-based)
        even_pages = [i for i in range(total_pages) if i % 2 != 0]  # Trang chẵn

        # Create new documents for front and back sides
        front_doc = fitz.open()
        back_doc = fitz.open()

        # Function to impose pages for the front side (odd pages)
        def impose_front_pages(pages, arrangement):
            page_index = 0
            total_pages_local = len(pages)
            while page_index < total_pages_local:
                new_page = front_doc.new_page(width=new_page_width_pt, height=new_page_height_pt)
                arranged_rects = []

                # Calculate x_offset and y_offset to center the content
                total_grid_width = arrangement['entries_per_row'] * arrangement['entry_width']
                total_grid_height = arrangement['entries_per_column'] * arrangement['entry_height']
                x_offset = (new_page_width_pt - total_grid_width) / 2
                y_offset = (new_page_height_pt - total_grid_height) / 2

                for row in range(arrangement['entries_per_column']):
                    y = y_offset + row * arrangement['entry_height']
                    for col in range(arrangement['entries_per_row']):
                        x = x_offset + col * arrangement['entry_width']
                        if page_index >= total_pages_local:
                            break
                        pno = pages[page_index]
                        rect = fitz.Rect(
                            x,
                            y,
                            x + arrangement['entry_width'],
                            y + arrangement['entry_height']
                        )
                        if arrangement['rotate']:
                            new_page.show_pdf_page(rect, doc, pno=pno, rotate=90)
                        else:
                            new_page.show_pdf_page(rect, doc, pno=pno)
                        arranged_rects.append((rect, row, col))
                        page_index += 1
                    if page_index >= total_pages_local:
                        break

                # Add crop marks
                for rect, row, col in arranged_rects:
                    edges = []
                    if row == 0:
                        edges.append('top')
                    if row == arrangement['entries_per_column'] - 1:
                        edges.append('bottom')
                    if col == 0:
                        edges.append('left')
                    if col == arrangement['entries_per_row'] - 1:
                        edges.append('right')
                    if edges:
                        self.add_crop_marks(new_page, rect, edges, cropmark_offset_pt, crop_length_pt, crop_thickness)

        def impose_back_pages(pages, arrangement):
            total_pages_local = len(pages)
            pages_per_sheet = arrangement['entries_per_row'] * arrangement['entries_per_column']
            sheet_number = 0

            while sheet_number * pages_per_sheet < total_pages_local:
                new_page = back_doc.new_page(width=new_page_width_pt, height=new_page_height_pt)
                arranged_rects = []

                # Tính toán x_offset và y_offset để căn giữa nội dung
                total_grid_width = arrangement['entries_per_row'] * arrangement['entry_width']
                total_grid_height = arrangement['entries_per_column'] * arrangement['entry_height']
                x_offset = (new_page_width_pt - total_grid_width) / 2
                y_offset = (new_page_height_pt - total_grid_height) / 2

                for row in range(arrangement['entries_per_column']):
                    y = y_offset + row * arrangement['entry_height']

                    for col in range(arrangement['entries_per_row']):
                        x = x_offset + col * arrangement['entry_width']

                        # Hoán đổi cột cho các hàng đầu tiên (trừ hàng cuối cùng)
                        if row < arrangement['entries_per_column'] - 1:
                            col_swapped = arrangement['entries_per_row'] - 1 - col
                        else:
                            col_swapped = col

                        # Tính toán chỉ số trang
                        page_index_in_sheet = row * arrangement['entries_per_row'] + col_swapped
                        page_index = sheet_number * pages_per_sheet + page_index_in_sheet

                        if page_index >= total_pages_local:
                            break

                        pno = pages[page_index]
                        rect = fitz.Rect(
                            x,
                            y,
                            x + arrangement['entry_width'],
                            y + arrangement['entry_height']
                        )

                        # Xoay trang nếu cần
                        if arrangement['rotate']:
                            rotation = 180
                        else:
                            rotation = 0

                        new_page.show_pdf_page(rect, doc, pno=pno, rotate=rotation)
                        arranged_rects.append((rect, row, col))

                sheet_number += 1

                # Thêm crop marks
                for rect, row, col in arranged_rects:
                    edges = []
                    if row == 0:
                        edges.append('top')
                    if row == arrangement['entries_per_column'] - 1:
                        edges.append('bottom')
                    if col == 0:
                        edges.append('left')
                    if col == arrangement['entries_per_row'] - 1:
                        edges.append('right')
                    if edges:
                        self.add_crop_marks(new_page, rect, edges, cropmark_offset_pt, crop_length_pt, crop_thickness)


        # Impose front (odd) pages
        impose_front_pages(odd_pages, best_arrangement)

        # Impose back (even) pages
        impose_back_pages(even_pages, best_arrangement)

        # Merge front and back documents by interleaving pages
        final_doc = fitz.open()
        num_pages_front = len(front_doc)
        num_pages_back = len(back_doc)
        for i in range(max(num_pages_front, num_pages_back)):
            if i < num_pages_front:
                final_doc.insert_pdf(front_doc, from_page=i, to_page=i)
            if i < num_pages_back:
                final_doc.insert_pdf(back_doc, from_page=i, to_page=i)

        # Save the final imposed PDF
        final_doc.save(output_pdf_path)
        final_doc.close()
        front_doc.close()
        back_doc.close()
        doc.close() phân tích mã này hiện tại mã dang sapes xếp theo thứ tự từ trái sang phải cho front back và từ phải sang trái cho back pack đúng ko