' ============================================
' frmImport - استيراد البيانات
' ============================================

Option Explicit

Private importedData As Collection
Private filePath As String

Private Sub UserForm_Initialize()
    ClearForm
    ' تعطيل زر الاستيراد حتى يتم اختيار خيار
    cmdImport.Enabled = False
    ' تعطيل زر التحديث في البداية
    cmdImportupdate.Enabled = False
End Sub

' عند تغيير خيار تحديث المنتجات الموجودة
Private Sub chkUpdateExisting_Click()
    CheckImportButtonState
    ' تفعيل/تعطيل زر التحديث بناءً على حالة chkUpdateExisting
    cmdImportupdate.Enabled = (chkUpdateExisting.Value = -1)
End Sub

' عند تغيير خيار تخطي المكررات
Private Sub chkSkipDuplicates_Click()
    CheckImportButtonState
End Sub

' عند تغيير خيار إضافة منتجات جديدة
Private Sub optAddNew_Click()
    CheckImportButtonState
End Sub

' التحقق من حالة زر الاستيراد
Private Sub CheckImportButtonState()
    ' تفعيل زر الاستيراد إذا تم اختيار أحد الخيارات على الأقل
    If chkUpdateExisting.Value = True Or chkSkipDuplicates.Value = True Or optAddNew.Value = True Then
        cmdImport.Enabled = True
    Else
        cmdImport.Enabled = False
    End If
End Sub

' استعراض ملف
Private Sub cmdBrowse_Click()
    Dim fd As Object
    Dim selectedFile As Variant
    
    Set fd = Application.FileDialog(msoFileDialogFilePicker)
    With fd
        .title = "اختر ملف Excel للاستيراد"
        .AllowMultiSelect = False
        .Filters.Clear
        .Filters.Add "ملفات Excel", "*.xlsx;*.xls;*.xlsm"
        .Filters.Add "ملفات CSV", "*.csv"
        .InitialFileName = ThisWorkbook.Path
        
        If .Show = -1 Then
            selectedFile = .SelectedItems(1)
            txtFilePath.Value = selectedFile
            filePath = selectedFile
        End If
    End With
    
    Set fd = Nothing
End Sub

' تحميل معاينة
Private Sub cmdLoadPreview_Click()
    If Trim(txtFilePath.Value) = "" Then
        MsgBox "يرجى اختيار ملف أولاً", vbExclamation
        Exit Sub
    End If
    
    ' استخدام المسار من الحقل (يدوياً أو من الاستعراض)
    filePath = Trim(txtFilePath.Value)
    
    If Dir(filePath) = "" Then
        MsgBox "الملف غير موجود: " & vbCrLf & filePath, vbExclamation
        Exit Sub
    End If
    
    LoadPreviewData
End Sub

' تحميل معاينة البيانات
' يُفتح الملف في نفس تطبيق Excel الحالي (بدون CreateObject) لتجنب رسالة "التطبيق مشغول"
' وتُقرأ الخلايا دفعة واحدة، ثم يُغلق الملف قبل تعبئة ListView لتقليل عمليات OLE و"waiting for another application"
Private Sub LoadPreviewData()
    Dim xlWB As Object
    Dim xlWS As Object
    Dim i As Long
    Dim lastRow As Long
    Dim headerRow As Long
    Dim dataArr As Variant
    Dim ub As Long
    Dim w As Object
    Dim errDesc As String, errNum As Long
    Dim savedCalc As Long
    
    On Error GoTo ErrorHandler
    
    ' عدم فتح ملف النظام (الملف الحالي) نفسه
    If StrComp(Replace(Trim(filePath), "/", "\"), Replace(ThisWorkbook.FullName, "/", "\"), vbTextCompare) = 0 Then
        MsgBox "لا يمكن استيراد ملف النظام (الملف الحالي) نفسه. اختر ملفاً آخر للاستيراد.", vbExclamation
        Exit Sub
    End If
    
    ' إذا كان الملف مفتوحاً بالفعل في هذه الجلسة، نطلب إغلاقه أولاً
    For Each w In Application.Workbooks
        If StrComp(Replace(w.FullName, "/", "\"), Replace(Trim(filePath), "/", "\"), vbTextCompare) = 0 Then
            MsgBox "الملف المحدد مفتوح بالفعل في Excel. أغلقه أولاً ثم أعد تحميل المعاينة.", vbExclamation
            Exit Sub
        End If
    Next w
    
    ' مسح البيانات السابقة أولاً
    Set importedData = New Collection
    ListBox1.Clear
    
    ' تخفيف الحساب والتحديث أثناء الفتح والقراءة (لتقليل "waiting for another application to complete an OLE action")
    savedCalc = Application.Calculation
    Application.Calculation = -4135   ' xlCalculationManual
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    
    ' فتح الملف في نفس تطبيق Excel
    Set xlWB = Application.Workbooks.Open(filePath, UpdateLinks:=0, ReadOnly:=True, IgnoreReadOnlyRecommended:=True)
    Set xlWS = xlWB.Worksheets(1)
    
    ' إعداد ListBox1 لعرض 8 أعمدة
    ListBox1.ColumnCount = 8
    ListBox1.ColumnWidths = "70;120;50;70;70;50;120;80"
    ListBox1.AddItem "رمز الصنف"
    Dim r As Long
    r = ListBox1.ListCount - 1
    ListBox1.List(r, 1) = "اسم الصنف"
    ListBox1.List(r, 2) = "الوحدة"
    ListBox1.List(r, 3) = "سعر الشراء"
    ListBox1.List(r, 4) = "سعر البيع"
    ListBox1.List(r, 5) = "الكمية"
    ListBox1.List(r, 6) = "ملاحظات"
    ListBox1.List(r, 7) = "الحالة"
    
    ' قراءة بالجملة ثم إغلاق الملف فوراً (قبل تعبئة ListView) لتقليل OLE والانتظار
    lastRow = xlWS.Cells(xlWS.Rows.count, 1).End(-4162).Row
    If lastRow < 1 Then lastRow = 1
    dataArr = xlWS.Range("A1:G" & lastRow).Value
    
    headerRow = 1
    ub = IIf(lastRow < 10, lastRow, 10)
    For i = 1 To ub
        If InStr(1, SafeCellStr(dataArr(i, 1)), "رمز") > 0 Or InStr(1, SafeCellStr(dataArr(i, 1)), "كود") > 0 Then
            headerRow = i
            Exit For
        End If
    Next i
    
    ' إغلاق الملف فوراً بعد قراءة البيانات (قبل الحلقة الثقيلة) لتقليل "OLE action" و"waiting for another application"
    xlWB.Close SaveChanges:=False
    Set xlWB = Nothing
    Application.DisplayAlerts = True
    
    ' تعبئة ListBox1 من الذاكرة (الملف مغلق): إخفاء مؤقت + DoEvents كل 150 صف لتفادي تجميد OLE
    ListBox1.Visible = False
    For i = headerRow + 1 To lastRow
        If Trim(SafeCellStr(dataArr(i, 1))) <> "" Then
            Dim rowData(1 To 8) As Variant
            rowData(1) = SafeCellStr(dataArr(i, 1))
            rowData(2) = SafeCellStr(dataArr(i, 2))
            rowData(3) = SafeCellStr(dataArr(i, 3))
            rowData(4) = SafeCellNum(dataArr(i, 4))
            rowData(5) = SafeCellNum(dataArr(i, 5))
            rowData(6) = SafeCellNum(dataArr(i, 6))
            rowData(7) = SafeCellStr(dataArr(i, 7))
            
            Dim validationResult As String
            validationResult = ValidateProductData(rowData)
            rowData(8) = validationResult
            
            importedData.Add rowData
            
            ListBox1.AddItem rowData(1)
            r = ListBox1.ListCount - 1
            ListBox1.List(r, 1) = rowData(2)
            ListBox1.List(r, 2) = rowData(3)
            ListBox1.List(r, 3) = Format(rowData(4), "#,##0.00")
            ListBox1.List(r, 4) = Format(rowData(5), "#,##0.00")
            ListBox1.List(r, 5) = Format(rowData(6), "#,##0.00")
            ListBox1.List(r, 6) = rowData(7)
            ListBox1.List(r, 7) = rowData(8)
        End If
        If (i - headerRow) Mod 150 = 0 Then DoEvents
    Next i
    ListBox1.Visible = True
    
    Application.ScreenUpdating = True
    Application.Calculation = savedCalc
    
    lblStatus.Caption = "تم تحميل " & importedData.count & " منتج للمعاينة"
    Exit Sub
    
ErrorHandler:
    errNum = Err.Number
    errDesc = Err.Description
    On Error Resume Next
    If Not xlWB Is Nothing Then xlWB.Close SaveChanges:=False
    Application.DisplayAlerts = True
    Application.ScreenUpdating = True
    Application.Calculation = -4105   ' xlCalculationAutomatic
    ListBox1.Visible = True
    On Error GoTo 0
    MsgBox "خطأ في قراءة الملف: " & errDesc & vbCrLf & vbCrLf & _
           "(رمز الخطأ: " & errNum & ")" & vbCrLf & _
           "تأكد من: إغلاق الملف إن كان مفتوحاً، وصحة المسار، وأن الملف excel/csv سليم.", vbCritical
End Sub

' قراءة آمنة لخلية كنص (تفادي Null أو قيم خطأ #N/A وغيرها)
Private Function SafeCellStr(v As Variant) As String
    On Error Resume Next
    If IsNull(v) Or IsEmpty(v) Then SafeCellStr = "": Exit Function
    If IsError(v) Then SafeCellStr = "": Exit Function
    SafeCellStr = CStr(v)
End Function

' قراءة آمنة لخلية كرقم
Private Function SafeCellNum(v As Variant) As Double
    On Error Resume Next
    SafeCellNum = 0
    If IsNull(v) Or IsError(v) Then Exit Function
    If IsNumeric(v) Then SafeCellNum = CDbl(v)
End Function

' التحقق من صحة بيانات المنتج
Private Function ValidateProductData(rowData As Variant) As String
    If Trim(rowData(1)) = "" Then
        ValidateProductData = "رمز الصنف فارغ"
        Exit Function
    End If
    
    If Trim(rowData(2)) = "" Then
        ValidateProductData = "اسم الصنف فارغ"
        Exit Function
    End If
    
    If Trim(rowData(3)) = "" Then
        ValidateProductData = "الوحدة فارغة"
        Exit Function
    End If
    
    If rowData(4) <= 0 Then
        ValidateProductData = "سعر الشراء غير صحيح"
        Exit Function
    End If
    
    ' سعر البيع: اختياري عند الاستيراد، يمكن إدخاله لاحقاً عند عملية البيع
    ' (لا نرفض الصف إذا كان سعر البيع 0 أو فارغاً)
    
    ' التحقق من الكمية (اختياري - إذا كانت 0 فلا مشكلة)
    If rowData(6) < 0 Then
        ValidateProductData = "الكمية غير صحيحة"
        Exit Function
    End If
    
    ' التحقق من التكرار - استخدام CleanProductCode لضمان المقارنة الصحيحة
    ' رمز الصنف هو المعرف الفريد
    If ProductExistsInTable(CStr(rowData(1))) Then
        If chkUpdateExisting.Value Then
            ValidateProductData = "موجود - سيتم تحديثه"
        ElseIf chkSkipDuplicates.Value Then
            ValidateProductData = "مكرر - سيتم تخطيه"
        Else
            ValidateProductData = "مكرر"
        End If
        Exit Function
    End If
    
    ValidateProductData = "صحيح"
End Function

' استيراد البيانات
Private Sub cmdImport_Click()
    If importedData Is Nothing Or importedData.count = 0 Then
        MsgBox "لا توجد بيانات للاستيراد. يرجى تحميل معاينة أولاً", vbExclamation
        Exit Sub
    End If
    
    ' التحقق من اختيار أحد الخيارات (إلزامي)
    ' في VBA: CheckBox.Value = -1 (True) أو 0 (False)
    If chkUpdateExisting.Value <> -1 And chkSkipDuplicates.Value <> -1 And optAddNew.Value = False Then
        MsgBox "يرجى اختيار أحد خيارات الاستيراد:" & vbCrLf & vbCrLf & _
               "• تحديث المنتجات الموجودة" & vbCrLf & _
               "• تخطي المكررات" & vbCrLf & _
               "• إضافة منتجات جديدة فقط", vbExclamation, "خيارات الاستيراد"
        Exit Sub
    End If
    
    Dim response As VbMsgBoxResult
    response = MsgBox("هل أنت متأكد من استيراد " & importedData.count & " منتج؟", vbYesNo + vbQuestion, "تأكيد الاستيراد")
    If response = vbNo Then Exit Sub
    
    ImportProducts
End Sub

' استيراد المنتجات - إعادة كتابة جذرية
Private Sub ImportProducts()
    Dim i As Long
    Dim addedCount As Long
    Dim updatedCount As Long
    Dim skippedCount As Long
    Dim errorCount As Long
    Dim itemData As Variant
    Dim tbl As ListObject
    Dim qty As Double
    Dim productCode As String
    Dim purchasePrice As Double
    Dim processedCodes As Object ' Dictionary لتتبع المنتجات المعالجة في نفس الجلسة
    Dim productExistsInDB As Boolean
    Dim productRowIndex As Long
    Dim newRow As ListRow
    
    ' الحصول على جدول المنتجات
    Set tbl = GetTableByName("tlbproduct")
    If tbl Is Nothing Then
        MsgBox "خطأ: لا يمكن العثور على جدول المنتجات", vbCritical
        Exit Sub
    End If
    
    ' إنشاء Dictionary لتتبع المنتجات المعالجة (لمنع التكرار في نفس ملف الاستيراد)
    Set processedCodes = CreateObject("Scripting.Dictionary")
    
    ' تهيئة العدادات
    addedCount = 0
    updatedCount = 0
    skippedCount = 0
    errorCount = 0
    
    ' قراءة حالة الخيارات مرة واحدة فقط - بشكل صحيح
    Dim shouldUpdate As Boolean
    Dim shouldSkip As Boolean
    Dim shouldAddNew As Boolean
    
    ' في VBA: CheckBox.Value = -1 (True) أو 0 (False)
    ' OptionButton.Value = True (-1) أو False (0)
    shouldUpdate = (chkUpdateExisting.Value = -1)
    shouldSkip = (chkSkipDuplicates.Value = -1)
    shouldAddNew = (optAddNew.Value = True)
    
    ' معالجة كل عنصر في البيانات المستوردة
    For i = 1 To importedData.count
        On Error Resume Next
        itemData = importedData(i)
        On Error GoTo 0
        
        ' ============================================
        ' الخطوة 1: التحقق من صحة البيانات الأساسية
        ' ============================================
        If IsEmpty(itemData) Then
            errorCount = errorCount + 1
            GoTo NextItem
        End If
        
        ' التحقق من وجود رمز المنتج واسمه
        If Trim(CStr(itemData(1))) = "" Or Trim(CStr(itemData(2))) = "" Then
            errorCount = errorCount + 1
            GoTo NextItem
        End If
        
        ' ============================================
        ' الخطوة 2: تنظيف رمز المنتج (المعرف الفريد)
        ' ============================================
        ' استخدام دالة CleanProductCode من Module_Import لضمان التنظيف الشامل والمقارنة الصحيحة
        productCode = CleanProductCode(CStr(itemData(1)))
        
        If productCode = "" Then
            errorCount = errorCount + 1
            GoTo NextItem
        End If
        
        ' ============================================
        ' الخطوة 3: التحقق من التكرار في نفس ملف الاستيراد
        ' ============================================
        If processedCodes.exists(productCode) Then
            ' المنتج مكرر في نفس ملف الاستيراد - تخطيه دائماً
            skippedCount = skippedCount + 1
            GoTo NextItem
        End If
        
        ' ============================================
        ' الخطوة 4: التحقق من وجود المنتج في قاعدة البيانات
        ' ============================================
        productExistsInDB = ProductExistsInTable(productCode)
        productRowIndex = 0
        
        If productExistsInDB Then
            productRowIndex = GetProductRowIndex(productCode)
            ' التحقق من صحة الفهرس
            If productRowIndex <= 0 Or productRowIndex > tbl.ListRows.count Then
                ' الفهرس غير صحيح - نعتبر المنتج غير موجود
                productExistsInDB = False
                productRowIndex = 0
            End If
        End If
        
        ' ============================================
        ' الخطوة 5: معالجة المنتج الموجود في قاعدة البيانات
        ' ============================================
        If productExistsInDB And productRowIndex > 0 Then
            ' المنتج موجود في قاعدة البيانات
            
            If shouldUpdate Then
                ' ===== تحديث المنتج الموجود =====
                On Error Resume Next
                tbl.ListRows(productRowIndex).Range(2).Value = CStr(itemData(2)) ' اسم الصنف
                tbl.ListRows(productRowIndex).Range(3).Value = CStr(itemData(3)) ' الوحدة
                If IsNumeric(itemData(4)) Then
                    tbl.ListRows(productRowIndex).Range(4).Value = CDbl(itemData(4)) ' سعر الشراء
                End If
                ' سعر البيع: نحدّث فقط إذا المستورد > 0 (إن كان 0 أو فارغاً لا نستبدل السعر الموجود)
                If IsNumeric(itemData(5)) And CDbl(itemData(5)) > 0 Then
                    tbl.ListRows(productRowIndex).Range(5).Value = CDbl(itemData(5)) ' سعر البيع
                End If
                tbl.ListRows(productRowIndex).Range(8).Value = Date ' تاريخ آخر تحديث
                If IsNumeric(itemData(4)) Then
                    tbl.ListRows(productRowIndex).Range(9).Value = CDbl(itemData(4)) ' آخر سعر شراء
                End If
                If IsNumeric(itemData(5)) And CDbl(itemData(5)) > 0 Then
                    tbl.ListRows(productRowIndex).Range(10).Value = CDbl(itemData(5)) ' آخر سعر بيع
                End If
                tbl.ListRows(productRowIndex).Range(11).Value = CStr(itemData(7)) ' ملاحظات
                On Error GoTo 0
                
                ' تحديث المخزون إذا كانت هناك كمية
                If IsNumeric(itemData(6)) Then
                    qty = CDbl(itemData(6))
                    If qty > 0 And IsNumeric(itemData(4)) Then
                        purchasePrice = CDbl(itemData(4))
                        UpdateInventoryForImport productCode, qty, purchasePrice
                    End If
                End If
                
                updatedCount = updatedCount + 1
                processedCodes.Add productCode, True
                GoTo NextItem
                
            ElseIf shouldSkip Then
                ' ===== تخطي المنتج الموجود =====
                skippedCount = skippedCount + 1
                processedCodes.Add productCode, True
                GoTo NextItem
                
            ElseIf shouldAddNew Then
                ' ===== خيار "إضافة جديدة فقط" - تخطي المنتج الموجود =====
                skippedCount = skippedCount + 1
                processedCodes.Add productCode, True
                GoTo NextItem
                
            Else
                ' ===== لا يوجد خيار محدد للمنتج الموجود - تخطيه =====
                skippedCount = skippedCount + 1
                processedCodes.Add productCode, True
                GoTo NextItem
            End If
        End If
        
        ' ============================================
        ' الخطوة 6: معالجة المنتج الجديد (غير موجود في قاعدة البيانات)
        ' ============================================
        If Not productExistsInDB Then
            ' المنتج جديد - إضافته فقط إذا كان الخيار "إضافة جديدة" مفعّل
            If shouldAddNew Then
                ' ===== إضافة المنتج الجديد =====
                On Error Resume Next
                Set newRow = tbl.ListRows.Add
                newRow.Range(1).Value = CStr(itemData(1)) ' رمز الصنف (الأصلي بدون تحويل)
                newRow.Range(2).Value = CStr(itemData(2)) ' اسم الصنف
                newRow.Range(3).Value = CStr(itemData(3)) ' الوحدة
                If IsNumeric(itemData(4)) Then
                    newRow.Range(4).Value = CDbl(itemData(4)) ' سعر الشراء
                Else
                    newRow.Range(4).Value = 0
                End If
                If IsNumeric(itemData(5)) Then
                    newRow.Range(5).Value = CDbl(itemData(5)) ' سعر البيع
                Else
                    newRow.Range(5).Value = 0
                End If
                newRow.Range(6).Value = Date ' تاريخ الإضافة
                newRow.Range(7).Value = "نشط" ' حالة المنتج
                newRow.Range(8).Value = Date ' تاريخ آخر تحديث
                If IsNumeric(itemData(4)) Then
                    newRow.Range(9).Value = CDbl(itemData(4)) ' آخر سعر شراء
                Else
                    newRow.Range(9).Value = 0
                End If
                If IsNumeric(itemData(5)) Then
                    newRow.Range(10).Value = CDbl(itemData(5)) ' آخر سعر بيع
                Else
                    newRow.Range(10).Value = 0
                End If
                newRow.Range(11).Value = CStr(itemData(7)) ' ملاحظات
                On Error GoTo 0
                
                ' إضافة سجل في Inventory مع الكمية
                If IsNumeric(itemData(6)) Then
                    qty = CDbl(itemData(6))
                Else
                    qty = 0
                End If
                
                If IsNumeric(itemData(4)) Then
                    purchasePrice = CDbl(itemData(4))
                Else
                    purchasePrice = 0
                End If
                
                AddInventoryForImport productCode, CStr(itemData(2)), qty, purchasePrice
                
                addedCount = addedCount + 1
                processedCodes.Add productCode, True
                GoTo NextItem
                
            Else
                ' ===== لا يوجد خيار "إضافة جديدة" - تخطي المنتج الجديد =====
                skippedCount = skippedCount + 1
                processedCodes.Add productCode, True
                GoTo NextItem
            End If
        End If
        
NextItem:
    Next i
    
    ' ============================================
    ' الخطوة 7: عرض تقرير النتائج
    ' ============================================
    Dim reportMsg As String
    reportMsg = "تم الانتهاء من الاستيراد:" & vbCrLf & vbCrLf
    reportMsg = reportMsg & "? تمت الإضافة: " & addedCount & " منتج" & vbCrLf
    reportMsg = reportMsg & "? تم التحديث: " & updatedCount & " منتج" & vbCrLf
    reportMsg = reportMsg & "? تم التخطي: " & skippedCount & " منتج" & vbCrLf
    If errorCount > 0 Then
        reportMsg = reportMsg & "? أخطاء: " & errorCount & " منتج"
    End If
    
    MsgBox reportMsg, vbInformation, "نتائج الاستيراد"
    
    ' تحديث ListView في frmProduct إذا كان مفتوحاً
    On Error Resume Next
    If Not frmProduct Is Nothing Then
        frmProduct.LoadProducts
    End If
    On Error GoTo 0
    
    ' مسح النموذج
    ClearForm
End Sub

' تحديث المخزون للاستيراد - محسّن
Private Sub UpdateInventoryForImport(productCode As String, qty As Double, purchasePrice As Double)
    Dim invTbl As ListObject
    Dim invRowIndex As Long
    Dim currentStock As Double
    Dim newStock As Double
    Dim currentAvgCost As Double
    Dim newAvgCost As Double
    
    On Error GoTo ErrorHandler
    
    ' التحقق من صحة المدخلات
    If Trim(productCode) = "" Or qty < 0 Or purchasePrice < 0 Then
        Exit Sub
    End If
    
    Set invTbl = GetTableByName("tlbInventory")
    If invTbl Is Nothing Then Exit Sub
    
    invRowIndex = GetInventoryRowIndex(productCode)
    If invRowIndex > 0 And invRowIndex <= invTbl.ListRows.count Then
        ' تحديث المخزون الموجود
        On Error Resume Next
        If IsNumeric(invTbl.ListRows(invRowIndex).Range(7).Value) Then
            currentStock = CDbl(invTbl.ListRows(invRowIndex).Range(7).Value)
        Else
            currentStock = 0
        End If
        On Error GoTo ErrorHandler
        
        newStock = currentStock + qty
        
        ' تحديث الكميات
        On Error Resume Next
        If IsNumeric(invTbl.ListRows(invRowIndex).Range(5).Value) Then
            invTbl.ListRows(invRowIndex).Range(5).Value = CDbl(invTbl.ListRows(invRowIndex).Range(5).Value) + qty ' الكمية الواردة
        Else
            invTbl.ListRows(invRowIndex).Range(5).Value = qty
        End If
        invTbl.ListRows(invRowIndex).Range(7).Value = newStock ' المخزون الحالي
        invTbl.ListRows(invRowIndex).Range(9).Value = Date ' آخر حركة
        On Error GoTo ErrorHandler
        
        ' تحديث Average Cost
        If invTbl.ListColumns.count >= 12 And IsNumeric(invTbl.ListRows(invRowIndex).Range(12).Value) Then
            currentAvgCost = CDbl(invTbl.ListRows(invRowIndex).Range(12).Value)
        ElseIf IsNumeric(invTbl.ListRows(invRowIndex).Range(4).Value) Then
            currentAvgCost = CDbl(invTbl.ListRows(invRowIndex).Range(4).Value)
        Else
            currentAvgCost = purchasePrice
        End If
        
        If currentStock > 0 And newStock > 0 Then
            newAvgCost = ((currentStock * currentAvgCost) + (qty * purchasePrice)) / newStock
        Else
            newAvgCost = purchasePrice
        End If
        
        ' حفظ متوسط التكلفة
        On Error Resume Next
        If invTbl.ListColumns.count >= 12 Then
            invTbl.ListRows(invRowIndex).Range(12).Value = newAvgCost
        End If
        invTbl.ListRows(invRowIndex).Range(4).Value = newAvgCost
        invTbl.ListRows(invRowIndex).Range(8).Value = newStock * newAvgCost ' قيمة المخزون
        On Error GoTo ErrorHandler
    End If
    
    Exit Sub
    
ErrorHandler:
    ' في حالة الخطأ، لا نفعل شيئاً (صامت)
    Exit Sub
End Sub

' إضافة سجل جديد في Inventory للاستيراد - محسّن
Private Sub AddInventoryForImport(productCode As String, productName As String, qty As Double, purchasePrice As Double)
    Dim invTbl As ListObject
    Dim invRow As ListRow
    
    On Error GoTo ErrorHandler
    
    ' التحقق من صحة المدخلات
    If Trim(productCode) = "" Or Trim(productName) = "" Then
        Exit Sub
    End If
    
    Set invTbl = GetTableByName("tlbInventory")
    If invTbl Is Nothing Then Exit Sub
    
    ' التحقق من وجود المنتج في Inventory قبل الإضافة
    If ProductExistsInInventory(productCode) Then
        ' تحديث المخزون الموجود
        UpdateInventoryForImport productCode, qty, purchasePrice
    Else
        ' إضافة سجل جديد
        On Error Resume Next
        Set invRow = invTbl.ListRows.Add
        invRow.Range(1).Value = CStr(productCode) ' رمز الصنف
        invRow.Range(2).Value = CStr(productName) ' اسم الصنف
        invRow.Range(3).Value = 0 ' المخزون أول الفترة
        invRow.Range(4).Value = IIf(purchasePrice > 0, purchasePrice, 0) ' متوسط التكلفة
        invRow.Range(5).Value = IIf(qty > 0, qty, 0) ' الكمية الواردة
        invRow.Range(6).Value = 0 ' الكمية الصادرة
        invRow.Range(7).Value = IIf(qty > 0, qty, 0) ' المخزون الحالي
        invRow.Range(8).Value = IIf(qty > 0 And purchasePrice > 0, qty * purchasePrice, 0) ' قيمة المخزون
        invRow.Range(9).Value = Date ' آخر حركة
        invRow.Range(10).Value = 10 ' حد التنبية (افتراضي)
        invRow.Range(11).Value = "كافي" ' الحالة
        If invTbl.ListColumns.count >= 12 Then
            invRow.Range(12).Value = IIf(purchasePrice > 0, purchasePrice, 0) ' Average Cost
        End If
        On Error GoTo ErrorHandler
    End If
    
    Exit Sub
    
ErrorHandler:
    ' في حالة الخطأ، لا نفعل شيئاً (صامت)
    Exit Sub
End Sub

' إلغاء
Private Sub cmdCancel_Click()
    Me.Hide
End Sub

' زر التحديث فقط - حل جذري
Private Sub cmdImportupdate_Click()
    If importedData Is Nothing Or importedData.count = 0 Then
        MsgBox "لا توجد بيانات للاستيراد. يرجى تحميل معاينة أولاً", vbExclamation
        Exit Sub
    End If
    
    ' التحقق من تفعيل خيار التحديث
    If chkUpdateExisting.Value <> -1 Then
        MsgBox "يرجى تفعيل خيار 'تحديث المنتجات الموجودة' أولاً", vbExclamation
        Exit Sub
    End If
    
    Dim response As VbMsgBoxResult
    response = MsgBox("هل أنت متأكد من تحديث " & importedData.count & " منتج؟" & vbCrLf & vbCrLf & _
                       "سيتم تحديث المنتجات الموجودة فقط.", vbYesNo + vbQuestion, "تأكيد التحديث")
    If response = vbNo Then Exit Sub
    
    ' استدعاء دالة التحديث فقط
    ImportUpdateOnly
End Sub

' دالة التحديث فقط - حل جذري منفصل تماماً
Private Sub ImportUpdateOnly()
    Dim i As Long
    Dim updatedCount As Long
    Dim skippedCount As Long
    Dim errorCount As Long
    Dim notFoundCount As Long
    Dim itemData As Variant
    Dim tbl As ListObject
    Dim qty As Double
    Dim productCode As String
    Dim purchasePrice As Double
    Dim processedCodes As Object ' Dictionary لتتبع المنتجات المعالجة
    Dim productExistsInDB As Boolean
    Dim productRowIndex As Long
    Dim hasChanges As Boolean
    
    On Error GoTo ErrorHandler
    
    ' الحصول على جدول المنتجات
    Set tbl = GetTableByName("tlbproduct")
    If tbl Is Nothing Then
        MsgBox "خطأ: لا يمكن العثور على جدول المنتجات", vbCritical
        Exit Sub
    End If
    
    ' إنشاء Dictionary لتتبع المنتجات المعالجة
    Set processedCodes = CreateObject("Scripting.Dictionary")
    
    ' تهيئة العدادات
    updatedCount = 0
    skippedCount = 0
    errorCount = 0
    notFoundCount = 0
    
    ' معالجة كل عنصر في البيانات المستوردة
    For i = 1 To importedData.count
        On Error Resume Next
        itemData = importedData(i)
        On Error GoTo ErrorHandler
        
        ' ============================================
        ' الخطوة 1: التحقق من صحة البيانات الأساسية
        ' ============================================
        If IsEmpty(itemData) Then
            errorCount = errorCount + 1
            GoTo NextItem
        End If
        
        ' التحقق من وجود رمز المنتج واسمه
        If Trim(CStr(itemData(1))) = "" Or Trim(CStr(itemData(2))) = "" Then
            errorCount = errorCount + 1
            GoTo NextItem
        End If
        
        ' ============================================
        ' الخطوة 2: تنظيف رمز المنتج (المعرف الفريد)
        ' ============================================
        ' استخدام دالة CleanProductCode من Module_Import لضمان التنظيف الشامل والمقارنة الصحيحة
        productCode = CleanProductCode(CStr(itemData(1)))
        
        If productCode = "" Then
            errorCount = errorCount + 1
            GoTo NextItem
        End If
        
        ' ============================================
        ' الخطوة 3: التحقق من التكرار في نفس ملف الاستيراد
        ' ============================================
        If processedCodes.exists(productCode) Then
            skippedCount = skippedCount + 1
            GoTo NextItem
        End If
        
        ' ============================================
        ' الخطوة 4: التحقق من وجود المنتج في قاعدة البيانات
        ' ============================================
        productExistsInDB = ProductExistsInTable(productCode)
        productRowIndex = 0
        
        If productExistsInDB Then
            productRowIndex = GetProductRowIndex(productCode)
            If productRowIndex <= 0 Or productRowIndex > tbl.ListRows.count Then
                productExistsInDB = False
                productRowIndex = 0
            End If
        End If
        
        ' ============================================
        ' الخطوة 5: تحديث المنتج الموجود فقط
        ' ============================================
        If productExistsInDB And productRowIndex > 0 Then
            ' المنتج موجود - تحديثه
            hasChanges = False
            
            On Error Resume Next
            
            ' التحقق من وجود تغييرات قبل التحديث
            If CStr(tbl.ListRows(productRowIndex).Range(2).Value) <> CStr(itemData(2)) Then
                hasChanges = True
            ElseIf CStr(tbl.ListRows(productRowIndex).Range(3).Value) <> CStr(itemData(3)) Then
                hasChanges = True
            ElseIf IsNumeric(itemData(4)) And CDbl(tbl.ListRows(productRowIndex).Range(4).Value) <> CDbl(itemData(4)) Then
                hasChanges = True
            ElseIf IsNumeric(itemData(5)) And CDbl(tbl.ListRows(productRowIndex).Range(5).Value) <> CDbl(itemData(5)) Then
                hasChanges = True
            ElseIf CStr(tbl.ListRows(productRowIndex).Range(11).Value) <> CStr(itemData(7)) Then
                hasChanges = True
            End If
            
            ' تحديث البيانات
            tbl.ListRows(productRowIndex).Range(2).Value = CStr(itemData(2)) ' اسم الصنف
            tbl.ListRows(productRowIndex).Range(3).Value = CStr(itemData(3)) ' الوحدة
            If IsNumeric(itemData(4)) Then
                tbl.ListRows(productRowIndex).Range(4).Value = CDbl(itemData(4)) ' سعر الشراء
            End If
            ' سعر البيع: نحدّث فقط إذا المستورد > 0 (إن كان 0 أو فارغاً لا نستبدل السعر الموجود)
            If IsNumeric(itemData(5)) And CDbl(itemData(5)) > 0 Then
                tbl.ListRows(productRowIndex).Range(5).Value = CDbl(itemData(5)) ' سعر البيع
            End If
            tbl.ListRows(productRowIndex).Range(8).Value = Date ' تاريخ آخر تحديث
            If IsNumeric(itemData(4)) Then
                tbl.ListRows(productRowIndex).Range(9).Value = CDbl(itemData(4)) ' آخر سعر شراء
            End If
            If IsNumeric(itemData(5)) And CDbl(itemData(5)) > 0 Then
                tbl.ListRows(productRowIndex).Range(10).Value = CDbl(itemData(5)) ' آخر سعر بيع
            End If
            tbl.ListRows(productRowIndex).Range(11).Value = CStr(itemData(7)) ' ملاحظات
            On Error GoTo ErrorHandler
            
            ' تحديث المخزون إذا كانت هناك كمية
            If IsNumeric(itemData(6)) Then
                qty = CDbl(itemData(6))
                If qty > 0 And IsNumeric(itemData(4)) Then
                    purchasePrice = CDbl(itemData(4))
                    UpdateInventoryForImport productCode, qty, purchasePrice
                End If
            End If
            
            updatedCount = updatedCount + 1
            processedCodes.Add productCode, True
            GoTo NextItem
            
        Else
            ' المنتج غير موجود - تخطيه
            notFoundCount = notFoundCount + 1
            processedCodes.Add productCode, True
            GoTo NextItem
        End If
        
NextItem:
    Next i
    
    ' ============================================
    ' الخطوة 6: عرض تقرير النتائج
    ' ============================================
    Dim reportMsg As String
    reportMsg = "تم الانتهاء من التحديث:" & vbCrLf & vbCrLf
    reportMsg = reportMsg & "? تم التحديث: " & updatedCount & " منتج" & vbCrLf
    reportMsg = reportMsg & "? غير موجود: " & notFoundCount & " منتج" & vbCrLf
    reportMsg = reportMsg & "? تم التخطي: " & skippedCount & " منتج" & vbCrLf
    If errorCount > 0 Then
        reportMsg = reportMsg & "? أخطاء: " & errorCount & " منتج"
    End If
    
    MsgBox reportMsg, vbInformation, "نتائج التحديث"
    
    ' تحديث ListView في frmProduct إذا كان مفتوحاً
    On Error Resume Next
    If Not frmProduct Is Nothing Then
        frmProduct.LoadProducts
    End If
    On Error GoTo 0
    
    Exit Sub
    
ErrorHandler:
    MsgBox "حدث خطأ أثناء التحديث: " & Err.Description, vbCritical
End Sub

' مسح النموذج
Private Sub ClearForm()
    txtFilePath.Value = ""
    filePath = ""
    Set importedData = New Collection
    ListBox1.Clear
    lblStatus.Caption = ""
    ' إعادة تعيين الخيارات
    chkSkipDuplicates.Value = False
    chkUpdateExisting.Value = False
    optAddNew.Value = False
    ' تعطيل زر التحديث
    cmdImportupdate.Enabled = False
End Sub




