<!DOCTYPE html>
<html lang="vi">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>THÊM HÀNG HÓA</title>
    <link rel="shortcut icon" href="1.png" type="image/x-icon">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css">
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/toastify-js"></script>
    <style>
        /* Reset và cơ bản */
        #productsTable {
            border-collapse: collapse;
            width: 100%;
            margin-bottom: 1rem;
        }

        table,
        tr {
            overflow: visible !important;
        }


        /* Header styles */
        #productsTable th {
            background-color: #f8f9fa;
            border-bottom: 2px solid #dee2e6;
            border-right: 1px solid #dee2e6;
            padding: 12px 8px;
            font-weight: 600;
            text-align: left;
            position: sticky;
            top: 0;
            z-index: 10;
            white-space: normal;
            word-wrap: break-word;
            min-width: 120px;
            vertical-align: middle;
        }

        /* Cell styles */
        #productsTable td {
            border: 1px solid #E2E8F0;
            padding: 8px;
            white-space: normal;
            word-wrap: break-word;
            min-width: 120px;
            max-width: 300px;
            vertical-align: top;
            background-color: #fff;
        }

        /* Input và control styles */

        #productsTable select,
        #productsTable textarea {
            width: 100%;
            border: none;
            background: transparent;
            padding: 8px;
            min-height: 32px;
            height: auto;
            font-size: 14px;
            line-height: 1.4;
            resize: none;
        }

        #productsTable input {
            border: none;
            background: transparent;
            padding: 8px;
            min-height: 32px;
            height: auto;
            font-size: 14px;
            line-height: 1.4;
            resize: none;
        }

        #productsTable input:focus,
        #productsTable select:focus,
        #productsTable textarea:focus {
            outline: none;
            background-color: #f0f7ff;
            box-shadow: inset 0 0 0 2px #3B82F6;
        }

        /* Cột cụ thể */
        #productsTable td:nth-child(2) {
            /* Tên hàng */
            min-width: 200px;
        }

        #productsTable td:nth-child(4) {
            /* Mota */
            min-width: 250px;
        }

        #productsTable td:nth-child(9),
        #productsTable td:nth-child(10),
        #productsTable td:nth-child(11),
        #productsTable td:nth-child(12) {
            /* Cột giá */
            min-width: 100px;
            text-align: right;
        }

        /* Cell multiline */
        .cell-multiline {
            white-space: pre-wrap;
            line-height: 1.4;
            min-height: 32px;
        }

        .multi-select {
            position: relative;
            /* Ensure the dropdown is positioned relative to this container */
        }

        .multi-select-dropdown {
            position: absolute;
            top: 100%;
            /* Position below by default */
            left: 0;
            z-index: 1000;
            /* Ensure it is above other elements */
            max-height: 300px;
            /* Optional: Limit dropdown height */
            overflow-y: auto;
            background: white;
            border: 1px solid #e2e8f0;
            border-radius: 4px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }



        .multi-select-dropdown label {
            display: flex;
            align-items: center;
            padding: 4px;
            cursor: pointer;
            transition: background-color 0.2s;
        }

        .multi-select-dropdown label:hover {
            background-color: #f8fafc;
        }

        /* Hàng chẵn lẻ */
        #productsTable tbody tr:nth-child(even) {
            background-color: #f8fafc;
        }

        /* Hover effect */
        #productsTable tbody tr:hover {
            background-color: #f0f7ff;
        }

        /* Scrollbar tùy chỉnh */
        ::-webkit-scrollbar {
            width: 4px;
            height: 4px;
        }

        ::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 4px;
        }

        ::-webkit-scrollbar-thumb {
            background: #888;
            border-radius: 4px;
        }

        ::-webkit-scrollbar-thumb:hover {
            background: #666;
        }

        /* Responsive table */
        @media screen and (max-width: 1024px) {
            #productsTable {
                display: block;
                overflow-x: auto;
                white-space: nowrap;
            }
        }

        /* Upload zone */
        .drop-zone {
            min-height: 60px;
            display: flex;
            align-items: center;
            justify-content: center;
            border: 2px dashed #e2e8f0;
            border-radius: 4px;
            transition: all 0.3s;
        }

        .drop-zone:hover {
            border-color: #3B82F6;
            background-color: #f8fafc;
        }

        /* Image preview */
        .image-preview {
            max-width: 48px;
            max-height: 48px;
            object-fit: cover;
            border-radius: 4px;
        }

        /* Action buttons */
        .action-button {
            padding: 4px;
            border-radius: 4px;
            transition: all 0.2s;
        }

        .action-button:hover {
            background-color: #f0f7ff;
        }

        /* Number inputs */
        input[type="number"] {
            text-align: right;
        }

        input[type="number"]::-webkit-outer-spin-button,
        input[type="number"]::-webkit-inner-spin-button {
            -webkit-appearance: none;
            margin: 0;
        }
    </style>
</head>

<body class="bg-gray-50">
    <!-- Loading Overlay -->
    <div id="loadingOverlay" class="fixed inset-0 bg-black bg-opacity-50 hidden flex items-center justify-center z-50">
        <div class="bg-white p-6 rounded-lg shadow-xl">
            <div class="flex items-center space-x-3">
                <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
                <div id="loadingText" class="text-gray-700">Đang xử lý...</div>
            </div>
            <div id="progressContainer" class="mt-4 hidden">
                <div class="w-full bg-gray-200 rounded-full h-2.5">
                    <div id="progressBar" class="bg-blue-600 h-2.5 rounded-full transition-all duration-300"
                        style="width: 0%"></div>
                </div>
                <div id="progressText" class="text-sm text-gray-600 mt-1 text-center">0%</div>
            </div>
        </div>
    </div>

    <!-- Main Container -->
    <div class="mx-auto px-4 py-8">
        <div class="bg-white rounded-lg shadow-lg p-6">
            <!-- Header Section -->
            <div class="flex justify-between items-center mb-6">
                <img src="1.png" alt="" width="50">
                <h1 class="text-2xl font-bold text-gray-800">Thêm sản phẩm nhanh</h1>
                <div class="flex items-center space-x-4">

                    <button id="addNewRow" onclick="addNewRow()"
                        class="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors flex items-center gap-2">
                        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
                        </svg>
                        Thêm dòng
                    </button>
                    <button id="saveAll" onclick="saveAllProducts()"
                        class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors flex items-center gap-2">
                        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4" />
                        </svg>
                        Lưu tất cả
                    </button>
                </div>
            </div>

            <!-- Import Section -->
            <div class="mb-6 p-4 bg-gray-50 rounded-lg border border-gray-200">
                <h2 class="text-lg font-semibold mb-3">Import từ Excel</h2>
                <div class="flex items-center gap-4">
                    <div class="flex-1">
                        <label for="excelFile"
                            class="block w-full p-4 border-2 border-dashed border-gray-300 rounded-lg text-center cursor-pointer hover:border-blue-500 transition-colors">
                            <span class="text-gray-600">Kéo thả file Excel hoặc click để chọn file</span>
                            <input type="file" id="excelFile" accept=".xlsx, .xls, .csv" class="hidden"
                                onchange="handleFileSelect(this)" />
                        </label>
                    </div>
                    <button onclick="importExcel()"
                        class="px-6 py-4 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors flex items-center gap-2">
                        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
                        </svg>
                        Import
                    </button>
                </div>
            </div>

            <!-- Products Table -->
            <div class="overflow-x-auto border border-gray-200 rounded-lg">
                <table id="productsTable" class="min-w-full divide-y divide-gray-200">
                    <thead class="bg-gray-50">
                        <tr>

                            <th hidden
                                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                Mã SP</th>
                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                Tensp</th>
                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                Nhomsp</th>
                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                Mota hàng hóa</th>
                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                Hinhanh</th>
                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                ĐVT</th>
                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                Gianhap</th>
                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                Giaban</th>
                         
                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                Xóa</th>
                        </tr>
                    </thead>
                    <tbody class="bg-white divide-y divide-gray-200">
                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <!-- Batch Actions -->
    <div id="batchActions"
        class="hidden fixed bottom-8 left-1/2 transform -translate-x-1/2 bg-white px-6 py-4 rounded-lg shadow-xl flex items-center gap-4">
        <span class="text-gray-600" id="selectedCount">Đã chọn: 0</span>
        <button onclick="deleteBatchProducts()"
            class="px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 transition-colors flex items-center gap-2">
            <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                    d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
            </svg>
            Xóa đã chọn
        </button>
        <button onclick="copyBatchProducts()"
            class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors flex items-center gap-2">
            <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                    d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
            </svg>
            Nhân bản
        </button>
    </div>

    <!-- Floating Action Buttons -->
    <div id="floatingButtons" class="fixed bottom-6 right-6 flex flex-col gap-3">
        <button onclick="addNewRow()"
            class="bg-green-600 hover:bg-green-700 text-white rounded-full p-4 shadow-lg transition-all hover:scale-105">
            <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
            </svg>
        </button>
        <button onclick="saveAllProducts()"
            class="bg-blue-600 hover:bg-blue-700 text-white rounded-full p-4 shadow-lg transition-all hover:scale-105">
            <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                    d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4" />
            </svg>
        </button>
    </div>

    <script>
        // Constants
        const APP_ID = 'a3c21623-f7da-4dfd-bbe4-197bd67d7296';
        const ACCESS_KEY = 'V2-5WcPS-sJgmv-8IXNy-QnfZ7-8sfxW-8XiP6-bZe4T-IaHdV';
        const REGION = 'www';
        const API_URL = `https://${REGION}.appsheet.com/api/v2/apps/${APP_ID}/tables`;
        const IMGBB_API_KEY = '7267d539a8c541130ce4524afdc69ad3';

        // State Management
        const state = {
            lastProductId: 0,
            products: new Map(),
            categories: [],
         
            units: ['Cái', 'Bộ', 'Chiếc', 'Hộp', 'Cuốn', 'Mét', 'Kg', 'Gram', 'Lít', 'Chai', 'Gói', 'Túi', 'Thùng', 'Tấm', 'Bình'],
            batchMode: false
        };
       
        
     
        // Toast Utilities
        const toast = {
            success(message) {
                Toastify({
                    text: message,
                    duration: 3000,
                    gravity: "top",
                    position: "right",
                    style: { background: "#4CAF50" },
                }).showToast();
            },
            error(message) {
                Toastify({
                    text: message,
                    duration: 3000,
                    gravity: "top",
                    position: "right",
                    style: { background: "#f44336" },
                }).showToast();
            },
            warning(message) {
                Toastify({
                    text: message,
                    duration: 3000,
                    gravity: "top",
                    position: "right",
                    style: { background: "#ff9800" },
                }).showToast();
            },
            info(message) {
                Toastify({
                    text: message,
                    duration: 3000,
                    gravity: "top",
                    position: "right",
                    style: { background: "#2196F3" },
                }).showToast();
            }
        };
        // Hàm để lấy danh sách phân nhóm từ NHOMHH
        async function fetchCategories() {
            try {
                const response = await apiRequest('NHOMSP', 'Find', {

                }, {
                });

                if (response && Array.isArray(response)) {
                    // Lọc các giá trị unique từ cột phan_nhom
                    const categories = [...new Set(response.map(item => item['Nhomsp']).filter(Boolean))];
                    state.categories = categories;

                    // Cập nhật lại tất cả các select box phân loại hiện có
                    updateCategorySelectBoxes();
                }
            } catch (error) {
                console.error('Lỗi khi lấy danh sách phân nhóm:', error);
                toast.error('Không thể tải danh sách phân nhóm');
            }
        }
        async function initialize() {
            try {
                loadingUtils.show('Đang tải dữ liệu...', true);
                await Promise.all([
                    fetchCategories()
                ]);
                loadingUtils.hide();
                // Thêm hàng đầu tiên sau khi đã load xong categories
                addNewRow();
            } catch (error) {
                loadingUtils.hide();
                console.error('Lỗi khởi tạo:', error);
                toast.error('Có lỗi xảy ra khi khởi tạo ứng dụng');
            }
        }
        function updateCategorySelectBoxes() {
            const selects = document.querySelectorAll('select[onchange*="Nhomsp"]');
            selects.forEach(select => {
                const currentValue = select.value;
                select.innerHTML = `
            <option value="">Phân loại</option>
            ${state.categories.map(cat => `
                <option value="${cat}" ${currentValue === cat ? 'selected' : ''}>
                    ${cat}
                </option>
            `).join('')}
        `;
            });
        }
        // Loading Utilities
        const loadingUtils = {
            overlay: null,
            progressBar: null,
            progressText: null,
            progressContainer: null,
            loadingText: null,

            init() {
                this.overlay = document.getElementById('loadingOverlay');
                this.progressBar = document.getElementById('progressBar');
                this.progressText = document.getElementById('progressText');
                this.progressContainer = document.getElementById('progressContainer');
                this.loadingText = document.getElementById('loadingText');
            },

            show(message = 'Đang xử lý...', showProgress = false) {
                if (!this.overlay) this.init();
                this.loadingText.textContent = message;
                this.overlay.classList.remove('hidden');
                if (showProgress) {
                    this.progressContainer.classList.remove('hidden');
                    this.updateProgress(0);
                } else {
                    this.progressContainer.classList.add('hidden');
                }
            },

            hide() {
                if (!this.overlay) this.init();
                this.overlay.classList.add('hidden');
                this.progressContainer.classList.add('hidden');
            },

            updateProgress(percent) {
                if (!this.progressBar) this.init();
                this.progressBar.style.width = `${percent}%`;
                this.progressText.textContent = `${percent}%`;
            }
        };

        // DOM Utilities
        const dom = {
            getProductRow(element) {
                return element.closest('tr');
            },

            getProductId(row) {
                return row.dataset.productId;
            },

            createInput(value, type = 'text') {
                const input = document.createElement('input');
                input.type = type;
                input.value = value || '';
                input.className = 'w-full px-2 py-1 border border-gray-300 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent';
                return input;
            },

            createSelect(value, options = [], placeholder = '') {
                const select = document.createElement('select');
                select.className = 'w-full px-2 py-1 border border-gray-300 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent';
                select.innerHTML = `
            <option value="">${placeholder}</option>
            ${options.map(opt => `
                <option value="${opt}" ${value === opt ? 'selected' : ''}>${opt}</option>
            `).join('')}
        `;
                return select;
            },

            createCategorySelect(value) {
                return this.createSelect(value, state.categories, 'Chọn phân loại');
            },

            createUnitSelect(value) {
                return this.createSelect(value, state.units, 'Chọn Dvtinh');
            }
        };

        // Event Handlers
        const handlers = {
            async handleImageUpload(event, productId) {
                const file = event.target.files[0];
                if (!file) return;

                const row = document.querySelector(`tr[data-product-id="${productId}"]`);
                const imgPreview = row.querySelector('.image-preview');
                const dropZone = row.querySelector('.drop-zone');

                try {
                    const base64 = await this.fileToBase64(file);
                    imgPreview.src = base64;
                    imgPreview.classList.remove('hidden');
                    dropZone.classList.add('has-image');

                    const product = state.products.get(productId);
                    if (product) {
                        product.imageBase64 = base64;
                        product.image = '';
                        state.products.set(productId, product);
                    }
                } catch (error) {
                    console.error('Error handling image:', error);
                    toast.error('Lỗi khi xử lý ảnh. Vui lòng thử lại.');
                }
            },

            fileToBase64(file) {
                return new Promise((resolve, reject) => {
                    const reader = new FileReader();
                    reader.readAsDataURL(file);
                    reader.onload = () => resolve(reader.result);
                    reader.onerror = error => reject(error);
                });
            },

            navigateToNextCell(currentRow, currentIndex, direction) {
                const editableCells = Array.from(currentRow.cells).filter(cell => cell.onclick);
                const currentCellIndex = editableCells.indexOf(currentRow.cells[currentIndex]);

                let nextCell;
                if (direction > 0 && currentCellIndex === editableCells.length - 1) {
                    // Move to next row
                    const nextRow = currentRow.nextElementSibling;
                    if (nextRow) {
                        nextCell = Array.from(nextRow.cells).find(cell => cell.onclick);
                    }
                } else if (direction < 0 && currentCellIndex === 0) {
                    // Move to previous row
                    const prevRow = currentRow.previousElementSibling;
                    if (prevRow) {
                        const editablePrevCells = Array.from(prevRow.cells).filter(cell => cell.onclick);
                        nextCell = editablePrevCells[editablePrevCells.length - 1];
                    }
                } else {
                    nextCell = editableCells[currentCellIndex + direction];
                }

                if (nextCell) nextCell.click();
            },

            updateCellValue(element, productId, columnIndex) {
                const value = element.value;
                const cell = element.parentElement;
                const product = state.products.get(productId);

                if (!product) return;

                switch (columnIndex) {
                    case 1: product.name = value; break;
                    case 3: product.unit = value; break;
                    case 4: product.category = value; break;
                    case 5: product.specification = value; break;
                    case 6: product.note = value; break;
                }

                cell.textContent = value || (columnIndex === 4 ? 'Chọn phân loại' : '');
            }
        };

        // Drag and Drop Utilities
        function setupDragAndDrop(row) {
            const dropZone = row.querySelector('.drop-zone');

            ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
                dropZone.addEventListener(eventName, preventDefaults, false);
            });

            function preventDefaults(e) {
                e.preventDefault();
                e.stopPropagation();
            }

            ['dragenter', 'dragover'].forEach(eventName => {
                dropZone.addEventListener(eventName, () => {
                    dropZone.classList.add('bg-blue-50');
                });
            });

            ['dragleave', 'drop'].forEach(eventName => {
                dropZone.addEventListener(eventName, () => {
                    dropZone.classList.remove('bg-blue-50');
                });
            });

            dropZone.addEventListener('drop', (e) => {
                const file = e.dataTransfer.files[0];
                if (file && file.type.startsWith('image/')) {
                    const productId = dom.getProductId(row);
                    handlers.handleImageUpload({ target: { files: [file] } }, productId);
                }
            });
        }

        async function addNewRow() {
            const tbody = document.querySelector('#productsTable tbody');
            const productId = utils.createUniqueId();
            const productCode = utils.generateProductCode();

            const product = {
                id: productId,
                code: productCode,
                ['Tensp']: '',
                ['Nhomsp']: '',
                ['Mota']: '',
                ['Hinhanh']: '',
                ['Dvtinh']: '',
                ['Gianhap']: '0',
                ['Giaban']: '0'
            };
            state.products.set(productId, product);

            const row = document.createElement('tr');
            row.dataset.productId = productId;
            row.className = 'hover:bg-gray-50 border-b border-gray-200';

            row.innerHTML = `
        ${state.batchMode ? `
            <td class="border-r border-gray-200 p-0">
                <input type="checkbox" class="form-checkbox text-blue-600 rounded m-2"
                       onchange="updateBatchActionVisibility()">
            </td>
        ` : ''}
        <td hidden class="border-r border-gray-200 p-2 text-sm text-gray-500">${productCode}</td>
        <td class="border-r border-gray-200 p-0">
            <div class="h-full w-full">
                <input type="text" 
                       class="w-full h-full px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:bg-blue-50"
                       value=""
                       placeholder="Nhập tên sản phẩm"
                       onchange="handleInputChange(event, '${productId}', 'Tensp')">
            </div>
        </td>
    
        <td class="border-r border-gray-200 p-0">
            <select class="w-full h-full px-2 py-1 border-0 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:bg-blue-50"
                    onchange="handleInputChange(event, '${productId}', 'Nhomsp')">
                <option value="">Phân loại</option>
                ${state.categories.map(cat => `<option value="${cat}">${cat}</option>`).join('')}
            </select>
        </td>
        <td class="border-r border-gray-200 p-0">
            <textarea 
                class="w-full cell-multiline px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:bg-blue-50"
                rows="1"
                placeholder="Nhập Mota"
                onchange="handleInputChange(event, '${productId}', 'Mota')"
                oninput="this.style.height = 'auto'; this.style.height = this.scrollHeight + 'px'">${product['Mota'] || ''}</textarea>
        </td>
        <td class="border-r border-gray-200 p-1">
            <div class="drop-zone flex items-center gap-2 rounded border border-dashed border-gray-300 hover:border-blue-500 transition-colors">
                <img class="image-preview w-12 h-12 object-cover rounded hidden" src="" alt="Preview">
                <label class="cursor-pointer flex-1 text-center py-1">
                    <input type="file" 
                           accept="image/*" 
                           class="hidden" 
                           onchange="handlers.handleImageUpload(event, '${productId}')">
                    <span class="text-blue-600 hover:text-blue-700 text-sm">Chọn ảnh</span>
                </label>
            </div>
        </td>
        <td class="border-r border-gray-200 p-0">
            <select class="w-full h-full px-2 py-1 border-0 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:bg-blue-50"
                    onchange="handleInputChange(event, '${productId}', 'Dvtinh')">
                <option value="">Chọn đơn vị tính</option>
                ${state.units.map(unit => `<option value="${unit}">${unit}</option>`).join('')}
            </select>
        </td>
        <td class="border-r border-gray-200 p-0">
        <input type="number" 
                   class="w-full h-full px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:bg-blue-50"
                   value="0"
                   placeholder="Nhập hệ số quy dổi"
                   onchange="handleInputChange(event, '${productId}', 'Gianhap')">
        </td>
        <td class="border-r border-gray-200 p-0">
        <input type="number" 
            class="w-full h-full px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:bg-blue-50"
            value="0"
            placeholder="Nhập hệ số quy dổi"
            onchange="handleInputChange(event, '${productId}', 'Giaban')">
        </td>
          
       
        <td class="p-1 text-center">
            <div class="flex items-center justify-center gap-1">
                <button onclick="deleteProduct('${productId}')" 
                        class="text-gray-400 hover:text-red-600 transition-colors p-1"
                        title="Xóa sản phẩm">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
                              d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
                    </svg>
                </button>
                <button onclick="duplicateProduct('${productId}')" 
                        class="text-gray-400 hover:text-blue-600 transition-colors p-1"
                        title="Nhân bản sản phẩm">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
                              d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
                    </svg>
                </button>
            </div>
        </td>
    `;

            tbody.appendChild(row);

            // Thêm vào cuối hàm
            setupDragAndDrop(row);
            initAutoResize();
            // Auto focus vào ô tên sản phẩm
            const nameInput = row.querySelector('input[placeholder="Nhập tên sản phẩm"]');
            if (nameInput) nameInput.focus();
        }

        // Thêm hàm xử lý thay đổi input
        function handleInputChange(event, productId, field) {
            const value = event.target.value;
            const product = state.products.get(productId);
            if (product) {
                // Xử lý đặc biệt cho các trường số
                if (['Gianhap', 'Giaban'].includes(field)) {
                    product[field] = parseFloat(value) || 0;
                } else {
                    product[field] = value;
                }
                state.products.set(productId, product);
            }
        }
        // Thêm hàm xử lý supplier
        function toggleSupplierDropdown(productId) {
            const dropdown = document.getElementById(`supplier-dropdown-${productId}`);
            const inputField = document.querySelector(`input.supplier-input[data-product-id="${productId}"]`);

            // Toggle visibility
            dropdown.classList.toggle('hidden');

            if (!dropdown.classList.contains('hidden')) {
                const rect = inputField.getBoundingClientRect();
                const dropdownRect = dropdown.getBoundingClientRect();
                const spaceBelow = window.innerHeight - rect.bottom;

                if (spaceBelow < dropdownRect.height) {
                    // Not enough space below, position above
                    dropdown.style.top = 'auto';
                    dropdown.style.bottom = '100%';
                } else {
                    // Enough space, position below
                    dropdown.style.top = '100%';
                    dropdown.style.bottom = 'auto';
                }
            }
        }

        function handleSupplierChange(productId, supplierId) {
            const product = state.products.get(productId);
            if (!product) return;

            // Khởi tạo mảng nếu chưa có
            product.ncc_uu_tien = product.ncc_uu_tien || [];

            // Toggle supplier
            const index = product.ncc_uu_tien.indexOf(supplierId);
            if (index === -1) {
                product.ncc_uu_tien.push(supplierId);
            } else {
                product.ncc_uu_tien.splice(index, 1);
            }

            // Cập nhật display
            updateSupplierDisplay(productId);
        }
     
        async function saveAllProducts() {
            try {
                loadingUtils.show('Đang kiểm tra dữ liệu...', true);
                const productsArray = Array.from(state.products.values());

                // Kiểm tra dữ liệu bắt buộc
                const invalidProducts = productsArray.filter(p => {
                    const missingFields = [];
                    if (!p['Tensp']?.trim()) missingFields.push('Tensp');
                    if (!p['Nhomsp']?.trim()) missingFields.push('Nhomsp');
                    if (!p['Dvtinh']?.trim()) missingFields.push('Dvtinh');
                    p.missingFields = missingFields;
                    return missingFields.length > 0;
                });

                if (invalidProducts.length > 0) {
                    const errorMessages = invalidProducts.map(p =>
                        `Sản phẩm "${p['Tensp'] || 'Chưa có tên'}" thiếu: ${p.missingFields.join(', ')}`
                    );
                    toast.warning(errorMessages.join('\n'));
                    loadingUtils.hide();
                    return;
                }

                // Xử lý upload ảnh
                const productsWithNewImages = productsArray.filter(p => p.imageBase64 && !p.image);
                if (productsWithNewImages.length > 0) {
                    loadingUtils.show(`Đang xử lý ${productsWithNewImages.length} ảnh...`, true);

                    // Upload ảnh theo batch để tránh quá tải
                    const BATCH_SIZE = 3;
                    for (let i = 0; i < productsWithNewImages.length; i += BATCH_SIZE) {
                        const batch = productsWithNewImages.slice(i, i + BATCH_SIZE);
                        await Promise.all(batch.map(async (product, index) => {
                            try {
                                const url = await uploadToCloudinary(product.imageBase64);
                                product.image = url;
                                delete product.imageBase64;

                                const progress = Math.round(((i + index + 1) / productsWithNewImages.length) * 60);
                                loadingUtils.updateProgress(progress);
                            } catch (error) {
                                console.error(`Lỗi upload ảnh cho sản phẩm ${product['Tensp']}:`, error);
                                product.image = 'https://i.ibb.co/cYHCSgp/image.png';
                                toast.warning(`Không thể tải ảnh cho sản phẩm "${product['Tensp']}"`);
                            }
                        }));

                        // Đợi một chút giữa các batch
                        if (i + BATCH_SIZE < productsWithNewImages.length) {
                            await new Promise(resolve => setTimeout(resolve, 500));
                        }
                    }
                }

                // Format dữ liệu
                loadingUtils.show('Đang chuẩn bị dữ liệu...', true);
                loadingUtils.updateProgress(80);

                const formattedProducts = productsArray.map(product => ({
                    ['Tensp']: product['Tensp'].trim(),
                    ['Nhomsp']: product['Nhomsp'].trim(),
                    ['Mota']: (product['Mota'] || '').trim(),
                    ['Hinhanh']: product.image || 'https://i.ibb.co/cYHCSgp/image.png',
                    ['Dvtinh']: product['Dvtinh'].trim(),
                    ['Gianhap']: parseFloat(product['Gianhap']) || 0,
                    ['Giaban']: parseFloat(product['Giaban']) || 0
                 
                }));
                // Lưu dữ liệu
                loadingUtils.show('Đang lưu dữ liệu...', true);
                const SAVE_BATCH_SIZE = 50; // Số lượng sản phẩm tối đa mỗi lần lưu

                for (let i = 0; i < formattedProducts.length; i += SAVE_BATCH_SIZE) {
                    const batch = formattedProducts.slice(i, i + SAVE_BATCH_SIZE);
                    await apiRequest('DMHH', 'Add', { Rows: batch });

                    const progress = 80 + Math.round((i + batch.length) / formattedProducts.length * 20);
                    loadingUtils.updateProgress(progress);
                }

                loadingUtils.updateProgress(100);

                // Hoàn thành
                setTimeout(() => {
                    loadingUtils.hide();
                    toast.success(`Đã lưu thành công ${formattedProducts.length} sản phẩm!`);
                    resetAfterSave();
                }, 500);

            } catch (error) {
                loadingUtils.hide();
                console.error('Lỗi khi lưu sản phẩm:', error);
                toast.error('Có lỗi xảy ra khi lưu dữ liệu: ' + (error.message || 'Lỗi không xác định'));
            }
        }
        const uploadToCloudinary = async (base64Image) => {
            const CLOUD_NAME = 'duv9pccwi';
            const UPLOAD_PRESET = 'poalupload';
            const MAX_RETRIES = 3;
            const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
            const MAX_DIMENSION = 1920;

            // Hàm nén ảnh
            const compressImage = async (base64) => {
                return new Promise((resolve) => {
                    const img = new Image();
                    img.onload = () => {
                        const canvas = document.createElement('canvas');
                        let width = img.width;
                        let height = img.height;

                        // Scale down nếu ảnh quá lớn
                        if (width > MAX_DIMENSION || height > MAX_DIMENSION) {
                            if (width > height) {
                                height *= MAX_DIMENSION / width;
                                width = MAX_DIMENSION;
                            } else {
                                width *= MAX_DIMENSION / height;
                                height = MAX_DIMENSION;
                            }
                        }

                        canvas.width = width;
                        canvas.height = height;
                        const ctx = canvas.getContext('2d');
                        ctx.drawImage(img, 0, 0, width, height);
                        resolve(canvas.toDataURL('image/jpeg', 0.8));
                    };
                    img.src = base64;
                });
            };

            let attempt = 0;
            while (attempt < MAX_RETRIES) {
                try {
                    // Nén ảnh trước khi upload
                    const compressedImage = await compressImage(base64Image);

                    // Xử lý base64 string
                    let base64Data = compressedImage;
                    if (base64Data.includes('base64,')) {
                        base64Data = base64Data.split('base64,')[1];
                    }

                    // Kiểm tra kích thước
                    const sizeInBytes = Math.ceil((base64Data.length * 3) / 4);
                    if (sizeInBytes > MAX_FILE_SIZE) {
                        throw new Error('Ảnh quá lớn (giới hạn 10MB)');
                    }

                    // Tạo form data
                    const formData = new FormData();
                    formData.append('file', `data:image/jpeg;base64,${base64Data}`);
                    formData.append('upload_preset', UPLOAD_PRESET);

                    // Gọi API Cloudinary
                    const response = await axios({
                        method: 'post',
                        url: `https://api.cloudinary.com/v1_1/${CLOUD_NAME}/image/upload`,
                        data: formData,
                        headers: { 'Content-Type': 'multipart/form-data' },
                        timeout: 15000 // 15s timeout
                    });

                    if (response.data?.secure_url) {
                        console.log('Upload success:', response.data.secure_url);
                        return response.data.secure_url;
                    }
                    throw new Error('Invalid response from Cloudinary');

                } catch (error) {
                    attempt++;
                    console.error(`Upload attempt ${attempt} failed:`, error);
                    await new Promise(resolve => setTimeout(resolve, 1000 * attempt));

                    if (attempt === MAX_RETRIES) {
                        console.error('All upload attempts failed');
                        return 'https://i.ibb.co/cYHCSgp/image.png'; // Default image
                    }
                }
            }
        };

        const apiRequest = async (tableName, action, data) => {
            try {
                const response = await fetch(`${API_URL}/${tableName}/Action`, {
                    method: 'POST',
                    headers: {
                        'ApplicationAccessKey': ACCESS_KEY,
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        Action: action,
                        ...data
                    })
                });

                if (!response.ok) {
                    const errorText = await response.text();
                    throw new Error(`API error (${response.status}): ${errorText}`);
                }

                const result = await response.json();
                return result;
            } catch (error) {
                console.error('API request failed:', error);
                throw error;
            }
        };
        async function importExcel() {
            const input = document.getElementById('excelFile');
            const file = input.files[0];

            if (!file) {
                toast.warning('Vui lòng chọn file Excel');
                return;
            }

            try {
                loadingUtils.show('Đang đọc file Excel...', true);
                loadingUtils.updateProgress(30);

                const data = await readExcelFile(file);
                if (data.length === 0) {
                    toast.warning('File Excel không có dữ liệu');
                    loadingUtils.hide();
                    return;
                }

                let importCount = 0;
                data.forEach((row, index) => {
                    if (row['TÊN HÀNG'] || row['MÃ HÀNG']) {
                        const productId = utils.createUniqueId();
                        const product = {
                            id: productId,
                            code: row['MÃ HÀNG'] || utils.generateProductCode(),
                            ['Tensp']: row['Tensp'] || '',
                            ['Nhomsp']: row['Nhomsp'] || '',
                            ['Mota']: row['Mota'] || '',
                            ['Hinhanh']: '',
                            ['Dvtinh']: row['Dvtinh'] || '',
                            ['Gianhap']: parseFloat(row['Gianhap']) || 0,
                            ['Giaban']: parseFloat(row['Giaban']) || 0
                        };
                        state.products.set(productId, product);
                        addExistingProduct(product);
                        importCount++;
                    }
                    const progress = Math.min(30 + Math.round((index + 1) / data.length * 70), 100);
                    loadingUtils.updateProgress(progress);
                });

                input.value = '';
                setTimeout(() => {
                    loadingUtils.hide();
                    toast.success(`Đã import ${importCount} sản phẩm`);
                }, 500);

            } catch (error) {
                loadingUtils.hide();
                console.error('Error importing Excel:', error);
                toast.error('Có lỗi xảy ra khi import file Excel');
            }
        }
        // Reset after save function
        function resetAfterSave() {
            // Clear the table
            const tbody = document.querySelector('#productsTable tbody');
            tbody.innerHTML = '';

            state.products.clear();
            state.lastProductId = 0;
            addNewRow();
        }

        // Duplicate product function
        function duplicateProduct(productId) {
            const originalProduct = state.products.get(productId);
            if (!originalProduct) return;

            const newProduct = {
                ...originalProduct,
                id: utils.createUniqueId(),
                code: utils.generateProductCode(),
                // Sao chép cả Hinhanh nếu có
                ['Hinhanh']: originalProduct['Hinhanh'],
                imageBase64: originalProduct.imageBase64
            };

            // Add to state
            state.products.set(newProduct.id, newProduct);

            addExistingProduct(newProduct);
            toast.success('Đã nhân bản sản phẩm thành công');
        }

        function addExistingProduct(product) {
            const tbody = document.querySelector('#productsTable tbody');
            const row = document.createElement('tr');
            row.dataset.productId = product.id;
            row.className = 'hover:bg-gray-50 border-b border-gray-200';

            row.innerHTML = `
        ${state.batchMode ? `
            <td class="border-r border-gray-200 p-0">
                <input type="checkbox" class="form-checkbox h-4 w-4 text-blue-600 rounded m-2"
                       onchange="updateBatchActionVisibility()">
            </td>
        ` : ''}
        <td hidden class="border-r border-gray-200 p-2 text-sm text-gray-500">${product.code}</td>
        <td class="border-r border-gray-200 p-0">
            <input type="text" 
                   class="w-full h-full px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:bg-blue-50"
                   value="${product['Tensp'] || ''}"
                   placeholder="Nhập tên sản phẩm"
                   onchange="handleInputChange(event, '${product.id}', 'Tensp')">
        </td>
        <td class="border-r border-gray-200 p-0">
            <select class="w-full h-full px-2 py-1 border-0 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:bg-blue-50"
                    onchange="handleInputChange(event, '${product.id}', 'Nhomsp')">
                <option value="">Phân loại</option>
                ${state.categories.map(cat => `
                    <option value="${cat}" ${product['Nhomsp'] === cat ? 'selected' : ''}>
                        ${cat}
                    </option>
                `).join('')}
            </select>
        </td>
        <td class="border-r border-gray-200 p-0">
    <textarea 
        class="w-full cell-multiline px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:bg-blue-50"
        rows="1"
        placeholder="Nhập Mota"
        onchange="handleInputChange(event, '${product.id}', 'Mota')"
        oninput="this.style.height = 'auto'; this.style.height = this.scrollHeight + 'px'">${product['Mota'] || ''}</textarea>
</td>
        <td class="border-r border-gray-200 p-1">
            <div class="drop-zone flex items-center gap-2 rounded border border-dashed border-gray-300 hover:border-blue-500 transition-colors">
                <img class="image-preview w-12 h-12 object-cover rounded ${product['Hinhanh'] ? '' : 'hidden'}" 
                     src="${product['Hinhanh'] || ''}" alt="Preview">
                <label class="cursor-pointer flex-1 text-center py-1">
                    <input type="file" 
                           accept="image/*" 
                           class="hidden" 
                           onchange="handlers.handleImageUpload(event, '${product.id}')">
                    <span class="text-blue-600 hover:text-blue-700 text-sm">Chọn ảnh</span>
                </label>
            </div>
        </td>
        <td class="border-r border-gray-200 p-0">
            <select class="w-full h-full px-2 py-1 border-0 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:bg-blue-50"
                    onchange="handleInputChange(event, '${product.id}', 'Dvtinh')">
                <option value="">Chọn đơn vị tính</option>
                ${state.units.map(unit => `
                    <option value="${unit}" ${product['Dvtinh'] === unit ? 'selected' : ''}>
                        ${unit}
                    </option>
                `).join('')}
            </select>
        </td>
        <td class="border-r border-gray-200 p-0">
            <input type="number" 
                   class="w-full h-full px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:bg-blue-50"
                   value="${product['Gianhap'] || '0'}"
                   placeholder="Nhập giá mua"
                   onchange="handleInputChange(event, '${product.id}', 'Gianhap')">
        </td>
        <td class="border-r border-gray-200 p-0">
            <input type="number" 
                   class="w-full h-full px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:bg-blue-50"
                   value="${product['Giaban'] || '0'}"
                   placeholder="Nhập Giaban"
                   onchange="handleInputChange(event, '${product.id}', 'Giaban')">
        </td>
       
      
        <td class="p-1 text-center">
            <div class="flex items-center justify-center gap-1">
                <button onclick="deleteProduct('${product.id}')" 
                        class="text-gray-400 hover:text-red-600 transition-colors p-1"
                        title="Xóa sản phẩm">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
                              d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
                    </svg>
                </button>
                <button onclick="duplicateProduct('${product.id}')" 
                        class="text-gray-400 hover:text-blue-600 transition-colors p-1"
                        title="Nhân bản sản phẩm">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
                              d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
                    </svg>
                </button>
            </div>
        </td>
    `;

            tbody.appendChild(row);
            setupDragAndDrop(row);
            initAutoResize();
        }

        // Function to handle file select for Excel import
        function handleFileSelect(input) {
            const file = input.files[0];
            if (file) {
                const fileName = file.name;
                const fileExt = fileName.split('.').pop().toLowerCase();

                if (!['xlsx', 'xls', 'csv'].includes(fileExt)) {
                    toast.error('Vui lòng chọn file Excel (.xlsx, .xls) hoặc CSV');
                    input.value = '';
                    return;
                }

                const fileLabel = input.parentElement.querySelector('span');
                fileLabel.textContent = fileName;
            }
        }
        function initAutoResize() {
            document.querySelectorAll('textarea').forEach(textarea => {
                textarea.addEventListener('input', function () {
                    this.style.height = 'auto';
                    this.style.height = this.scrollHeight + 'px';
                });
            });
        }
        // Function to read Excel file
        function readExcelFile(file) {
            return new Promise((resolve, reject) => {
                const reader = new FileReader();

                reader.onload = (e) => {
                    try {
                        const data = new Uint8Array(e.target.result);
                        const workbook = XLSX.read(data, { type: 'array' });
                        const firstSheet = workbook.Sheets[workbook.SheetNames[0]];
                        const jsonData = XLSX.utils.sheet_to_json(firstSheet);
                        resolve(jsonData);
                    } catch (error) {
                        reject(error);
                    }
                };

                reader.onerror = (error) => reject(error);
                reader.readAsArrayBuffer(file);
            });
        }

        // Delete product function
        function deleteProduct(productId) {
            if (!confirm('Bạn có chắc chắn muốn xóa sản phẩm này?')) return;

            const row = document.querySelector(`tr[data-product-id="${productId}"]`);
            if (row) {
                row.remove();
                state.products.delete(productId);
                toast.success('Đã xóa sản phẩm');

                // Update batch actions visibility if in batch mode
                if (state.batchMode) {
                    updateBatchActionVisibility();
                }
            }
        }


        function toggleAllProducts(checkbox) {
            const table = document.getElementById('productsTable');
            table.querySelectorAll('tbody tr input[type="checkbox"]')
                .forEach(cb => cb.checked = checkbox.checked);
            updateBatchActionVisibility();
        }

        function updateBatchActionVisibility() {
            const batchActions = document.getElementById('batchActions');
            const checkedBoxes = document.querySelectorAll('tbody tr input[type="checkbox"]:checked');
            const selectedCount = document.getElementById('selectedCount');

            selectedCount.textContent = `Đã chọn: ${checkedBoxes.length}`;
            batchActions.classList.toggle('hidden', checkedBoxes.length === 0);
        }

        function getSelectedProducts() {
            const selectedRows = document.querySelectorAll('tbody tr input[type="checkbox"]:checked');
            return Array.from(selectedRows).map(checkbox => dom.getProductId(dom.getProductRow(checkbox)));
        }

        function deleteBatchProducts() {
            const selectedIds = getSelectedProducts();
            if (!selectedIds.length) return;

            if (confirm(`Bạn có chắc chắn muốn xóa ${selectedIds.length} sản phẩm đã chọn?`)) {
                selectedIds.forEach(id => {
                    const row = document.querySelector(`tr[data-product-id="${id}"]`);
                    if (row) {
                        row.remove();
                        state.products.delete(id);
                    }
                });
                toast.success(`Đã xóa ${selectedIds.length} sản phẩm`);
                updateBatchActionVisibility();
            }
        }

        function copyBatchProducts() {
            const selectedIds = getSelectedProducts();
            if (!selectedIds.length) return;

            selectedIds.forEach(id => {
                const originalProduct = state.products.get(id);
                if (originalProduct) {
                    const newProduct = { ...originalProduct };
                    newProduct.id = utils.createUniqueId();
                    newProduct.code = utils.generateProductCode();
                    state.products.set(newProduct.id, newProduct);
                    addExistingProduct(newProduct);
                }
            });

            toast.success(`Đã nhân bản ${selectedIds.length} sản phẩm`);
        }

        // Utility Functions
        const utils = {
            generateProductCode() {
                state.lastProductId++;
                return `SP${String(state.lastProductId).padStart(5, '0')}`;
            },

            createUniqueId() {
                return Date.now().toString(36) + Math.random().toString(36).substr(2);
            },

            validateProduct(product) {
                return (
                    product['Tensp']?.trim() &&
                    product['Nhomsp']?.trim() &&
                    product['Dvtinh']?.trim()
                );
            }
        };
        document.addEventListener('DOMContentLoaded', initialize);

        // Event Listeners
    </script>

</body>

</html>