"""
inventory_module.py — Module Quản lý Kho hàng (Nhập-Xuất-Tồn)
"""
import os
import sys
from PySide6.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QLabel, QFrame,
    QTableWidget, QTableWidgetItem, QHeaderView, QPushButton,
    QLineEdit, QScrollArea, QGroupBox, QGridLayout, QMessageBox, QDialog,
    QComboBox, QTabWidget, QAbstractItemView, QDoubleSpinBox, QTextEdit, QFileDialog
)
from PySide6.QtCore import Qt
from PySide6.QtGui import QFont, QColor

from gui.theme import COLORS
from gui.ui_helpers import (
    SP, PrimaryButton, SecondaryButton, DangerButton, GhostButton,
    make_input, make_combo, make_date_edit, make_form, make_group,
    CardFrame, apply_table_style, IconButton, FilterBar, PageHeader,
    make_spinbox, show_toast
)
from core.inventory import (
    get_stock_summary, add_product, get_next_product_code,
    get_categories, add_category, update_category, delete_category
)
from core.hkd_tax import SIMPLE_INDUSTRY_NAMES

class CategoryDialog(QDialog):
    """Dialog thêm/sửa Ngành nghề mới."""
    def __init__(self, cat_id=None, name="", desc="", gtgt_rate=0.0, tncn_rate=0.0, parent=None):
        super().__init__(parent)
        self.cat_id = cat_id
        if cat_id:
            self.setWindowTitle("✏️ Sửa Nhóm Thuế")
        else:
            self.setWindowTitle("➕ Thêm Nhóm Thuế mới")
        self.setFixedWidth(620)
        
        layout = QVBoxLayout(self)
        layout.setSpacing(12)
        self.form = make_group("Thông tin Ngành nghề")
        grid = make_form()
        
        self.inp_name = make_input("VD: Nhóm dịch vụ, Sản xuất, Vận tải...")
        self.inp_name.setText(name)
        grid.addRow(QLabel("Tên nhóm:"), self.inp_name)
        
        # Khung mô tả đa dòng
        self.inp_desc = QTextEdit()
        self.inp_desc.setPlaceholderText("Nhập mô tả chi tiết ngành nghề...")
        self.inp_desc.setMinimumHeight(90)
        self.inp_desc.setMaximumHeight(120)
        self.inp_desc.setText(desc)
        self.inp_desc.setStyleSheet(
            f"border: 1px solid #d1d5db; border-radius: 6px; "
            f"padding: 6px 10px; font-size: 13px; background: #ffffff;"
        )
        grid.addRow(QLabel("Mô tả:"), self.inp_desc)
        
        # Thêm cấu hình % GTGT và % TNCN
        self.inp_gtgt = make_spinbox(0, 100, suffix=" %")
        self.inp_gtgt.setSingleStep(0.5)
        self.inp_gtgt.setDecimals(2)
        self.inp_gtgt.setValue(gtgt_rate)
        grid.addRow(QLabel("% GTGT:"), self.inp_gtgt)

        self.inp_tncn = make_spinbox(0, 100, suffix=" %")
        self.inp_tncn.setSingleStep(0.5)
        self.inp_tncn.setDecimals(2)
        self.inp_tncn.setValue(tncn_rate)
        grid.addRow(QLabel("% TNCN:"), self.inp_tncn)
        
        self.form.layout().addLayout(grid)
        layout.addWidget(self.form)
        
        btns = QHBoxLayout()
        btn_cancel = SecondaryButton("Hủy", icon="❌")
        btn_cancel.clicked.connect(self.reject)
        
        btn_save = PrimaryButton("Lưu", icon="💾")
        btn_save.clicked.connect(self.accept)
        
        btns.addStretch()
        btns.addWidget(btn_cancel)
        btns.addWidget(btn_save)
        layout.addLayout(btns)

    def get_data(self):
        return {
            "name": self.inp_name.text().strip(),
            "description": self.inp_desc.toPlainText().strip(),
            "gtgt_rate": self.inp_gtgt.value(),
            "tncn_rate": self.inp_tncn.value(),
        }


class ProductDialog(QDialog):
    """Dialog thêm sản phẩm mới."""
    def __init__(self, categories, default_code="HH001", parent=None):
        super().__init__(parent)
        self.setWindowTitle("➕ Thêm sản phẩm mới")
        self.setFixedWidth(550)  # Mở rộng dialog để xem hết tên ngành nghề dài
        
        layout = QVBoxLayout(self)
        self.form = make_group("Thông tin hàng hóa")
        grid = make_form()
        
        self.inp_code = make_input("Ví dụ: HH001")
        self.inp_code.setText(default_code)
        grid.addRow(QLabel("Mã hàng:"), self.inp_code)
        
        self.inp_name = make_input()
        self.inp_name.setFocus() # Focus vào tên hàng để nhập cho nhanh
        grid.addRow(QLabel("Tên hàng:"), self.inp_name)

        self.combo_cat = make_combo(["--- Không chọn ---"])
        self.combo_cat.setItemData(0, None)
        for c in categories:
            # Tính tổng thuế (%)
            gtgt = float(c.get("gtgt_rate") or 0.0)
            tncn = float(c.get("tncn_rate") or 0.0)
            total = gtgt + tncn
            # Format: Nhóm X — Tên... - X%
            display_text = f"{c['name']} - {total:g}%"
            self.combo_cat.addItem(display_text, c["id"])
        grid.addRow(QLabel("Nhóm Thuế:"), self.combo_cat)
        
        self.inp_unit = make_combo(["Cái", "Bộ", "Chiếc", "Kg", "Mét", "Gói", "Thùng", "Lon", "Chai", "Cuộn"])
        self.inp_unit.setEditable(True)  # Cho phép tự điền thêm
        grid.addRow(QLabel("Đơn vị tính:"), self.inp_unit)
        
        self.inp_buy = make_input()
        self.inp_buy.setText("0")
        grid.addRow(QLabel("Giá mua:"), self.inp_buy)
        
        self.inp_sell = make_input()
        self.inp_sell.setText("0")
        grid.addRow(QLabel("Giá bán:"), self.inp_sell)
        
        self.form.layout().addLayout(grid)
        layout.addWidget(self.form)
        
        # Buttons
        btns = QHBoxLayout()
        btn_cancel = SecondaryButton("Hủy")
        btn_cancel.clicked.connect(self.reject)
        
        btn_save = PrimaryButton("Lưu")
        btn_save.clicked.connect(self.accept)
        
        btns.addStretch()
        btns.addWidget(btn_cancel)
        btns.addWidget(btn_save)
        layout.addLayout(btns)

    def get_data(self):
        cat_id = self.combo_cat.currentData()
        
        return {
            "code": self.inp_code.text().strip(),
            "name": self.inp_name.text().strip(),
            "unit": self.inp_unit.currentText().strip(),
            "category_id": cat_id,
            "buy": float(self.inp_buy.text().replace(',', '') or 0),
            "sell": float(self.inp_sell.text().replace(',', '') or 0)
        }

class CategoryTab(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 16, 0, 16)
        layout.setSpacing(15)

        t_layout = QHBoxLayout()
        btn_add = PrimaryButton("Thêm Nhóm", icon="➕")
        btn_add.clicked.connect(self._on_add)
        
        btn_edit = SecondaryButton("Sửa", icon="✏️")
        btn_edit.clicked.connect(self._on_edit)
        
        btn_del = DangerButton("Xóa", icon="✕")
        btn_del.clicked.connect(self._on_del)

        btn_refresh = SecondaryButton("Làm mới", icon="🔄")
        btn_refresh.clicked.connect(self._on_refresh)

        t_layout.addWidget(btn_add)
        t_layout.addWidget(btn_edit)
        t_layout.addWidget(btn_del)
        t_layout.addWidget(btn_refresh)
        t_layout.addStretch()
        
        layout.addLayout(t_layout)

        self.table = QTableWidget()
        self.table.setColumnCount(6)
        self.table.setHorizontalHeaderLabels(["ID", "Tên nhóm gốc", "% GTGT", "% TNCN", "Thuế ra (%)", "Mô tả"])
        self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(5, QHeaderView.ResizeMode.Stretch)
        self.table.verticalHeader().setVisible(False)
        self.table.setAlternatingRowColors(True)
        self.table.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
        self.table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
        self.table.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
        apply_table_style(self.table)

        layout.addWidget(self.table)
        
    def _on_add(self):
        main = self.window()
        db_path = getattr(main, "current_db_path", "")
        if not db_path:
            QMessageBox.warning(self, "Lỗi", "Vui lòng chọn database trước.")
            return
            
        dlg = CategoryDialog(parent=self)
        if dlg.exec():
            data = dlg.get_data()
            if not data["name"]:
                QMessageBox.warning(self, "Lỗi", "Tên nhóm không được để trống.")
                return
            try:
                add_category(db_path, data["name"], data["description"], data["gtgt_rate"], data["tncn_rate"])
                self.refresh()
                show_toast(self.window(), f"Đã thêm nhóm: {data['name']}")
            except Exception as e:
                QMessageBox.critical(self, "Lỗi", f"Không thể thêm. Có thể tên bị trùng.\nChi tiết: {e}")

    def _on_edit(self):
        rows = self.table.selectedItems()
        if not rows:
            QMessageBox.warning(self, "Lỗi", "Vui lòng chọn một nhóm để sửa.")
            return
        
        row = rows[0].row()
        cat_id = int(self.table.item(row, 0).text())
        name = self.table.item(row, 1).text()
        gtgt_rate = self.table.item(row, 2).data(Qt.ItemDataRole.UserRole) or 0.0
        tncn_rate = self.table.item(row, 3).data(Qt.ItemDataRole.UserRole) or 0.0
        desc = self.table.item(row, 5).text() if self.table.item(row, 5) else ""
        
        main = self.window()
        db_path = getattr(main, "current_db_path", "")
        
        dlg = CategoryDialog(cat_id, name, desc, gtgt_rate, tncn_rate, parent=self)
        if dlg.exec():
            data = dlg.get_data()
            if not data["name"]:
                QMessageBox.warning(self, "Lỗi", "Tên nhóm không được để trống.")
                return
            try:
                update_category(db_path, cat_id, data["name"], data["description"], data["gtgt_rate"], data["tncn_rate"])
                self.refresh()
                show_toast(self.window(), f"Đã cập nhật nhóm: {data['name']}")
            except Exception as e:
                QMessageBox.critical(self, "Lỗi", f"Không thể sửa: {e}")

    def _on_del(self):
        rows = self.table.selectedItems()
        if not rows:
            QMessageBox.warning(self, "Lỗi", "Vui lòng chọn một nhóm để xóa.")
            return
        
        row = rows[0].row()
        cat_id = int(self.table.item(row, 0).text())
        name = self.table.item(row, 1).text()
        
        reply = QMessageBox.question(self, "Xác nhận xóa", f"Bạn có chắc muốn xóa nhóm '{name}'?",
                                     QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
        if reply == QMessageBox.StandardButton.Yes:
            main = self.window()
            db_path = getattr(main, "current_db_path", "")
            try:
                delete_category(db_path, cat_id)
                self.refresh()
                show_toast(self.window(), f"Đã xóa nhóm: {name}")
            except Exception as e:
                QMessageBox.critical(self, "Lỗi", f"Không thể xóa: {e}")

    def _on_refresh(self):
        self.refresh()

    def refresh(self):
        main = self.window()
        db_path = getattr(main, "current_db_path", "")
        if not db_path or not os.path.exists(db_path):
            return
            
        try:
            cats = get_categories(db_path)
            self.table.setRowCount(len(cats))
            for i, c in enumerate(cats):
                self.table.setItem(i, 0, QTableWidgetItem(str(c["id"])))
                self.table.setItem(i, 1, QTableWidgetItem(c["name"]))
                
                gtgt = float(c.get("gtgt_rate") or 0.0)
                tncn = float(c.get("tncn_rate") or 0.0)
                total_tax = gtgt + tncn
                
                item_gtgt = QTableWidgetItem(f"{gtgt:g}%")
                item_gtgt.setData(Qt.ItemDataRole.UserRole, gtgt)
                self.table.setItem(i, 2, item_gtgt)
                
                item_tncn = QTableWidgetItem(f"{tncn:g}%")
                item_tncn.setData(Qt.ItemDataRole.UserRole, tncn)
                self.table.setItem(i, 3, item_tncn)
                
                self.table.setItem(i, 4, QTableWidgetItem(f"{total_tax:g}%"))
                
                self.table.setItem(i, 5, QTableWidgetItem(c.get("description") or ""))
        except Exception as e:
            print("Error parsing categories:", e)


class InventoryPage(QWidget):
    """Module Quản lý Kho hàng."""

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setObjectName("content_area")

        root = QVBoxLayout(self)
        root.setContentsMargins(16, 16, 16, 16)
        root.setSpacing(0)


        # TABS
        self.tabs = QTabWidget()
        self.tabs.setObjectName("tab_main")
        root.addWidget(self.tabs)

        self.inventory_tab = self._build_inventory_tab()
        self.category_tab = CategoryTab(self)

        self.tabs.addTab(self.inventory_tab, "📦 Hàng Hóa & Tồn Kho")
        self.tabs.addTab(self.category_tab, "🗂️ Nhóm Thuế HKD")


    def _build_inventory_tab(self):
        w = QWidget()
        layout = QVBoxLayout(w)
        layout.setContentsMargins(0, 0, 0, 0)

        # ── Toolbar ───────────────────────────────────────
        toolbar = QWidget()
        t_layout = QHBoxLayout(toolbar)
        t_layout.setContentsMargins(0, 10, 0, 5)

        btn_add = PrimaryButton("Thêm", icon="➕")
        btn_add.clicked.connect(self._on_add_product)

        btn_edit = SecondaryButton("Sửa", icon="✏️")
        btn_edit.clicked.connect(self._on_edit_product)

        btn_del = DangerButton("Xóa", icon="✕")
        btn_del.clicked.connect(self._on_delete_product)

        btn_import = SecondaryButton("Nạp từ Excel", icon="📥")
        btn_import.clicked.connect(self._on_import_products)

        btn_refresh = SecondaryButton("Làm mới", icon="🔄")
        btn_refresh.clicked.connect(self._on_refresh_clicked)

        t_layout.addWidget(btn_add)
        t_layout.addWidget(btn_edit)
        t_layout.addWidget(btn_del)
        t_layout.addWidget(btn_import)
        t_layout.addWidget(btn_refresh)
        t_layout.addStretch()
        layout.addWidget(toolbar)

        # ── Body ────────────────────────────────────────────
        body = QWidget()
        body_layout = QVBoxLayout(body)
        body_layout.setContentsMargins(0, 5, 0, 15)
        body_layout.setSpacing(15)

        # Table
        self.table = QTableWidget()
        self.table.setColumnCount(9)
        self.table.setHorizontalHeaderLabels([
            "Mã Hàng", "Tên Hàng Hóa", "Giá Bán", "Giá Mua", "Thuế", "ĐVT", "Tổng Nhập", "Tổng Xuất", "Tồn Cuối"
        ])
        self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
        self.table.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeMode.ResizeToContents)
        self.table.verticalHeader().setVisible(False)
        self.table.setAlternatingRowColors(True)
        self.table.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
        apply_table_style(self.table)
        
        body_layout.addWidget(self.table)
        layout.addWidget(body)
        return w


    def _on_add_product(self):
        main = self.window()
        db_path = getattr(main, "current_db_path", "")
        if not db_path:
            QMessageBox.warning(self, "Lỗi", "Vui lòng chọn database trước.")
            return
            
        # Get categories
        cats = get_categories(db_path)
            
        # Tự động lấy mã tiếp theo
        next_code = get_next_product_code(db_path)
        dlg = ProductDialog(categories=cats, default_code=next_code, parent=self)
        
        if dlg.exec():
            try:
                data = dlg.get_data()
                if not data["code"] or not data["name"]:
                    QMessageBox.warning(self, "Lỗi", "Mã và Tên hàng không được để trống.")
                    return
                add_product(db_path, data["code"], data["name"], data["unit"], data["category_id"], data["buy"], data["sell"])
                self.refresh(db_path)
                show_toast(self.window(), f"Đã thêm sản phẩm: {data['name']}")
            except Exception as e:
                QMessageBox.critical(self, "Lỗi", f"Không thể thêm: {e}")

    def _on_edit_product(self):
        main = self.window()
        db_path = getattr(main, "current_db_path", "")
        if not db_path: return

        items = self.table.selectedItems()
        if not items:
            QMessageBox.warning(self, "Lỗi", "Vui lòng chọn sản phẩm cần sửa.")
            return
        
        row = items[0].row()
        code = self.table.item(row, 0).text()
        
        # Lấy thông tin hiện tại từ database để pre-fill
        import sqlite3
        conn = sqlite3.connect(db_path)
        conn.row_factory = sqlite3.Row
        p = conn.cursor().execute("SELECT * FROM products WHERE code=?", (code,)).fetchone()
        conn.close()
        
        if not p: return

        msg = self.window()
        db_path = getattr(msg, "current_db_path", "")
        cats = get_categories(db_path)

        dlg = ProductDialog(categories=cats, default_code=p["code"], parent=self)
        dlg.setWindowTitle("✏️ Sửa sản phẩm")
        dlg.inp_name.setText(p["name"])
        dlg.inp_unit.setCurrentText(p["unit"])
        dlg.inp_buy.setText(str(p["purchase_price"]))
        dlg.inp_sell.setText(str(p["sale_price"]))
        
        # Chọn đúng category
        for i in range(dlg.combo_cat.count()):
            if dlg.combo_cat.itemData(i) == p["category_id"]:
                dlg.combo_cat.setCurrentIndex(i)
                break

        if dlg.exec():
            try:
                data = dlg.get_data()
                from core.inventory import update_product
                update_product(db_path, code, data["code"], data["name"], data["unit"], data["category_id"], data["buy"], data["sell"])
                self.refresh(db_path)
                show_toast(self.window(), f"Đã cập nhật sản phẩm: {data['name']}")
            except Exception as e:
                QMessageBox.critical(self, "Lỗi", f"Không thể cập nhật: {e}")

    def _on_delete_product(self):
        main = self.window()
        db_path = getattr(main, "current_db_path", "")
        if not db_path: return

        items = self.table.selectedItems()
        if not items:
            QMessageBox.warning(self, "Lỗi", "Vui lòng chọn sản phẩm cần xóa.")
            return
            
        row = items[0].row()
        code = self.table.item(row, 0).text()
        name = self.table.item(row, 1).text()
        
        ans = QMessageBox.question(self, "Xác nhận", f"Bạn có chắc muốn xóa sản phẩm '{name}' (Mã: {code})?",
                                   QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
        
        if ans == QMessageBox.StandardButton.Yes:
            try:
                from core.inventory import delete_product
                delete_product(db_path, code)
                self.refresh(db_path)
                show_toast(self.window(), f"Đã xóa sản phẩm: {name}")
            except Exception as e:
                QMessageBox.critical(self, "Lỗi", f"Không thể xóa: {e}")


    def _on_refresh_clicked(self):
        main = self.window()
        if hasattr(main, "current_db_path"):
            self.refresh(main.current_db_path)

    def _on_import_products(self):
        """Mở dialog chọn file Excel để import sản phẩm."""
        main = self.window()
        db_path = getattr(main, "current_db_path", "")
        if not db_path:
            QMessageBox.warning(self, "Lỗi", "Vui lòng chọn database trước.")
            return

        file_path, _ = QFileDialog.getOpenFileName(
            self, "Chọn file Excel để nạp sản phẩm", "", "Excel Files (*.xlsx)"
        )
        if not file_path:
            return

        try:
            import openpyxl
            wb = openpyxl.load_workbook(file_path, data_only=True)
            ws = wb.active

            print(f"[DEBUG] File Excel: {ws.max_row} dòng, {ws.max_column} cột")

            # Dòng đầu là header, bắt đầu từ dòng 2
            success_count = 0
            error_count = 0
            errors = []

            for row_idx, row in enumerate(ws.iter_rows(min_row=2, values_only=True), start=2):
                try:
                    # Cấu trúc file: Mã Hàng (col 0), Tên Hàng (col 1), Đơn vị (col 2), Giá Mua (col 3), Giá Bán (col 4)
                    if len(row) < 5:
                        errors.append(f"Dòng {row_idx}: Không đủ 5 cột dữ liệu")
                        error_count += 1
                        print(f"[SKIP] Dòng {row_idx}: Chỉ có {len(row)} cột")
                        continue

                    code = str(row[0] or "").strip()
                    name = str(row[1] or "").strip()
                    unit = str(row[2] or "Cái").strip()

                    try:
                        buy_price = float(str(row[3] or 0).replace(",", "").replace(" ", ""))
                    except:
                        buy_price = 0

                    try:
                        sell_price = float(str(row[4] or 0).replace(",", "").replace(" ", ""))
                    except:
                        sell_price = 0

                    if not code or not name:
                        errors.append(f"Dòng {row_idx}: Mã/Tên hàng trống")
                        error_count += 1
                        print(f"[SKIP] Dòng {row_idx}: code='{code}', name='{name}'")
                        continue

                    print(f"[ADD] Dòng {row_idx}: {code} | {name} | {unit} | {buy_price} | {sell_price}")

                    # Thêm sản phẩm
                    add_product(db_path, code, name, unit, None, buy_price, sell_price)
                    success_count += 1

                except Exception as e:
                    error_count += 1
                    err_msg = f"Dòng {row_idx}: {str(e)}"
                    errors.append(err_msg)
                    print(f"[ERROR] {err_msg}")

            print(f"[RESULT] Thành công: {success_count}, Lỗi: {error_count}")

            # Làm mới danh sách
            self.refresh(db_path)

            # Hiển thị kết quả
            msg = f"✅ Import hoàn thành!\n\n"
            msg += f"Thêm thành công: {success_count} sản phẩm\n"
            if error_count > 0:
                msg += f"Lỗi: {error_count} dòng\n\n"
                msg += "Chi tiết lỗi:\n"
                for err in errors[:5]:
                    msg += f"  • {err}\n"
                if len(errors) > 5:
                    msg += f"  ... và {len(errors) - 5} lỗi khác"

            QMessageBox.information(self, "Kết quả", msg)
            if success_count > 0:
                show_toast(self.window(), f"✓ Nạp {success_count} sản phẩm thành công!")

        except Exception as e:
            print(f"[FATAL] {e}")
            import traceback
            traceback.print_exc()
            QMessageBox.critical(self, "Lỗi", f"Lỗi import file:\n{e}")


    def refresh(self, db_path: str):
        """Load data from DB."""
        if not db_path or not os.path.exists(db_path):
            return

        # Refresh categories tab too
        self.category_tab.refresh()

        try:
            data = get_stock_summary(db_path)
            self.table.setRowCount(len(data))
            for i, row in enumerate(data):
                def _item(txt, align=Qt.AlignmentFlag.AlignLeft):
                    it = QTableWidgetItem(str(txt))
                    it.setTextAlignment(align | Qt.AlignmentFlag.AlignVCenter)
                    return it

                self.table.setItem(i, 0, _item(row.get("code") or ""))
                self.table.setItem(i, 1, _item(row.get("name") or ""))

                # Giá bán / Giá mua — căn phải
                sell = float(row.get("sale_price") or 0)
                buy  = float(row.get("purchase_price") or 0)
                self.table.setItem(i, 2, _item(f"{sell:,.0f} đ", Qt.AlignmentFlag.AlignRight))
                self.table.setItem(i, 3, _item(f"{buy:,.0f} đ",  Qt.AlignmentFlag.AlignRight))

                gtgt = float(row.get("gtgt_rate") or 0.0)
                tncn = float(row.get("tncn_rate") or 0.0)
                total_tax = gtgt + tncn
                self.table.setItem(i, 4, _item(f"{total_tax:g}%", Qt.AlignmentFlag.AlignCenter))
                self.table.setItem(i, 5, _item(row.get("unit") or "", Qt.AlignmentFlag.AlignCenter))

                tin  = float(row.get("total_in")  or 0)
                tout = float(row.get("total_out") or 0)
                bal  = float(row.get("balance")   or 0)

                self.table.setItem(i, 6, _item(f"{tin:,.0f}",  Qt.AlignmentFlag.AlignRight))
                self.table.setItem(i, 7, _item(f"{tout:,.0f}", Qt.AlignmentFlag.AlignRight))

                bal_item = _item(f"{bal:,.0f}", Qt.AlignmentFlag.AlignRight)
                if bal < 5:
                    bal_item.setForeground(QColor(COLORS["danger"]))
                self.table.setItem(i, 8, bal_item)
        except Exception as e:
            print(f"Error in inventory refresh: {e}")
