from __future__ import annotations

import tkinter as tk
import threading
import uuid
from datetime import datetime
from tkinter import messagebox, ttk

from app_core.ui_helpers import configure_striped_treeview


PO_HEADER_FIELDS = [
    ("po_number", "po_number"),
    ("po_date", "po_date"),
    ("po_time", "po_time"),
    ("simple_domestic_pt", "simple_domestic_pt"),
    ("dept_number", "dept_number"),
    ("order_date", "order_date"),
    ("ship_date", "ship_date"),
    ("cancel_date", "cancel_date"),
    ("vendor_name", "vendor_name"),
    ("vendor_attention", "vendor_attention"),
    ("vendor_email", "vendor_email"),
    ("buyer_name", "buyer_name"),
    ("buyer_email", "buyer_email"),
    ("duns", "duns"),
    ("bealls_code", "bealls_code"),
    ("terms", "terms"),
    ("fob_point", "fob_point"),
    ("freight_allowance", "freight_allowance"),
    ("total_packs_ordered", "total_packs_ordered"),
    ("total_units", "total_units"),
    ("total_cost", "total_cost"),
    ("total_qty", "total_qty"),
    ("status", "status"),
    ("is_active", "active_status"),
    ("store_number", "store_number"),
    ("mark_for", "mark_for"),
    ("ship_to_full", "ship_to_full"),
    ("shipping_address", "shipping_address"),
    ("mailing_address", "mailing_address"),
    ("vendor_address", "vendor_address"),
]

PO_TREE_COLUMNS = (
    "export_flag",
    "created_at",
    "po_number",
    "dept_number",
    "po_date",
    "po_time",
    "order_date",
    "ship_date",
    "cancel_date",
    "simple_domestic_pt",
    "buyer",
    "style",
    "season",
    "vendor",
    "total_packs_ordered",
    "store_number",
    "size_range",
    "size_scale",
    "line_cost",
    "line_comp",
    "line_retail",
    "total_cost",
    "total_qty",
    "active",
    "status",
    "updated_at",
    "version_number",
    "latest_user",
)

PO_ITEM_COLUMNS = (
    "sku",
    "style",
    "color",
    "size",
    "description",
    "upc",
    "cost",
    "comp",
    "retail",
    "pack_qty",
    "total_packs",
    "total_units",
)

PO_SORT_KEY_OPTIONS = [
    ("po_number", "sort_po_number"),
    ("dept_number", "dept_number"),
    ("vendor", "sort_vendor"),
    ("po_date", "sort_order_date"),
    ("order_date", "order_date"),
    ("ship_date", "ship_date"),
    ("cancel_date", "cancel_date"),
    ("total_packs_ordered", "total_packs_ordered"),
    ("store_number", "store_number"),
    ("size_range", "costing_size_range_column"),
    ("size_scale", "costing_size_scale_column"),
    ("line_cost", "item_cost"),
    ("line_comp", "item_comp"),
    ("line_retail", "item_retail"),
    ("total_cost", "sort_total_cost"),
    ("total_qty", "sort_total_qty"),
    ("version_number", "po_version_column"),
    ("active", "active_status"),
    ("status", "status"),
]

PO_FILTER_FIELD_OPTIONS = [
    ("__all__", "samples_filter_all_option"),
    ("po_number", "po_number"),
    ("dept_number", "dept_number"),
    ("po_date", "po_date"),
    ("po_time", "po_time"),
    ("order_date", "order_date"),
    ("ship_date", "ship_date"),
    ("cancel_date", "cancel_date"),
    ("simple_domestic_pt", "simple_domestic_pt"),
    ("buyer", "buyer_name"),
    ("style", "tree_style"),
    ("season", "tech_pack_season_column"),
    ("vendor_name", "vendor_name"),
    ("total_packs_ordered", "total_packs_ordered"),
    ("store_number", "store_number"),
    ("size_range", "costing_size_range_column"),
    ("size_scale", "costing_size_scale_column"),
    ("line_cost", "item_cost"),
    ("line_comp", "item_comp"),
    ("line_retail", "item_retail"),
    ("total_cost", "tree_total_cost"),
    ("total_qty", "tree_total_qty"),
    ("active", "active_status"),
    ("status", "status"),
    ("created_at", "create_time_column"),
    ("updated_at", "revised_time_column"),
]

PO_DATE_FILTER_FIELDS = {
    "po_date",
    "order_date",
    "ship_date",
    "cancel_date",
    "created_at",
    "updated_at",
}

PO_FILTER_DEBOUNCE_MS = 180


def _normalize_po_item_text(value: object) -> str:
    return str(value or "").strip().lower()


def _normalize_po_style_text(value: object) -> str:
    return str(value or "").strip().upper()


def _parse_po_item_number(value: object) -> float:
    text = str(value or "").strip().replace(",", "")
    if not text:
        return 0.0
    try:
        return float(text)
    except (TypeError, ValueError):
        return 0.0


def _format_po_item_total(value: float) -> str:
    if abs(value - round(value)) < 1e-9:
        return str(int(round(value)))
    return f"{value:.2f}".rstrip("0").rstrip(".")


def build_purchase_order_module(self, parent: ttk.Frame) -> None:
    toolbar = ttk.Frame(parent)
    toolbar.pack(fill="x", pady=(0, 12))

    self.widget_text["import_pdf_button"] = ttk.Button(toolbar, command=self.import_pdf)
    self.widget_text["import_pdf_button"].pack(side="left")
    self.register_permission_widget("action.purchase_order.import_pdf", self.widget_text["import_pdf_button"])
    self.widget_text["import_folder_button"] = ttk.Button(toolbar, command=self.import_folder)
    self.widget_text["import_folder_button"].pack(side="left", padx=(8, 0))
    self.register_permission_widget("action.purchase_order.import_folder", self.widget_text["import_folder_button"])
    self.widget_text["export_report_toolbar_button"] = ttk.Button(toolbar, command=lambda: self.export_report("purchase_order"))
    self.widget_text["export_report_toolbar_button"].pack(side="left", padx=(8, 0))
    self.register_permission_widget("action.purchase_order.export_report", self.widget_text["export_report_toolbar_button"])
    self.widget_text["delete_po_button"] = ttk.Button(toolbar, command=self.delete_selected_po)
    self.widget_text["delete_po_button"].pack(side="left", padx=(8, 0))
    self.register_permission_widget("action.purchase_order.delete_po", self.widget_text["delete_po_button"])
    self.widget_text["edit_po_button"] = ttk.Button(toolbar, command=self.edit_selected_po_item)
    self.widget_text["edit_po_button"].pack(side="left", padx=(8, 0))
    self.register_permission_widget("action.purchase_order.edit_po", self.widget_text["edit_po_button"])
    self.widget_text["compare_po_button"] = ttk.Button(toolbar, text=self.t("compare_po"), command=self.show_selected_po_history)
    self.widget_text["compare_po_button"].pack(side="left", padx=(8, 0))
    self.register_permission_widget("action.purchase_order.compare_po", self.widget_text["compare_po_button"])
    self.widget_text["quick_po_status_button"] = ttk.Button(toolbar, text=self.t("quick_po_status"), command=self.quick_update_po_status)
    self.widget_text["quick_po_status_button"].pack(side="left", padx=(8, 0))
    self.register_permission_widget("action.purchase_order.edit_po", self.widget_text["quick_po_status_button"])

    body = ttk.Frame(parent)
    body.pack(fill="both", expand=True)
    self.purchase_order_pane = body

    left = ttk.Frame(body)
    left.pack(fill="both", expand=True)

    self.widget_text["orders_section"] = ttk.Label(left, style="Section.TLabel")
    self.widget_text["orders_section"].pack(anchor="w", pady=(0, 8))

    controls = ttk.Frame(left)
    controls.pack(fill="x", pady=(0, 8))
    controls.columnconfigure(8, weight=1)

    self.widget_text["po_filter_field_label"] = ttk.Label(controls)
    self.widget_text["po_filter_field_label"].grid(row=0, column=0, sticky="w", padx=(0, 6))
    self.po_filter_field_combo = ttk.Combobox(controls, textvariable=self.po_filter_field_var, state="readonly", width=22)
    self.po_filter_field_combo.grid(row=0, column=1, sticky="w")
    self.po_filter_field_combo.bind("<<ComboboxSelected>>", self.on_po_filter_field_changed)
    self.widget_text["po_filter_value_label"] = ttk.Label(controls)
    self.widget_text["po_filter_value_label"].grid(row=0, column=2, sticky="w", padx=(12, 6))
    self.search_entry = ttk.Entry(controls, textvariable=self.search_var, width=36)
    self.search_entry.grid(row=0, column=3, sticky="w", padx=(0, 12))
    self.search_entry.bind("<Return>", self.on_po_search_submit)
    self.search_entry.bind("<KP_Enter>", self.on_po_search_submit)
    self.widget_text["po_date_from_label"] = ttk.Label(controls)
    self.widget_text["po_date_from_label"].grid(row=0, column=4, sticky="w", padx=(0, 6))
    self.po_date_from_entry = ttk.Entry(controls, textvariable=self.po_date_from_var, width=12)
    self.po_date_from_entry.grid(row=0, column=5, sticky="w", padx=(0, 12))
    self.bind_date_entry_picker(self.po_date_from_entry, self.po_date_from_var)
    self.po_date_from_var.trace_add("write", lambda *_args: self.apply_filters_and_sort())
    self.widget_text["po_date_to_label"] = ttk.Label(controls)
    self.widget_text["po_date_to_label"].grid(row=0, column=6, sticky="w", padx=(0, 6))
    self.po_date_to_entry = ttk.Entry(controls, textvariable=self.po_date_to_var, width=12)
    self.po_date_to_entry.grid(row=0, column=7, sticky="w")
    self.bind_date_entry_picker(self.po_date_to_entry, self.po_date_to_var)
    self.po_date_to_var.trace_add("write", lambda *_args: self.apply_filters_and_sort())

    self.widget_text["sort_by_label"] = ttk.Label(controls)
    self.widget_text["sort_by_label"].grid(row=1, column=0, sticky="w", pady=(8, 0), padx=(0, 6))
    self.sort_key_combo = ttk.Combobox(
        controls,
        textvariable=self.sort_key_var,
        state="readonly",
        width=18,
    )
    self.sort_key_combo.grid(row=1, column=1, sticky="w", pady=(8, 0))
    self.sort_key_combo.bind("<<ComboboxSelected>>", self.on_sort_key_changed)

    self.widget_text["sort_order_label"] = ttk.Label(controls)
    self.widget_text["sort_order_label"].grid(row=1, column=2, sticky="w", pady=(8, 0), padx=(12, 6))
    self.sort_order_combo = ttk.Combobox(
        controls,
        textvariable=self.sort_order_var,
        state="readonly",
        width=12,
    )
    self.sort_order_combo.grid(row=1, column=3, sticky="w", pady=(8, 0))
    self.sort_order_combo.bind("<<ComboboxSelected>>", self.on_sort_order_changed)
    self.update_po_filter_input_state()

    orders_table = ttk.Frame(left)
    orders_table.pack(fill="both", expand=True)
    orders_table.columnconfigure(0, weight=1)
    orders_table.rowconfigure(0, weight=1)
    self.orders_tree = ttk.Treeview(orders_table, columns=PO_TREE_COLUMNS, show="headings", selectmode="browse")
    configure_striped_treeview(self.orders_tree)
    order_column_widths = {
        "export_flag": 70,
        "created_at": 145,
        "po_number": 120,
        "dept_number": 80,
        "po_date": 110,
        "po_time": 80,
        "order_date": 110,
        "ship_date": 110,
        "cancel_date": 110,
        "simple_domestic_pt": 210,
        "buyer": 90,
        "style": 110,
        "season": 100,
        "vendor": 280,
        "total_packs_ordered": 90,
        "store_number": 90,
        "size_range": 110,
        "size_scale": 160,
        "line_cost": 90,
        "line_comp": 90,
        "line_retail": 90,
        "total_cost": 120,
        "total_qty": 100,
        "active": 90,
        "status": 90,
        "updated_at": 145,
        "version_number": 90,
        "latest_user": 140,
    }
    for key, width in order_column_widths.items():
        anchor = "center" if key == "export_flag" else "w"
        self.orders_tree.column(key, width=width, anchor=anchor, stretch=False)
        self.orders_tree.heading(key, command=lambda column=key: self.on_tree_heading_click(column))
    self.orders_tree.heading("latest_user", text=self.t("latest_user_column"), command=lambda: self.on_tree_heading_click("latest_user"))

    orders_scroll = ttk.Scrollbar(orders_table, orient="vertical", command=self.orders_tree.yview)
    orders_scroll_x = ttk.Scrollbar(orders_table, orient="horizontal")
    summary_width = sum(order_column_widths.get(column_key, 80) for column_key in PO_TREE_COLUMNS)
    self.po_list_total_qty_var = tk.StringVar(value="0")
    self.po_list_summary_canvas = tk.Canvas(orders_table, height=30, highlightthickness=0, background="#f0f0f0")
    summary_inner = ttk.Frame(self.po_list_summary_canvas)
    for column_index, column_key in enumerate(PO_TREE_COLUMNS):
        summary_inner.columnconfigure(column_index, minsize=order_column_widths.get(column_key, 80))
    total_cost_index = PO_TREE_COLUMNS.index("total_cost")
    total_qty_index = PO_TREE_COLUMNS.index("total_qty")
    ttk.Label(summary_inner, text="Filtered Total", anchor="w").grid(row=0, column=total_cost_index, sticky="w")
    ttk.Label(summary_inner, textvariable=self.po_list_total_qty_var, anchor="w").grid(row=0, column=total_qty_index, sticky="w")
    self.po_list_summary_canvas.create_window(0, 0, anchor="nw", window=summary_inner, width=summary_width, height=30)
    self.po_list_summary_canvas.configure(scrollregion=(0, 0, summary_width, 30))

    def sync_orders_xview(first: str, last: str) -> None:
        orders_scroll_x.set(first, last)
        try:
            self.po_list_summary_canvas.xview_moveto(float(first))
        except (tk.TclError, ValueError):
            pass

    def scroll_orders_xview(*args: object) -> None:
        self.orders_tree.xview(*args)
        self.po_list_summary_canvas.xview(*args)

    orders_scroll_x.configure(command=scroll_orders_xview)
    self.orders_tree.configure(yscrollcommand=orders_scroll.set, xscrollcommand=sync_orders_xview)
    self.orders_tree.tag_configure("missing_data", background=self.missing_background)
    self.orders_tree.grid(row=0, column=0, sticky="nsew")
    orders_scroll.grid(row=0, column=1, sticky="ns")
    orders_scroll_x.grid(row=1, column=0, sticky="ew")
    self.po_list_summary_canvas.grid(row=2, column=0, sticky="ew")
    self.orders_tree.bind("<<TreeviewSelect>>", self.on_order_selected)
    self.orders_tree.bind("<Double-1>", self.on_orders_tree_double_click)
    self.orders_tree.bind("<Button-1>", self.on_orders_tree_click)
    self.widget_text["detail_section"] = ttk.Label(left, style="Section.TLabel")
    self.widget_text["detail_section"].pack(anchor="w", pady=(8, 0))
    self.detail_hint_label = ttk.Label(left, text="Double click one PO to open PO detail in a new window.")
    self.detail_hint_label.pack(anchor="w", pady=(4, 0))
    self.notebook_tabs = {}
    self.notebook = None
    self.items_tree = None
    self.instructions_text = None
    self.po_list_total_qty_var = getattr(self, "po_list_total_qty_var", None)
    self.item_total_packs_var = None
    self.item_total_units_var = None


def _add_header_field(self, parent: ttk.Frame, row_index: int, text_key: str, data_key: str, wraplength: int) -> None:
    label_widget = ttk.Label(parent, style="FieldLabel.TLabel")
    label_widget.grid(row=row_index, column=0, sticky="nw", padx=(0, 12), pady=4)
    value_var = tk.StringVar(value="")
    value_widget = ttk.Label(parent, textvariable=value_var, wraplength=wraplength, justify="left")
    value_widget.grid(row=row_index, column=1, sticky="w", pady=4)
    self.header_label_widgets[text_key] = label_widget
    self.header_vars[data_key] = value_var
    self.header_value_widgets[data_key] = value_widget


def build_po_detail_widgets(self, parent: ttk.Frame) -> None:
    notebook = ttk.Notebook(parent)
    notebook.pack(fill="both", expand=True)

    header_tab = ttk.Frame(notebook, padding=12)
    items_tab = ttk.Frame(notebook, padding=12)
    raw_tab = ttk.Frame(notebook, padding=12)
    self.notebook_tabs = {"header": header_tab, "items": items_tab, "notes": raw_tab}
    notebook.add(header_tab, text="Header")
    notebook.add(items_tab, text="Items")
    notebook.add(raw_tab, text="Notes")
    self.notebook = notebook

    self.header_label_widgets = {}
    self.header_vars = {}
    self.header_value_widgets = {}

    left_fields = ttk.Frame(header_tab)
    right_fields = ttk.Frame(header_tab)
    left_fields.pack(side="left", fill="both", expand=True, padx=(0, 10))
    right_fields.pack(side="left", fill="both", expand=True, padx=(10, 0))
    left_fields.columnconfigure(1, weight=1)
    right_fields.columnconfigure(1, weight=1)

    midpoint = (len(PO_HEADER_FIELDS) + 1) // 2
    for row_index, (text_key, data_key) in enumerate(PO_HEADER_FIELDS[:midpoint]):
        self._add_header_field(left_fields, row_index, text_key, data_key, wraplength=360)
    for row_index, (text_key, data_key) in enumerate(PO_HEADER_FIELDS[midpoint:]):
        self._add_header_field(right_fields, row_index, text_key, data_key, wraplength=360)

    items_table = ttk.Frame(items_tab)
    items_table.pack(fill="both", expand=True)
    items_table.columnconfigure(0, weight=1)
    items_table.rowconfigure(0, weight=1)
    self.items_tree = ttk.Treeview(items_table, columns=PO_ITEM_COLUMNS, show="headings")
    configure_striped_treeview(self.items_tree)
    item_widths = {
        "sku": 90,
        "style": 90,
        "color": 120,
        "size": 60,
        "description": 320,
        "upc": 120,
        "cost": 70,
        "comp": 70,
        "retail": 70,
        "pack_qty": 80,
        "total_packs": 90,
        "total_units": 90,
    }
    for key, width in item_widths.items():
        self.items_tree.column(key, width=width, anchor="w", stretch=False)

    items_scroll_y = ttk.Scrollbar(items_table, orient="vertical", command=self.items_tree.yview)
    items_scroll_x = ttk.Scrollbar(items_table, orient="horizontal", command=self.items_tree.xview)
    self.items_tree.configure(yscrollcommand=items_scroll_y.set, xscrollcommand=items_scroll_x.set)
    self.items_tree.grid(row=0, column=0, sticky="nsew")
    items_scroll_y.grid(row=0, column=1, sticky="ns")
    items_scroll_x.grid(row=1, column=0, sticky="ew")

    items_summary = ttk.Frame(items_tab)
    items_summary.pack(fill="x", pady=(8, 0))
    self.items_summary_frame = items_summary
    self.item_total_packs_var = tk.StringVar(value="0")
    self.item_total_units_var = tk.StringVar(value="0")
    for column_index, key in enumerate(PO_ITEM_COLUMNS):
        minsize = item_widths.get(key, 80)
        items_summary.columnconfigure(column_index, minsize=minsize)
    ttk.Label(items_summary, text="Filtered Total", anchor="w").grid(row=0, column=8, sticky="w")
    ttk.Label(items_summary, textvariable=self.item_total_packs_var, anchor="w").grid(row=0, column=10, sticky="w")
    ttk.Label(items_summary, textvariable=self.item_total_units_var, anchor="w").grid(row=0, column=11, sticky="w")

    self.widget_text["notes_title"] = ttk.Label(raw_tab, style="Section.TLabel")
    self.widget_text["notes_title"].pack(anchor="w")
    self.instructions_text = tk.Text(raw_tab, wrap="word", height=12)
    self.instructions_text.pack(fill="both", expand=True, pady=(8, 0))


def close_po_detail_window(self) -> None:
    dialog = getattr(self, "po_detail_dialog", None)
    self.po_detail_dialog = None
    self.notebook = None
    self.notebook_tabs = {}
    self.items_tree = None
    self.instructions_text = None
    self.item_total_packs_var = None
    self.item_total_units_var = None
    self.header_label_widgets = {}
    self.header_vars = {}
    self.header_value_widgets = {}
    if dialog is not None:
        try:
            if dialog.winfo_exists():
                dialog.destroy()
        except tk.TclError:
            pass


def open_po_detail_window(self, order_id: int | None = None) -> None:
    target_order_id = order_id
    if target_order_id is None:
        selection = self.orders_tree.selection()
        if not selection:
            messagebox.showwarning(self.t("warning_title"), "Please select one PO first.")
            return
        target_order_id = self.select_po_tree_display_row(selection[0])

    existing = getattr(self, "po_detail_dialog", None)
    if existing is not None:
        try:
            if existing.winfo_exists():
                existing.lift()
                existing.focus_force()
                self.load_order(target_order_id)
                return
        except tk.TclError:
            pass

    dialog = tk.Toplevel(self.root)
    dialog.title("PO Detail")
    dialog.geometry("1260x760")
    dialog.minsize(1080, 680)
    self.po_detail_dialog = dialog
    dialog.protocol("WM_DELETE_WINDOW", self.close_po_detail_window)

    frame = ttk.Frame(dialog, padding=16)
    frame.pack(fill="both", expand=True)
    frame.columnconfigure(0, weight=1)
    frame.rowconfigure(1, weight=1)

    ttk.Label(frame, text="PO Detail", style="Section.TLabel").grid(row=0, column=0, sticky="w", pady=(0, 8))
    detail_host = ttk.Frame(frame)
    detail_host.grid(row=1, column=0, sticky="nsew")
    self.build_po_detail_widgets(detail_host)
    if hasattr(self, "update_translations"):
        try:
            self.update_translations()
        except Exception:
            pass
    self.load_order(target_order_id)


def on_orders_tree_double_click(self, event: tk.Event) -> str | None:
    row_id = self.orders_tree.identify_row(event.y)
    if not row_id:
        return None
    self.orders_tree.selection_set(row_id)
    self.orders_tree.focus(row_id)
    order_id = self.select_po_tree_display_row(row_id)
    self.open_po_detail_window(order_id)
    return "break"


def refresh_orders_tree(self, selected_id: str | None = None) -> None:
    current_selection = self.orders_tree.selection()
    if selected_id is None:
        selected_id = current_selection[0] if current_selection else None

    for item in self.orders_tree.get_children():
        self.orders_tree.delete(item)
    self.orders_tree.tag_configure("po_status_draft", background="#ffffff")
    self.orders_tree.tag_configure("po_status_checking", background="#fff7cc")
    self.orders_tree.tag_configure("po_status_approved", background="#dff5e3")

    for row in self.filtered_orders:
        row_tags: list[str] = []
        if any(
            self.is_missing_value(row.get(key))
            for key in (
                "dept_number",
                "po_date",
                "po_time",
                "order_date",
                "ship_date",
                    "cancel_date",
                    "simple_domestic_pt",
                    "buyer",
                    "style",
                    "vendor_name",
                "total_packs_ordered",
                "store_number",
                "total_cost",
                "total_qty",
            )
        ):
            row_tags.append("missing_data")
        status_value = str(row.get("status", "")).strip().lower()
        row_tags.append(
            {
                "checking": "po_status_checking",
                "approved": "po_status_approved",
            }.get(status_value, "po_status_draft")
        )
        self.orders_tree.insert(
            "",
            "end",
            iid=self.po_tree_item_display_id(row),
            values=self.build_order_tree_values(row),
            tags=tuple(row_tags),
        )

    if selected_id and self.orders_tree.exists(selected_id):
        self.orders_tree.selection_set(selected_id)
        self.orders_tree.focus(selected_id)


def update_orders_tree_export_state(self, row_id: str | None = None) -> None:
    if not hasattr(self, "orders_tree"):
        return
    target_ids = [row_id] if row_id else list(self.orders_tree.get_children())
    for item_id in target_ids:
        if not self.orders_tree.exists(item_id):
            continue
        try:
            order_id = self.po_tree_item_order_id(item_id)
        except (TypeError, ValueError):
            continue
        values = list(self.orders_tree.item(item_id, "values"))
        if len(values) < 1:
            continue
        values[0] = self.export_flag_value(order_id)
        self.orders_tree.item(item_id, values=tuple(values))


def purchase_order_history_group_key(self, row: dict) -> str:
    po_number = str(row.get("po_number", "")).strip().upper()
    return po_number or str(row.get("id", "")).strip()


def parse_purchase_order_version_datetime(self, row: dict) -> datetime | None:
    date_text = str(row.get("po_date", "") or "").strip()
    time_text = str(row.get("po_time", "") or "").strip()
    if not date_text or date_text == "-":
        return None
    parsed_date: datetime | None = None
    for date_format in ("%m/%d/%Y", "%Y-%m-%d", "%d/%m/%Y"):
        try:
            parsed_date = datetime.strptime(date_text, date_format)
            break
        except ValueError:
            continue
    if parsed_date is None:
        return None
    if not time_text or time_text == "-":
        return parsed_date
    for time_format in ("%H:%M:%S", "%H:%M", "%I:%M:%S %p", "%I:%M %p"):
        try:
            parsed_time = datetime.strptime(time_text, time_format).time()
            return datetime.combine(parsed_date.date(), parsed_time)
        except ValueError:
            continue
    return parsed_date


def purchase_order_version_sort_key(self, row: dict) -> tuple[int, str, int, str, str, int]:
    try:
        row_id = int(row.get("id", 0) or 0)
    except (TypeError, ValueError):
        row_id = 0
    version_datetime = self.parse_purchase_order_version_datetime(row)
    simple_domestic_pt_digits = "".join(ch for ch in str(row.get("simple_domestic_pt", "") or "") if ch.isdigit())
    simple_domestic_pt_order = int(simple_domestic_pt_digits) if simple_domestic_pt_digits else 0
    return (
        1 if version_datetime is not None else 0,
        version_datetime.isoformat() if version_datetime is not None else "",
        simple_domestic_pt_order,
        str(row.get("created_at", "") or ""),
        str(row.get("updated_at", "") or ""),
        row_id,
    )


def extract_latest_purchase_order_versions(self, rows: list[dict]) -> list[dict]:
    latest_by_po: dict[str, dict] = {}
    version_count_by_po: dict[str, int] = {}
    for row in rows:
        if not isinstance(row, dict):
            continue
        group_key = self.purchase_order_history_group_key(row)
        version_count_by_po[group_key] = version_count_by_po.get(group_key, 0) + 1
        existing = latest_by_po.get(group_key)
        if existing is None or self.purchase_order_version_sort_key(row) > self.purchase_order_version_sort_key(existing):
            latest_by_po[group_key] = dict(row)
    for group_key, row in latest_by_po.items():
        row["version_number"] = version_count_by_po.get(group_key, 1)
    latest_rows = list(latest_by_po.values())
    latest_rows.sort(key=self.purchase_order_version_sort_key, reverse=True)
    return latest_rows


def purchase_order_version_ids_for_order_id(self, order_id: int) -> list[int]:
    try:
        target_id = int(order_id)
    except (TypeError, ValueError):
        return []
    if target_id <= 0:
        return []

    version_rows = [
        dict(row)
        for row in list(getattr(self, "all_order_versions", []) or [])
        if isinstance(row, dict)
    ]
    selected_row = next(
        (
            row
            for row in version_rows
            if int(row.get("id", 0) or 0) == target_id
        ),
        None,
    )
    if selected_row is None:
        selected_row = next(
            (
                row
                for row in list(getattr(self, "all_orders", []) or [])
                if isinstance(row, dict) and self.po_base_order_id(row) == target_id
            ),
            None,
        )
    if selected_row is None:
        return [target_id]

    group_key = self.purchase_order_history_group_key(selected_row)
    version_ids: list[int] = []
    for row in version_rows:
        if self.purchase_order_history_group_key(row) != group_key:
            continue
        try:
            version_id = int(row.get("id", 0) or 0)
        except (TypeError, ValueError):
            continue
        if version_id > 0 and version_id not in version_ids:
            version_ids.append(version_id)
    return version_ids or [target_id]


def po_base_order_id(self, row: dict) -> int:
    return int(row.get("po_base_order_id") or row.get("id") or 0)


def po_tree_item_order_id(self, item_id: object) -> int:
    text = str(item_id or "").strip()
    if "::" in text:
        text = text.split("::", 1)[0]
    return int(text)


def po_tree_item_display_id(self, row: dict) -> str:
    value = str(row.get("po_display_row_id", "") or "").strip()
    if value:
        return value
    return str(row.get("id", "") or "")


def po_display_style_for_item_id(self, item_id: object) -> str:
    display_id = str(item_id or "").strip()
    for row in list(getattr(self, "filtered_orders", []) or []):
        if self.po_tree_item_display_id(row) != display_id:
            continue
        style_code = _normalize_po_style_text(row.get("style"))
        return "" if "," in style_code else style_code
    return ""


def select_po_tree_display_row(self, item_id: object) -> int:
    order_id = self.po_tree_item_order_id(item_id)
    self.selected_order_id = order_id
    self.selected_order_style = self.po_display_style_for_item_id(item_id)
    return order_id


def build_purchase_order_style_display_rows(self, rows: list[dict]) -> list[dict]:
    display_rows: list[dict] = []
    for row in rows:
        if not isinstance(row, dict):
            continue
        try:
            order_id = int(row.get("id", 0) or 0)
        except (TypeError, ValueError):
            order_id = 0
        style_codes = self.extract_order_style_codes(row)
        if not style_codes:
            display_row = dict(row)
            display_row["season"] = str(display_row.get("season", "") or "").strip()
            display_row["po_base_order_id"] = order_id
            display_row["po_display_row_id"] = str(order_id or row.get("po_number", ""))
            if hasattr(self, "summarize_order_line_item_values"):
                display_row["line_cost"] = self.summarize_order_line_item_values(display_row, "cost_unit")
                display_row["line_comp"] = self.summarize_order_line_item_values(display_row, "comp")
                display_row["line_retail"] = self.summarize_order_line_item_values(display_row, "retail")
            display_rows.append(display_row)
            continue
        for style_code in style_codes:
            display_row = dict(row)
            display_row["style"] = style_code
            display_row["season"] = self.get_style_season(style_code) if hasattr(self, "get_style_season") else str(row.get("season", "") or "").strip()
            display_row["po_base_order_id"] = order_id
            display_row["po_display_row_id"] = f"{order_id}::{style_code}"
            if hasattr(self, "summarize_order_line_item_values"):
                display_row["line_cost"] = self.summarize_order_line_item_values(display_row, "cost_unit")
                display_row["line_comp"] = self.summarize_order_line_item_values(display_row, "comp")
                display_row["line_retail"] = self.summarize_order_line_item_values(display_row, "retail")
            display_rows.append(display_row)
    return display_rows


def refresh_purchase_order_seasons_from_tech_pack(self) -> bool:
    versions = [dict(row) for row in list(getattr(self, "all_order_versions", []) or []) if isinstance(row, dict)]
    if not versions:
        return False
    new_orders = self.build_purchase_order_style_display_rows(self.extract_latest_purchase_order_versions(versions))
    if new_orders == getattr(self, "all_orders", []):
        return False
    self.all_orders = new_orders
    valid_order_ids = {self.po_base_order_id(row) for row in self.all_orders}
    self.checked_order_ids.intersection_update(valid_order_ids)
    self.apply_filters_and_sort()
    if hasattr(self, "save_main_ui_session_cache"):
        cached_payload = self.load_main_ui_session_cache("purchase_order") if hasattr(self, "load_main_ui_session_cache") else None
        payload = dict(cached_payload) if isinstance(cached_payload, dict) else {}
        payload["all_order_versions"] = versions
        payload["all_orders"] = new_orders
        self.save_main_ui_session_cache("purchase_order", payload)
    return True


def refresh_orders(self, silent: bool = False, *, refresh_tech_pack: bool = True, force: bool = False) -> bool:
    if hasattr(self, "invalidate_style_season_lookup_cache"):
        self.invalidate_style_season_lookup_cache()
    active_prefixes = self.get_active_collection_prefixes()
    cached_payload = None if force or not hasattr(self, "load_main_ui_session_cache") else self.load_main_ui_session_cache("purchase_order")
    if isinstance(cached_payload, dict) and isinstance(cached_payload.get("all_order_versions"), list) and isinstance(cached_payload.get("all_orders"), list):
        new_versions = [dict(row) for row in list(cached_payload.get("all_order_versions", []) or []) if isinstance(row, dict)]
        new_orders = self.build_purchase_order_style_display_rows(self.extract_latest_purchase_order_versions(new_versions))
    elif isinstance(cached_payload, dict):
        source_rows = [dict(row) for row in list(cached_payload.get("order_versions", []) or []) if isinstance(row, dict)]
        new_versions = [self.enrich_order_row(row, active_prefixes=active_prefixes) for row in source_rows]
        new_orders = self.build_purchase_order_style_display_rows(self.extract_latest_purchase_order_versions(new_versions))
    else:
        source_rows = [dict(row) for row in self.fetch_order_records_from_source() if isinstance(row, dict)]
        new_versions = [self.enrich_order_row(row, active_prefixes=active_prefixes) for row in source_rows]
        new_orders = self.build_purchase_order_style_display_rows(self.extract_latest_purchase_order_versions(new_versions))
        if hasattr(self, "save_main_ui_session_cache"):
            self.save_main_ui_session_cache(
                "purchase_order",
                {
                    "order_versions": source_rows,
                    "all_order_versions": new_versions,
                    "all_orders": new_orders,
                },
            )
    changed = new_versions != getattr(self, "all_order_versions", []) or new_orders != self.all_orders
    self.all_order_versions = new_versions
    self.all_orders = new_orders
    valid_order_ids = {self.po_base_order_id(row) for row in self.all_orders}
    self.checked_order_ids.intersection_update(valid_order_ids)
    if changed or not silent:
        self.apply_filters_and_sort()
        if refresh_tech_pack:
            self.refresh_tech_pack_module(silent=silent)
    if not silent:
        self.set_status(self.t("loaded_orders", count=len(self.all_orders)))
    return changed


def apply_filters_and_sort(self) -> None:
    if getattr(self, "_po_filter_update_suspended", False):
        return
    query = str(getattr(self, "po_search_committed_value", self.search_var.get()) or "").strip().lower()
    from_text = self.po_date_from_var.get().strip()
    to_text = self.po_date_to_var.get().strip()
    filter_field = getattr(self, "po_filter_field_internal", "__all__")
    is_date_field = filter_field in PO_DATE_FILTER_FIELDS
    filtered = list(self.all_orders)
    query_digits = "".join(ch for ch in query if ch.isdigit())
    normalized_query_digits = query_digits.lstrip("0") if query_digits else ""

    def po_number_matches_query(row: dict) -> bool:
        if not normalized_query_digits:
            return False
        po_digits = "".join(ch for ch in str(row.get("po_number", "") or "") if ch.isdigit()).lstrip("0")
        return bool(po_digits) and po_digits == normalized_query_digits

    if is_date_field:
        filtered = [
            row
            for row in filtered
            if self.is_within_date_range(row.get(filter_field), from_text, to_text)
        ]
    elif filter_field == "__all__" and query:
        filtered = [
            row
            for row in filtered
            if po_number_matches_query(row) or query in " ".join(
                str(row.get(key, "")).lower()
                for key in (
                    "po_number",
                    "dept_number",
                    "po_date",
                    "po_time",
                    "order_date",
                    "ship_date",
                    "cancel_date",
                    "simple_domestic_pt",
                    "buyer",
                    "style",
                    "season",
                    "vendor_name",
                    "total_packs_ordered",
                    "store_number",
                    "line_cost",
                    "line_comp",
                    "line_retail",
                    "total_cost",
                    "total_qty",
                    "active",
                    "status",
                    "source_pdf",
                    "size_range",
                    "size_scale",
                    "created_at",
                    "updated_at",
                )
            )
        ]
    elif filter_field == "po_number" and query:
        filtered = [
            row
            for row in filtered
            if po_number_matches_query(row) or self.display_value(row.get(filter_field)).strip().lower() == query
        ]
    elif query:
        filtered = [
            row
            for row in filtered
            if self.display_value(row.get(filter_field)).strip().lower() == query
        ]

    sort_key = self.sort_key_internal
    reverse = self.sort_order_internal == "desc"
    sort_map = {
        "po_number": "po_number",
        "dept_number": "dept_number",
        "po_date": "po_date",
        "order_date": "order_date",
        "ship_date": "ship_date",
        "cancel_date": "cancel_date",
        "season": "season",
        "vendor": "vendor_name",
        "total_packs_ordered": "total_packs_ordered",
        "store_number": "store_number",
        "size_range": "size_range",
        "size_scale": "size_scale",
        "line_cost": "line_cost",
        "line_comp": "line_comp",
        "line_retail": "line_retail",
        "total_cost": "total_cost",
        "total_qty": "total_qty",
        "version_number": "version_number",
        "active": "is_active",
        "status": "status",
        "created_at": "created_at",
        "updated_at": "updated_at",
    }
    data_key = sort_map.get(sort_key, "po_number")
    filtered.sort(key=lambda row: self.parse_sort_value(sort_key, row.get(data_key, "")), reverse=reverse)
    self.filtered_orders = list(filtered)
    self.update_po_list_totals()
    self.update_report_target_summary()
    if hasattr(self, "orders_tree"):
        self.refresh_orders_tree()


def commit_po_search_query(self, value: object | None = None, *, apply_filter: bool = True) -> None:
    committed_value = self.search_var.get() if value is None else value
    self.po_search_committed_value = str(committed_value or "").strip()
    if apply_filter:
        self.apply_filters_and_sort()


def on_po_search_submit(self, _event: object | None = None) -> str:
    self.commit_po_search_query()
    return "break"


def sync_po_search_query(self, value: object) -> None:
    normalized_value = str(value or "").strip()
    self.search_var.set(normalized_value)
    self.po_search_committed_value = normalized_value


def schedule_po_filter_apply(self) -> None:
    self.commit_po_search_query()


def run_po_filter_apply(self) -> None:
    self.apply_filters_and_sort()


def update_po_filter_input_state(self, *, clear_irrelevant: bool = False) -> None:
    filter_field = getattr(self, "po_filter_field_internal", "__all__")
    is_date_field = filter_field in PO_DATE_FILTER_FIELDS
    if hasattr(self, "search_entry"):
        self.search_entry.configure(state="disabled" if is_date_field else "normal")
    if hasattr(self, "po_date_from_entry"):
        self.po_date_from_entry.configure(state="normal" if is_date_field else "disabled")
    if hasattr(self, "po_date_to_entry"):
        self.po_date_to_entry.configure(state="normal" if is_date_field else "disabled")
    if clear_irrelevant:
        self._po_filter_update_suspended = True
        try:
            if is_date_field:
                self.sync_po_search_query("")
            else:
                self.po_date_from_var.set("")
                self.po_date_to_var.set("")
        finally:
            self._po_filter_update_suspended = False


def on_order_selected(self, _event: object) -> None:
    selection = self.orders_tree.selection()
    if selection:
        self.select_po_tree_display_row(selection[0])


def on_orders_tree_click(self, event: tk.Event) -> str | None:
    region = self.orders_tree.identify_region(event.x, event.y)
    if region != "cell":
        return None

    column = self.orders_tree.identify_column(event.x)
    if column != "#1":
        return None

    row_id = self.orders_tree.identify_row(event.y)
    if not row_id:
        return None

    order_id = self.select_po_tree_display_row(row_id)
    if order_id in self.checked_order_ids:
        self.checked_order_ids.remove(order_id)
    else:
        self.checked_order_ids.add(order_id)

    self.update_orders_tree_export_state()
    self.orders_tree.selection_set(row_id)
    self.orders_tree.focus(row_id)
    return "break"


def clear_order_details(self) -> None:
    self.selected_order_id = None
    self.selected_order_style = ""
    if not self.header_vars:
        return
    for key, variable in self.header_vars.items():
        variable.set("")
        widget = self.header_value_widgets.get(key)
        if widget is not None:
            widget.configure(foreground=self.default_label_foreground, background=self.default_label_background)
    if self.items_tree is not None:
        for item in self.items_tree.get_children():
            self.items_tree.delete(item)
    if hasattr(self, "item_total_packs_var") and self.item_total_packs_var is not None:
        self.item_total_packs_var.set("0")
    if hasattr(self, "item_total_units_var") and self.item_total_units_var is not None:
        self.item_total_units_var.set("0")
    if self.instructions_text is not None:
        self.instructions_text.delete("1.0", tk.END)


def get_filtered_po_detail_items(self, order: dict) -> list[dict]:
    items = [dict(item) for item in list(order.get("items", [])) if isinstance(item, dict)]
    selected_style = _normalize_po_style_text(getattr(self, "selected_order_style", ""))
    if selected_style:
        return [
            item
            for item in items
            if _normalize_po_style_text(item.get("mfg_style") or item.get("style_code")) == selected_style
        ]

    query = str(getattr(self, "po_search_committed_value", self.search_var.get()) or "").strip().lower()
    if not query:
        return items

    filter_field = getattr(self, "po_filter_field_internal", "__all__")
    item_field_map = {
        "__all__": None,
        "style": "mfg_style",
    }
    item_field = item_field_map.get(filter_field)
    if filter_field not in {"__all__", "style"}:
        return items

    query_digits = "".join(ch for ch in query if ch.isdigit()).lstrip("0")
    po_digits = "".join(ch for ch in str((order.get("header") or {}).get("po_number", "") or "") if ch.isdigit()).lstrip("0")
    if filter_field == "__all__" and query_digits and query_digits == po_digits:
        return items

    filtered_items: list[dict] = []
    for item in items:
        if item_field:
            if _normalize_po_item_text(item.get(item_field)) == query:
                filtered_items.append(item)
            continue

        haystack = " ".join(
            _normalize_po_item_text(item.get(key))
            for key in ("sku", "mfg_style", "mfg_color", "size_desc", "description", "upc")
        )
        if query in haystack:
            filtered_items.append(item)
    if filter_field == "__all__" and not filtered_items:
        return items
    return filtered_items


def update_po_item_totals(self, items: list[dict]) -> None:
    total_packs = sum(_parse_po_item_number(item.get("total_packs")) for item in items)
    total_units = sum(_parse_po_item_number(item.get("total_units")) for item in items)
    if hasattr(self, "item_total_packs_var") and self.item_total_packs_var is not None:
        self.item_total_packs_var.set(_format_po_item_total(total_packs))
    if hasattr(self, "item_total_units_var") and self.item_total_units_var is not None:
        self.item_total_units_var.set(_format_po_item_total(total_units))


def update_po_list_totals(self) -> None:
    total_qty = sum(_parse_po_item_number(row.get("total_qty")) for row in list(getattr(self, "filtered_orders", []) or []))
    if hasattr(self, "po_list_total_qty_var") and self.po_list_total_qty_var is not None:
        self.po_list_total_qty_var.set(_format_po_item_total(total_qty))


def delete_selected_po(self) -> None:
    if not self.is_action_allowed("action.purchase_order.delete_po"):
        return
    selected_ids = sorted(self.checked_order_ids)
    if selected_ids:
        orders_to_delete: list[tuple[int, str, list[int]]] = []
        seen_delete_groups: set[str] = set()
        for order_id in selected_ids:
            selected_row = next(
                (
                    row
                    for row in list(getattr(self, "all_orders", []) or [])
                    if isinstance(row, dict) and self.po_base_order_id(row) == int(order_id)
                ),
                None,
            )
            group_key = self.purchase_order_history_group_key(selected_row or {"id": order_id})
            if group_key in seen_delete_groups:
                continue
            seen_delete_groups.add(group_key)
            version_ids = self.purchase_order_version_ids_for_order_id(order_id)
            po_number = str((selected_row or {}).get("po_number", "")).strip()
            if not po_number:
                order = self.fetch_order_detail_from_source(order_id)
                if order is not None:
                    po_number = str(order["header"].get("po_number", "")).strip()
            orders_to_delete.append((order_id, po_number, version_ids))
        if not orders_to_delete:
            self.refresh_orders(force=True)
            self.clear_order_details()
            return

        if len(orders_to_delete) == 1:
            confirm_message = self.t("delete_po_message", po_number=orders_to_delete[0][1])
        else:
            preview = ", ".join(po_number or str(order_id) for order_id, po_number, _version_ids in orders_to_delete[:5])
            if len(orders_to_delete) > 5:
                preview += ", ..."
            confirm_message = (
                f"Are you sure you want to delete {len(orders_to_delete)} purchase orders?\n\n"
                f"{preview}\n\n"
                "This action cannot be undone."
            )

        if not messagebox.askyesno(self.t("delete_po_title"), confirm_message):
            return

        failed_deletes: list[str] = []
        for order_id, po_number, version_ids in orders_to_delete:
            for version_id in version_ids:
                try:
                    self.delete_purchase_order_from_source(version_id)
                    self.checked_order_ids.discard(version_id)
                except Exception as exc:
                    failed_deletes.append(f"{po_number or version_id}: {exc}")
            self.checked_order_ids.discard(order_id)

        self.refresh_orders(force=True)
        self.clear_order_details()
        if failed_deletes:
            messagebox.showwarning(
                self.t("delete_po_title"),
                "Some purchase orders could not be deleted:\n\n" + "\n".join(failed_deletes[:10]),
            )
            return
        if len(orders_to_delete) == 1:
            self.set_status(self.t("delete_po_done", po_number=orders_to_delete[0][1]))
        else:
            self.set_status(f"Deleted {len(orders_to_delete)} purchase orders.")
        return

    selection = self.orders_tree.selection()
    if not selection:
        messagebox.showwarning(self.t("error_title"), self.t("delete_po_missing"))
        return

    order_id = self.po_tree_item_order_id(selection[0])
    order = self.fetch_order_detail_from_source(order_id)
    if order is None:
        self.refresh_orders()
        self.clear_order_details()
        return

    po_number = order["header"].get("po_number", "")
    confirmed = messagebox.askyesno(
        self.t("delete_po_title"),
        self.t("delete_po_message", po_number=po_number),
    )
    if not confirmed:
        return

    version_ids = self.purchase_order_version_ids_for_order_id(order_id)
    failed_deletes: list[str] = []
    try:
        for version_id in version_ids:
            self.delete_purchase_order_from_source(version_id)
            self.checked_order_ids.discard(version_id)
    except Exception as exc:
        failed_deletes.append(str(exc))
    if failed_deletes:
        messagebox.showwarning(self.t("delete_po_title"), "\n".join(failed_deletes[:10]))
        self.refresh_orders(force=True)
        return
    self.checked_order_ids.discard(order_id)
    self.refresh_orders(force=True)
    self.clear_order_details()
    self.set_status(self.t("delete_po_done", po_number=po_number))


def show_selected_po_history(self) -> None:
    if not self.is_action_allowed("action.purchase_order.compare_po"):
        return
    selection = self.orders_tree.selection() if hasattr(self, "orders_tree") else ()
    if selection:
        order_id = self.po_tree_item_order_id(selection[0])
    else:
        order_id = int(getattr(self, "selected_order_id", 0) or 0)
    if not order_id:
        messagebox.showwarning(self.t("po_history_title"), self.t("po_history_need_one"))
        return

    try:
        report = self.build_po_history_report(order_id)
    except ValueError as exc:
        messagebox.showwarning(self.t("po_history_title"), str(exc))
        return

    if report in {self.t("po_history_no_diff"), self.t("po_history_no_versions")}:
        messagebox.showinfo(self.t("po_history_title"), report)
        return

    self.show_compare_report(self.t("po_history_result_title"), report)


def selected_po_order_ids(self) -> list[int]:
    selected_ids = sorted(int(order_id) for order_id in getattr(self, "checked_order_ids", set()) if int(order_id) > 0)
    if selected_ids:
        return selected_ids
    selection = self.orders_tree.selection() if hasattr(self, "orders_tree") else ()
    if selection:
        try:
            return [self.po_tree_item_order_id(selection[0])]
        except Exception:
            return []
    selected_order_id = int(getattr(self, "selected_order_id", 0) or 0)
    return [selected_order_id] if selected_order_id > 0 else []


def quick_update_po_status(self) -> None:
    if not self.is_action_allowed("action.purchase_order.edit_po"):
        return
    order_ids = self.selected_po_order_ids()
    if not order_ids:
        messagebox.showwarning(self.t("quick_po_status_title"), self.t("quick_po_status_need_selection"))
        return

    dialog = tk.Toplevel(self.root)
    dialog.title(self.t("quick_po_status_title"))
    dialog.transient(self.root)
    dialog.grab_set()

    frame = ttk.Frame(dialog, padding=16)
    frame.pack(fill="both", expand=True)
    frame.columnconfigure(1, weight=1)

    ttk.Label(frame, text=self.t("quick_po_status_count", count=len(order_ids))).grid(
        row=0,
        column=0,
        columnspan=2,
        sticky="w",
        pady=(0, 12),
    )
    status_var = tk.StringVar(value="checking")
    ttk.Label(frame, text=self.t("status")).grid(row=1, column=0, sticky="w", padx=(0, 10), pady=4)
    ttk.Combobox(
        frame,
        textvariable=status_var,
        values=("draft", "checking", "approved"),
        state="readonly",
        width=18,
    ).grid(row=1, column=1, sticky="ew", pady=4)

    actions = ttk.Frame(frame)
    actions.grid(row=2, column=0, columnspan=2, sticky="e", pady=(14, 0))

    def apply_status() -> None:
        target_status = str(status_var.get() or "").strip().lower()
        if target_status not in {"draft", "checking", "approved"}:
            return
        if target_status == "approved" and not self.is_action_allowed("action.purchase_order.approve"):
            self.deny_permission_action("action.purchase_order.approve")
            return
        dialog.destroy()
        self.start_quick_po_status_worker(order_ids, target_status)

    ttk.Button(actions, text=self.t("collection_list_save"), command=apply_status).pack(side="right")
    ttk.Button(actions, text=self.t("close"), command=dialog.destroy).pack(side="right", padx=(0, 8))
    self.center_dialog(dialog, min_width=360, min_height=170)
    dialog.wait_window()


def start_quick_po_status_worker(self, order_ids: list[int], target_status: str) -> None:
    normalized_ids: list[int] = []
    for order_id in order_ids:
        try:
            normalized_id = int(order_id)
        except (TypeError, ValueError):
            continue
        if normalized_id > 0 and normalized_id not in normalized_ids:
            normalized_ids.append(normalized_id)
    if not normalized_ids:
        return
    if getattr(self, "quick_po_status_loading", False):
        messagebox.showinfo(self.t("quick_po_status_title"), self.t("quick_po_status_running"))
        return

    self.quick_po_status_loading = True
    quick_button = getattr(self, "widget_text", {}).get("quick_po_status_button")
    if quick_button is not None:
        try:
            quick_button.configure(state="disabled")
        except tk.TclError:
            pass
    self.set_status(self.t("quick_po_status_running_count", count=len(normalized_ids)))

    def worker() -> None:
        updated_count = 0
        skipped_count = 0
        updated_order_ids: list[int] = []
        updated_versions: list[dict[str, int]] = []
        failed: list[str] = []
        for order_id in normalized_ids:
            try:
                order = self.fetch_order_detail_from_source(order_id)
                if order is None:
                    failed.append(str(order_id))
                    continue
                header = dict(order.get("header", {}))
                before_header = dict(header)
                if str(header.get("status", "") or "").strip().lower() == target_status:
                    skipped_count += 1
                    continue
                header["status"] = target_status
                header["items"] = list(order.get("items", []) or [])
                saved_order_id = self.push_purchase_order_to_source(header)
                self.record_quick_po_status_history_in_worker(
                    entity_key=saved_order_id or order_id,
                    entity_label=str(header.get("po_number", "")).strip() or str(order_id),
                    before_header=before_header,
                    target_status=target_status,
                    summary=f"Quick status PO {header.get('po_number', '')}: {target_status}",
                )
                updated_count += 1
                updated_order_ids.append(order_id)
                try:
                    saved_order_id_int = int(saved_order_id or 0)
                except (TypeError, ValueError):
                    saved_order_id_int = 0
                updated_versions.append({"order_id": order_id, "saved_order_id": saved_order_id_int})
            except Exception as exc:
                failed.append(f"{order_id}: {exc}")
        payload = {
            "target_status": target_status,
            "updated_count": updated_count,
            "skipped_count": skipped_count,
            "updated_order_ids": updated_order_ids,
            "updated_versions": updated_versions,
            "failed": failed,
        }
        self.schedule_root_after(0, lambda result=payload: self.finish_quick_po_status_worker(result))

    threading.Thread(target=worker, daemon=True).start()


def record_quick_po_status_history_in_worker(
    self,
    *,
    entity_key: object,
    entity_label: str,
    before_header: dict,
    target_status: str,
    summary: str,
) -> None:
    should_record, changed_fields, row_details = self.should_record_entity_history(
        action="update",
        before={"header": before_header},
        after={"header": {"status": target_status}},
        details=None,
    )
    if not should_record:
        return
    normalized_entity_key = str(entity_key or "").strip()
    if not normalized_entity_key:
        return
    actor = self.get_current_actor_snapshot()
    changed_at = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    history_row = {
        "history_id": uuid.uuid4().hex,
        "scope": "purchase_order",
        "entity_key": normalized_entity_key,
        "entity_label": str(entity_label or normalized_entity_key).strip(),
        "action": "update",
        "user_email": actor["email"],
        "user_display_name": actor["display_name"],
        "changed_at": changed_at,
        "summary": str(summary or "").strip() or (", ".join(changed_fields[:4]) if changed_fields else "Updated record"),
        "details": row_details,
    }
    latest_map = dict(getattr(self, "entity_latest_user_map", {}) or {})
    audit_key = self.build_entity_audit_key("purchase_order", normalized_entity_key)
    latest_map[audit_key] = {
        "scope": "purchase_order",
        "entity_key": normalized_entity_key,
        "user_email": actor["email"],
        "user_display_name": actor["display_name"],
        "changed_at": changed_at,
    }
    history_rows = list(getattr(self, "history_rows", []) or [])
    history_rows.append(history_row)
    self.entity_latest_user_map = self.save_entity_latest_users_to_source(latest_map)
    try:
        self.history_rows = self.save_entity_history_rows_to_source(history_rows)
    except Exception:
        self.history_rows = self.prepare_entity_history_rows_for_storage(history_rows)


def finish_quick_po_status_worker(self, payload: dict) -> None:
    self.quick_po_status_loading = False
    quick_button = getattr(self, "widget_text", {}).get("quick_po_status_button")
    if quick_button is not None:
        try:
            quick_button.configure(state="normal")
        except tk.TclError:
            pass

    target_status = str(payload.get("target_status", "") or "").strip().lower()
    updated_order_ids = {
        int(order_id)
        for order_id in list(payload.get("updated_order_ids", []) or [])
        if str(order_id).strip().isdigit()
    }
    if target_status and updated_order_ids:
        version_rows = [
            dict(row)
            for row in list(getattr(self, "all_order_versions", []) or [])
            if isinstance(row, dict)
        ]
        version_rows_by_id: dict[int, dict] = {}
        for row in version_rows:
            try:
                row_id = int(row.get("id", 0) or 0)
            except (TypeError, ValueError):
                row_id = 0
            if row_id > 0:
                version_rows_by_id[row_id] = row
        id_replacements: dict[int, int] = {}
        for item in list(payload.get("updated_versions", []) or []):
            if not isinstance(item, dict):
                continue
            try:
                original_id = int(item.get("order_id", 0) or 0)
                saved_id = int(item.get("saved_order_id", 0) or 0)
            except (TypeError, ValueError):
                continue
            if original_id <= 0:
                continue
            target_id = saved_id if saved_id > 0 else original_id
            id_replacements[original_id] = target_id
            source_row = version_rows_by_id.get(original_id)
            if source_row is None:
                continue
            next_row = dict(source_row)
            next_row["id"] = target_id
            next_row["status"] = target_status
            next_row["updated_at"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            if target_id in version_rows_by_id:
                version_rows_by_id[target_id].update(next_row)
            else:
                version_rows.append(next_row)
                version_rows_by_id[target_id] = next_row

        for row in version_rows:
            try:
                row_id = int(row.get("id", 0) or 0)
            except (TypeError, ValueError):
                row_id = 0
            if row_id in updated_order_ids:
                row["status"] = target_status
        self.all_order_versions = version_rows
        self.all_orders = self.build_purchase_order_style_display_rows(self.extract_latest_purchase_order_versions(version_rows))
        if hasattr(self, "checked_order_ids"):
            valid_order_ids = {self.po_base_order_id(row) for row in self.all_orders}
            next_checked_ids: set[int] = set()
            for order_id in set(getattr(self, "checked_order_ids", set()) or set()):
                try:
                    checked_id = int(order_id)
                except (TypeError, ValueError):
                    continue
                mapped_id = id_replacements.get(checked_id, checked_id)
                if mapped_id in valid_order_ids:
                    next_checked_ids.add(mapped_id)
            self.checked_order_ids = next_checked_ids
        self.apply_filters_and_sort()
        if getattr(self, "current_module", "") == "history" and hasattr(self, "apply_history_filter"):
            self.apply_history_filter()

    updated_count = int(payload.get("updated_count", 0) or 0)
    failed = list(payload.get("failed", []) or [])
    self.set_status(self.t("quick_po_status_done", count=updated_count, status=target_status))
    if failed:
        messagebox.showwarning(
            self.t("quick_po_status_title"),
            self.t("quick_po_status_failed", count=len(failed)) + "\n\n" + "\n".join(str(item) for item in failed[:10]),
        )


def build_ship_to_full(self, header: dict) -> str:
    parts = []
    if header.get("ship_to_name"):
        parts.append(str(header["ship_to_name"]).strip())
    if header.get("store_number"):
        parts.append(f"Store: {header['store_number']}")
    if header.get("ship_to_address"):
        parts.append(str(header["ship_to_address"]).strip())
    if header.get("mark_for"):
        parts.append(f"Mark For: {header['mark_for']}")
    return "\n".join(part for part in parts if part)


def load_order(self, order_id: int) -> None:
    order = self.fetch_order_detail_from_source(order_id)
    if order is None:
        return

    self.selected_order_id = order_id
    if not self.header_vars or self.items_tree is None or self.instructions_text is None:
        return
    header = dict(order["header"])
    header["ship_to_full"] = self.build_ship_to_full(header)

    for key, variable in self.header_vars.items():
        if key == "is_active":
            value = "Active" if bool(header.get(key, True)) else "Inactive"
        elif key == "status":
            value = str(header.get(key, "draft") or "draft").strip().lower()
        else:
            value = self.display_value(header.get(key, ""))
        variable.set(value)
        widget = self.header_value_widgets.get(key)
        if widget is not None:
            if value == self.missing_display_value:
                widget.configure(foreground=self.missing_foreground, background=self.missing_background)
            else:
                widget.configure(foreground=self.default_label_foreground, background=self.default_label_background)

    for item in self.items_tree.get_children():
        self.items_tree.delete(item)

    all_items = [dict(item) for item in list(order.get("items", [])) if isinstance(item, dict)]
    detail_items = self.get_filtered_po_detail_items(order)
    self.po_detail_item_source_indices = []
    for original_index, item in enumerate(all_items):
        if item in detail_items:
            self.po_detail_item_source_indices.append(original_index)
    for index, item in enumerate(detail_items, start=1):
        self.items_tree.insert(
            "",
            "end",
            iid=str(index),
            values=(
                item["sku"],
                item["mfg_style"],
                item["mfg_color"],
                item["size_desc"],
                item["description"],
                item["upc"],
                item["cost_unit"],
                item["comp"],
                item["retail"],
                item["pack_qty"],
                item["total_packs"],
                item["total_units"],
            ),
            tags=("odd_row" if index % 2 == 1 else "even_row",),
        )
    self.update_po_item_totals(detail_items)

    if self.items_tree.exists("1"):
        self.items_tree.selection_set("1")
        self.items_tree.focus("1")

    self.instructions_text.delete("1.0", tk.END)
    self.instructions_text.insert("1.0", self.display_value(header.get("special_instructions", "")))
    self.set_status(self.t("viewing_po", po_number=header.get("po_number", "")))


def bind_po_module(app_cls: type) -> None:
    method_map = {
        "build_purchase_order_module": build_purchase_order_module,
        "_add_header_field": _add_header_field,
        "build_po_detail_widgets": build_po_detail_widgets,
        "close_po_detail_window": close_po_detail_window,
        "open_po_detail_window": open_po_detail_window,
        "refresh_orders_tree": refresh_orders_tree,
        "update_orders_tree_export_state": update_orders_tree_export_state,
        "purchase_order_history_group_key": purchase_order_history_group_key,
        "parse_purchase_order_version_datetime": parse_purchase_order_version_datetime,
        "purchase_order_version_sort_key": purchase_order_version_sort_key,
        "extract_latest_purchase_order_versions": extract_latest_purchase_order_versions,
        "purchase_order_version_ids_for_order_id": purchase_order_version_ids_for_order_id,
        "po_base_order_id": po_base_order_id,
        "po_tree_item_order_id": po_tree_item_order_id,
        "po_tree_item_display_id": po_tree_item_display_id,
        "po_display_style_for_item_id": po_display_style_for_item_id,
        "select_po_tree_display_row": select_po_tree_display_row,
        "build_purchase_order_style_display_rows": build_purchase_order_style_display_rows,
        "refresh_orders": refresh_orders,
        "apply_filters_and_sort": apply_filters_and_sort,
        "commit_po_search_query": commit_po_search_query,
        "on_po_search_submit": on_po_search_submit,
        "schedule_po_filter_apply": schedule_po_filter_apply,
        "run_po_filter_apply": run_po_filter_apply,
        "sync_po_search_query": sync_po_search_query,
        "update_po_filter_input_state": update_po_filter_input_state,
        "on_order_selected": on_order_selected,
        "on_orders_tree_double_click": on_orders_tree_double_click,
        "on_orders_tree_click": on_orders_tree_click,
        "clear_order_details": clear_order_details,
        "get_filtered_po_detail_items": get_filtered_po_detail_items,
        "update_po_item_totals": update_po_item_totals,
        "update_po_list_totals": update_po_list_totals,
        "delete_selected_po": delete_selected_po,
        "compare_selected_pos": show_selected_po_history,
        "show_selected_po_history": show_selected_po_history,
        "selected_po_order_ids": selected_po_order_ids,
        "quick_update_po_status": quick_update_po_status,
        "start_quick_po_status_worker": start_quick_po_status_worker,
        "record_quick_po_status_history_in_worker": record_quick_po_status_history_in_worker,
        "finish_quick_po_status_worker": finish_quick_po_status_worker,
        "build_ship_to_full": build_ship_to_full,
        "load_order": load_order,
    }
    for method_name, function in method_map.items():
        setattr(app_cls, method_name, function)
