/**
 * KNSDD Kural Yönetimi - Olay Yönetim Modülü
 *
 * Bu dosya, Kural Yönetimi sayfasındaki tüm kullanıcı etkileşimlerini (tıklama,
 * değişiklik vb.) yönetir. Diğer modülleri (render, modals, validators)
 * kullanarak sayfanın ana iş mantığını yürütür ve başlatır.
 */
jQuery(document).ready(function ($) {
    'use strict';

    // Sadece kural yönetimi sayfasındaysak bu kodları çalıştır.
    if (typeof knsdd_data === 'undefined' || knsdd_data.page !== 'rules') {
        return;
    }

    // Gerekli modüllerin varlığını kontrol et
    if (typeof KNSDDRules === 'undefined' || !KNSDDRules.render || !KNSDDRules.validators || !KNSDDRules.modals) {
        console.error('KNSDD Rules modülleri düzgün yüklenemedi.');
        return;
    }

    // Sık kullanılan jQuery nesnelerini tanımla
    const $selectGroup = $('#knsdd-select-group');
    const $rulesTbody = $('#knsdd-rules-tbody');
    // Ürün -> Kategori eşleşmelerini sayfa yaşamında cache'leriz
    const productCatCache = {};

    /**
     * Süresi bitmiş kampanyalar için UI'ı read-only yapar
     */
    const applyExpiredGroupState = () => {
        // Kuralları Kaydet butonunu gizle
        $('#knsdd-save-rules').hide();

        // Yeni Kural Ekle butonunu gizle
        $('#knsdd-add-rule').hide();

        // Tüm input alanlarını disable et
        $rulesTbody.find('select, input[type="text"], input[type="number"], input[type="checkbox"]:not(.knsdd-tier-checkbox)').prop('disabled', true);

        // Select2'leri disable et
        $rulesTbody.find('select').trigger('change.select2');

        // Tüm butonları disable et (EXCEPT limitler butonu - sadece görüntüleme için açılabilir)
        $rulesTbody.find('button:not(.knsdd-limits-rule)').prop('disabled', true).addClass('knsdd-btn-disabled');

        // Limitler butonuna görsel olarak "sadece görüntüleme" işareti ekle
        $rulesTbody.find('.knsdd-limits-rule').addClass('knsdd-btn-readonly');

        // Görsel feedback: Satırları soluklaştır
        $rulesTbody.find('tr').addClass('knsdd-expired-row');
    };

    /**
     * Expired state'i kaldırır, UI'ı normal hale getirir
     */
    const removeExpiredGroupState = () => {
        const groupName = $('#knsdd-select-group').val();
        const groupRuleType = knsdd_data.group_rule_types && knsdd_data.group_rule_types[groupName];

        // Özel kampanyada buton kontrolü applyGroupRuleTypeRestrictions tarafından yapılır
        // Diğer grup tiplerinde butonları göster
        if (groupRuleType !== 'special_campaign') {
            $('#knsdd-save-rules').show();
            $('#knsdd-add-rule').show();
        }
        // NOT: Özel kampanyalarda butonlar applyGroupRuleTypeRestrictions tarafından kontrol edilir

        // Input alanlarını enable et
        $rulesTbody.find('select, input[type="text"], input[type="number"], input[type="checkbox"]:not(.knsdd-tier-checkbox)').prop('disabled', false);

        // Select2'leri enable et
        $rulesTbody.find('select').trigger('change.select2');

        // Butonları enable et
        $rulesTbody.find('button').prop('disabled', false).removeClass('knsdd-btn-disabled knsdd-btn-readonly');

        // Görsel feedback'i kaldır
        $rulesTbody.find('tr').removeClass('knsdd-expired-row');
    };

    // Satır içi uyarıları temizle
    const clearInlineWarnings = () => {
        $rulesTbody.find('.knsdd-notice').remove();
        $('.knsdd-form-field .knsdd-validation .knsdd-notice').remove();
        $('.knsdd-warning-row').remove();
        $('.knsdd-inline-error-row').remove();
    };

    // Inline uyarı göster - gruplar sayfası ile birebir aynı
    const showInlineWarning = ($row, message) => {
        if (!$row || !$row.length) return;

        // Ayarlardan tema, süre ve erişilebilirlik al (gruplar sayfası ile aynı)
        const theme = (knsdd_data.settings && knsdd_data.settings.warning_theme) ? knsdd_data.settings.warning_theme : 'rose';
        const duration = (knsdd_data.settings && knsdd_data.settings.inline_warning_ms) ? parseInt(knsdd_data.settings.inline_warning_ms, 10) : 5000;
        const useAlertRole = (knsdd_data.settings && knsdd_data.settings.a11y_alert_role);

        // Mevcut inline uyarıyı kontrol et
        let $inline = $row.next('tr.knsdd-inline-error-row');
        if (!$inline.length) {
            // Dinamik colspan: satırdaki sütun sayısını al
            const colCount = $row.find('td').length || 100;
            const roleAttrs = useAlertRole ? ' role="alert" aria-live="polite"' : '';
            $inline = $('<tr class="knsdd-inline-error-row"><td colspan="' + colCount + '" class="knsdd-inline-warning knsdd-theme-' + theme + '"' + roleAttrs + '></td></tr>');
            $row.after($inline);
        }
        $inline.find('td').text(message);

        // Belirli süre sonra kaldır (gruplar sayfası ile aynı)
        setTimeout(() => {
            $inline.fadeOut(300, function () {
                $(this).remove();
            });
        }, duration);
    };

    /**
     * Sayfadaki tüm olay dinleyicilerini (event listeners) bağlar.
     */
    const bindEvents = () => {
        // Yardımcılar: Seçili ürün ID'lerini oku ve kategori haritalamasını (cache'li) hazırla
        const getSelectedProductIds = ($row) => {
            return ($row.find('.knsdd-rule-product').val() || [])
                .map(v => parseInt(v, 10))
                .filter(v => !isNaN(v));
        };

        const ensureProductCats = (productIds, cb) => {
            try {
                const missing = Array.from(new Set((productIds || []).filter(id => !(id in productCatCache))));
                if (missing.length === 0) { if (typeof cb === 'function') cb(); return; }
                ajaxRequest('get_product_categories', { product_ids: missing }, (resp) => {
                    const map = (resp && resp.map) ? resp.map : {};
                    Object.keys(map).forEach(k => {
                        const pid = parseInt(k, 10);
                        productCatCache[pid] = (map[k] || []).map(x => parseInt(x, 10));
                    });
                    if (typeof cb === 'function') cb();
                }, () => { if (typeof cb === 'function') cb(); });
            } catch (_e) { if (typeof cb === 'function') cb(); }
        };

        const computeCommonCategoryIfUnique = (productIds) => {
            if (!Array.isArray(productIds) || productIds.length === 0) return null;
            if (productIds.length === 1) {
                const cats = productCatCache[productIds[0]] || [];
                if (cats.length === 0) return null;
                // Tek üründe: İlk kategoriyi döndür (backend'den sıralı gelir: doğrudan atanan önce)
                return cats[0];
            }
            // Çoklu ürün: kategorilerin kesişimi tekse döndür
            let set = new Set(productCatCache[productIds[0]] || []);
            for (let i = 1; i < productIds.length; i++) {
                const next = new Set(productCatCache[productIds[i]] || []);
                set = new Set([...set].filter(x => next.has(x)));
                if (set.size === 0) break;
            }
            return (set.size === 1) ? Array.from(set)[0] : null;
        };

        const autoFillCategoryIfNeeded = ($row) => {
            const $cat = $row.find('.knsdd-rule-category');
            const pids = getSelectedProductIds($row);

            // Ürün yoksa kategoriyi temizle
            if (pids.length === 0) {
                if ($cat.val()) {
                    $cat.val(null).trigger('change');
                }
                return;
            }

            // Kategori zaten seçiliyse dokunma
            const currentCat = $cat.val();
            if (currentCat) return;

            // Ürün varsa ve kategori boşsa otomatik doldur
            ensureProductCats(pids, () => {
                const uniqueCat = computeCommonCategoryIfUnique(pids);
                if (uniqueCat) {
                    $cat.val(String(uniqueCat)).trigger('change');
                }
            });
        };

        const pruneProductsNotInCategory = ($row) => {
            const $cat = $row.find('.knsdd-rule-category');
            const catVal = parseInt($cat.val(), 10);
            if (!catVal || isNaN(catVal)) return;
            const $prod = $row.find('.knsdd-rule-product');
            const selected = getSelectedProductIds($row);
            if (selected.length === 0) return;
            ensureProductCats(selected, () => {
                const kept = selected.filter(pid => (productCatCache[pid] || []).includes(catVal));
                const removedCount = selected.length - kept.length;
                if (removedCount > 0) {
                    $prod.val(kept.map(String)).trigger('change');
                    const msg = (knsdd_data.i18n && knsdd_data.i18n.products_pruned_due_category)
                        ? String(knsdd_data.i18n.products_pruned_due_category).replace('%d', removedCount)
                        : (removedCount + ' ürün seçili kategoride olmadığı için kaldırıldı.');
                    showInlineWarning($row, msg);
                }
            });
        };

        const getCurrentRuleCount = () => $rulesTbody.find('tr[data-rule-id]').length;

        const openUpgradePage = () => {
            const upgradeUrl = (knsdd_data.license && knsdd_data.license.upgrade_url) ? knsdd_data.license.upgrade_url : '#';
            if (upgradeUrl && upgradeUrl !== '#') {
                window.open(upgradeUrl, '_blank');
            }
        };

        const isFreeFixedDiscountLimitReached = (groupName, showWarning = true) => {
            if (!groupName) return false;
            const groupRuleType = knsdd_data.group_rule_types && knsdd_data.group_rule_types[groupName];
            if (groupRuleType !== 'fixed_discount') return false;

            const maxRules = (knsdd_data.license && knsdd_data.license.max_rules_per_group) ? parseInt(knsdd_data.license.max_rules_per_group, 10) : 3;
            const currentRuleCount = getCurrentRuleCount();

            if (currentRuleCount >= maxRules) {
                if (showWarning) {
                    const limitMsg = (knsdd_data.i18n && knsdd_data.i18n.free_rules_limit_reached)
                        ? knsdd_data.i18n.free_rules_limit_reached
                        : '';
                    if (limitMsg) {
                        showNotice('warning', limitMsg);
                    }
                }
                return true;
            }
            return false;
        };

        // Grup seçimi değiştiğinde kuralları yeniden çiz
        $selectGroup.on('change', function () {
            const groupName = $(this).val();
            KNSDDRules.render.rules(groupName, $rulesTbody);

            // Grup tipine göre UI kısıtlamalarını uygula
            if (groupName && KNSDDRules.render.applyGroupRuleTypeRestrictions) {
                KNSDDRules.render.applyGroupRuleTypeRestrictions(groupName);
            }

            // Süresi bitmiş kampanyalar için UI'ı disable et
            if (groupName && KNSDDRules.utils.isGroupExpired(groupName)) {
                applyExpiredGroupState();
            } else {
                removeExpiredGroupState();
            }
        });

        // Yeni kural ekle butonu
        $('#knsdd-add-rule').on('click', () => {
            const groupName = $selectGroup.val();
            if (!groupName) {
                showNotice('error', knsdd_data.i18n.please_select_group);
                return;
            }

            if (isFreeFixedDiscountLimitReached(groupName, true)) {
                openUpgradePage();
                if (KNSDDRules.render.applyGroupRuleTypeRestrictions) {
                    KNSDDRules.render.applyGroupRuleTypeRestrictions(groupName);
                }
                return;
            }

            // Grup tipine göre rule_type'ı belirt
            const groupRuleType = knsdd_data.group_rule_types && knsdd_data.group_rule_types[groupName];
            const newRule = {};
            if (groupRuleType === 'special_campaign') {
                newRule.rule_type = 'special_campaign';
            }

            $rulesTbody.append(KNSDDRules.render.ruleRow(newRule));

            // Yeni satır eklendikten sonra kısıtlamaları tekrar uygula
            if (KNSDDRules.render.applyGroupRuleTypeRestrictions) {
                KNSDDRules.render.applyGroupRuleTypeRestrictions(groupName);
            }
        });

        // Kuralları Kaydet butonu
        $('#knsdd-save-rules').on('click', () => {
            // Önceki satır içi uyarıları temizle
            clearInlineWarnings();

            const group = $selectGroup.val();
            if (!group) {
                // Ayar kontrolü: satır içi veya üstte göster
                if (knsdd_data.settings && knsdd_data.settings.warning_location === 'top_notice') {
                    showNotice('error', knsdd_data.i18n.please_select_group);
                } else {
                    // Satır içi gösterim için uygun bir alan bul
                    const $groupSelect = $('#knsdd-select-group');
                    const $validation = $groupSelect.closest('.knsdd-form-field').find('.knsdd-validation');
                    if ($validation.length) {
                        $validation.html(`<div class="knsdd-notice knsdd-notice-error"><p>${knsdd_data.i18n.please_select_group}</p></div>`).show();
                    } else {
                        showNotice('error', knsdd_data.i18n.please_select_group);
                    }
                }
                return;
            }

            // Kopya kuralları kontrol et
            const signatureToRows = new Map();
            let duplicateRows = [];

            $rulesTbody.find('tr').each(function () {
                const $row = $(this);
                if (KNSDDRules.validators.isRowCompletelyEmpty($row)) {
                    return;
                }

                const sig = KNSDDRules.validators.buildRowSignature($row);
                const rows = signatureToRows.get(sig) || [];
                rows.push($row);
                signatureToRows.set(sig, rows);
            });

            // Sadece ilk satır dışındaki kopyaları işaretle ve kenarlık sınıflarını ekle
            signatureToRows.forEach(rows => {
                if (rows.length > 1) {
                    const actualDuplicates = rows.slice(1); // İlk elemanı (orijinali) atla
                    actualDuplicates.forEach((r, idx) => {
                        r.addClass('knsdd-row-duplicate');
                        if (idx === 0) { r.addClass('knsdd-row-duplicate-start'); }
                        if (idx === actualDuplicates.length - 1) { r.addClass('knsdd-row-duplicate-end'); }
                    });
                    duplicateRows = duplicateRows.concat(actualDuplicates);
                }
            });

            if (duplicateRows.length > 0) {
                // Ayar kontrolü: satır içi veya üstte göster
                if (knsdd_data.settings && knsdd_data.settings.warning_location === 'top_notice') {
                    showNotice('warning', knsdd_data.i18n.duplicate_rules_warning);
                } else {
                    // Satır içi: ayarlar sayfasındaki tema ile
                    const $firstDuplicateRow = duplicateRows[0];
                    showInlineWarning($firstDuplicateRow, knsdd_data.i18n.duplicate_rules_warning);
                    if ($firstDuplicateRow && $firstDuplicateRow.offset()) {
                        $('html, body').animate({ scrollTop: $firstDuplicateRow.offset().top - 120 }, 300);
                    }
                }
                return;
            }

            // --- KATEGORİ–ÜRÜN ve GRUPLAR ARASI KAPSAM ÇAKIŞMASI KONTROLLERİ + KAYDET ---
            const proceedSaveFlow = (productCatMap) => {
                // AJAX için kural verilerini topla
                const rulesPayload = [];
                let anySwappedRanges = false;
                $rulesTbody.find('tr').each(function () {
                    const $row = $(this);
                    if (KNSDDRules.validators.isRowCompletelyEmpty($row)) { return; }
                    const ruleData = $row.data('ruleData') || {};
                    // Min/Max normalize: DOM üzerinde swap (0 => sonsuz olarak kalır)
                    const minStrInput = $row.find('.knsdd-rule-min');
                    const maxStrInput = $row.find('.knsdd-rule-max');
                    const mn = parseFloat(minStrInput.val());
                    const mx = parseFloat(maxStrInput.val());
                    const minNum = isNaN(mn) ? 0 : Math.max(0, mn);
                    const rawMaxNum = isNaN(mx) ? 0 : Math.max(0, mx);
                    if (rawMaxNum !== 0 && isFinite(rawMaxNum) && isFinite(minNum) && minNum > rawMaxNum) {
                        // Swap DOM
                        minStrInput.val(rawMaxNum);
                        maxStrInput.val(minNum);
                        anySwappedRanges = true;
                    }
                    const min = parseFloat(minStrInput.val()) || 0;
                    const max = parseFloat(maxStrInput.val()) || 0;

                    const baseData = {
                        rule_id: ruleData.rule_id,
                        category: $row.find('.knsdd-rule-category').val(),
                        product: $row.find('.knsdd-rule-product').val() || [],
                        min: min,
                        max: max,
                        login_required: $row.find('.knsdd-rule-login-required').is(':checked'),
                        first_order_only: $row.find('.knsdd-rule-first-order').is(':checked'),
                        allowed_customers: ruleData.allowed_customers || [],
                        rule_type: ruleData.rule_type || 'standard_discount',
                        messages: ruleData.messages || {},
                        total_limit: ruleData.total_limit || 0,
                        per_customer_limit: ruleData.per_customer_limit || 0,
                    };

                    if (baseData.rule_type === 'special_campaign') {
                        Object.assign(baseData, {
                            campaign_type: ruleData.campaign_type,
                            buy_x: ruleData.buy_x,
                            pay_y: ruleData.pay_y,
                            nth: ruleData.nth,
                            min_cart_total: ruleData.min_cart_total,
                            discount_type: ruleData.discount_type,
                            discount_value: ruleData.discount_value,
                            // BOGO alanları - YENİ: Kategori+Ürün kombinasyonu desteği
                            // trigger_type/target_type artık kullanılmıyor (backend direkt products/category'ye bakıyor)
                            // Geriye uyumluluk için 'product' gönderiyoruz
                            trigger_type: 'product',
                            trigger_products: ruleData.trigger_products || [],
                            trigger_category: ruleData.trigger_category || 0,
                            trigger_quantity: ruleData.trigger_quantity,
                            target_type: 'product',
                            target_products: ruleData.target_products || [],
                            target_category: ruleData.target_category || 0,
                            target_quantity: ruleData.target_quantity
                        });
                    } else {
                        Object.assign(baseData, {
                            discount_type: $row.find('.knsdd-rule-discount-type').val(),
                            discount_value: $row.find('.knsdd-rule-discount-value').val()
                        });
                    }
                    rulesPayload.push(baseData);
                });

                if (anySwappedRanges) {
                    const msgSwap = (knsdd_data.i18n && knsdd_data.i18n.normalized_min_max)
                        ? knsdd_data.i18n.normalized_min_max
                        : 'Bazı satırlarda minimum > maksimum girilmişti; değerler otomatik düzeltildi.';
                    showNotice('warning', msgSwap);
                }

                // --- KOPYA GRUP KONTROLÜ (tarih çakışması + aynı kural seti) ---
                const parseYMD = (s) => { if (!s) return null; const [y, m, d] = String(s).split('-').map(Number); return (y && m && d) ? new Date(y, m - 1, d) : null; };
                const rangesOverlap = (aS, aE, bS, bE) => {
                    if (!aS || !aE || !bS || !bE) return false; // tarihsizler serbest
                    const aStart = parseYMD(aS), aEnd = parseYMD(aE), bStart = parseYMD(bS), bEnd = parseYMD(bE);
                    if (!aStart || !aEnd || !bStart || !bEnd) return false;
                    aStart.setHours(0, 0, 0, 0); aEnd.setHours(0, 0, 0, 0); bStart.setHours(0, 0, 0, 0); bEnd.setHours(0, 0, 0, 0);
                    return aStart <= bEnd && bStart <= aEnd;
                };

                const datesMap = (knsdd_data.data && knsdd_data.data.dates) ? knsdd_data.data.dates : {};
                const myDates = (datesMap && datesMap[group]) ? datesMap[group] : { start: '', end: '' };
                const myGroupRuleType = (knsdd_data.rule_types && knsdd_data.rule_types[group]) || 'fixed_discount';
                let conflictingGroup = null;
                for (const otherGroup of (knsdd_data.groups || [])) {
                    if (otherGroup === group) continue;

                    // Farklı tipteki grupları atla (sabit indirim vs özel kampanya)
                    const otherRuleType = (knsdd_data.rule_types && knsdd_data.rule_types[otherGroup]) || 'fixed_discount';
                    if (myGroupRuleType !== otherRuleType) continue;

                    // Tamamlanmış kampanyaları atla (performans optimizasyonu)
                    const od = (knsdd_data.data.dates && knsdd_data.data.dates[otherGroup]) || { start: '', end: '' };
                    if (od.end) {
                        const endDate = parseYMD(od.end);
                        const today = new Date();
                        today.setHours(0, 0, 0, 0);
                        if (endDate && endDate < today) {
                            continue; // Tamamlanmış kampanya
                        }
                    }

                    if (!rangesOverlap(myDates.start, myDates.end, od.start, od.end)) continue;
                    const otherRules = (knsdd_data.data.rules && knsdd_data.data.rules[otherGroup]) || [];
                    if (KNSDDRules.validators.areRuleSetsEqual(rulesPayload, otherRules)) { conflictingGroup = otherGroup; break; }
                }

                if (conflictingGroup) {
                    const $rows = $rulesTbody.find('tr');
                    $rows.removeClass('knsdd-row-duplicate knsdd-row-duplicate-start knsdd-row-duplicate-end');
                    $rows.addClass('knsdd-row-duplicate');
                    $rows.first().addClass('knsdd-row-duplicate-start');
                    $rows.last().addClass('knsdd-row-duplicate-end');
                    const msg = (knsdd_data.i18n && knsdd_data.i18n.duplicate_group_rules_with_overlap)
                        ? knsdd_data.i18n.duplicate_group_rules_with_overlap.replace('%s', conflictingGroup)
                        : `Bu grup ‘${conflictingGroup}’ grubu ile bire bir aynı kurallar içermektedir. Lütfen tarih aralığını değiştirin.`;
                    // Ayar kontrolü: satır içi veya üstte göster
                    if (knsdd_data.settings && knsdd_data.settings.warning_location === 'top_notice') {
                        showNotice('error', msg);
                    } else {
                        // Satır içi: ayarlar sayfasındaki tema ile geçici göster
                        showInlineWarning($rows.first(), msg);
                    }
                    const $first = $rows.first();
                    if ($first && $first.offset()) { $('html, body').animate({ scrollTop: $first.offset().top - 120 }, 300); }
                    return;
                }

                // Kaydet
                // NOT: Buton görünürlüğü applyGroupRuleTypeRestrictions() tarafından yönetiliyor
                // Burada ek gizleme yapmıyoruz çünkü render.rules() zaten doğru durumu ayarlıyor

                ajaxRequest('save_rules', { group, rules: rulesPayload }, (data) => {
                    knsdd_data.data.rules[group] = data.rules;
                    // render.rules() otomatik olarak boş satır ekler (eğer rules boşsa)
                    KNSDDRules.render.rules(group, $rulesTbody);

                    try { if (window.localStorage) localStorage.setItem('lastGroup', group); } catch (e) { }
                    showNotice('success', data.message);
                });
            };

            // --- Ön Kontrol: Aynı grupta kategori–ürün çatışması + Gruplar arası kapsam çatışması ---

            // Özel kampanya: Grup içi kontrol atla (tek kural var)
            const groupRuleType = knsdd_data.group_rule_types && knsdd_data.group_rule_types[group];
            if (groupRuleType === 'special_campaign') {
                // Direkt kaydet (backend validation var)
                proceedSaveFlow({});
                return;
            }

            // --- Sabit İndirim: Grup içi + Gruplar arası kontrol ---
            // --- ÖNCE: Aynı grupta aynı kapsamda miktar aralığı çakışması (ÜRÜN–ÜRÜN ve KATEGORİ–KATEGORİ) ---
            // max=0 sonsuz kabul edilir; [a,b] ve [c,d] aralığı a <= d && c <= b ise çakışır
            const parseRange = (minStr, maxStr) => {
                const mn = parseFloat(minStr); const mx = parseFloat(maxStr);
                let min = isNaN(mn) ? 0 : Math.max(0, mn);
                let rawMax = isNaN(mx) ? 0 : Math.max(0, mx);
                // 0 => sonsuz
                let max = (!isFinite(rawMax) || rawMax === 0) ? Number.POSITIVE_INFINITY : rawMax;
                // Her iki değer de sonlu ve min > max ise swap
                if (rawMax !== 0 && isFinite(rawMax) && isFinite(min) && min > rawMax) {
                    const tmp = min; min = rawMax; max = tmp;
                }
                return { min, max };
            };
            const rangesOverlapNums = (a, b) => (a.min <= b.max) && (b.min <= a.max);

            // Tek döngüde tüm verileri topla (performans optimizasyonu)
            const rangeCategoryRows = [];
            const rangeProductRows = [];
            const categoryOnlyRows = [];
            const productRows = [];
            const collectProductIds = new Set();

            $rulesTbody.find('tr').each(function () {
                const $row = jQuery(this);
                if (KNSDDRules.validators.isRowCompletelyEmpty($row)) return;
                const rd = $row.data('ruleData') || {};
                const ruleType = rd.rule_type || 'standard_discount';
                if (ruleType === 'special_campaign' && rd.campaign_type === 'cart_total_discount') {
                    return;
                }
                const catVal = $row.find('.knsdd-rule-category').val();
                const prodVals = ($row.find('.knsdd-rule-product').val() || []).map(v => parseInt(v, 10)).filter(v => !isNaN(v));
                const rng = parseRange($row.find('.knsdd-rule-min').val(), $row.find('.knsdd-rule-max').val());

                if (catVal && (!prodVals || prodVals.length === 0)) {
                    const catId = parseInt(catVal, 10);
                    // Hem aralık kontrolü hem kategori-ürün kontrolü için
                    rangeCategoryRows.push({ $row, category: catId, range: rng });
                    categoryOnlyRows.push({ $row, category: catId, range: rng });
                }
                if (prodVals && prodVals.length > 0) {
                    // Hem aralık kontrolü hem kategori-ürün kontrolü için
                    rangeProductRows.push({ $row, products: prodVals, range: rng });
                    productRows.push({ $row, products: prodVals, range: rng });
                    prodVals.forEach(id => collectProductIds.add(id));
                }
            });

            let rangeConflict = false;
            const markConflictRow = ($r) => { $r.addClass('knsdd-row-duplicate'); };

            // Kategori–Kategori: aynı kategori ve aralık çakışması
            for (let i = 0; i < rangeCategoryRows.length && !rangeConflict; i++) {
                for (let j = i + 1; j < rangeCategoryRows.length; j++) {
                    const A = rangeCategoryRows[i], B = rangeCategoryRows[j];
                    if (A.category === B.category && rangesOverlapNums(A.range, B.range)) {
                        rangeConflict = true; markConflictRow(A.$row); markConflictRow(B.$row); break;
                    }
                }
            }
            // Ürün–Ürün: ürün kümeleri kesişiyor ve aralık çakışıyor
            if (!rangeConflict) {
                for (let i = 0; i < rangeProductRows.length && !rangeConflict; i++) {
                    for (let j = i + 1; j < rangeProductRows.length; j++) {
                        const A = rangeProductRows[i], B = rangeProductRows[j];
                        const setA = new Set(A.products);
                        const intersects = B.products.some(p => setA.has(p));
                        if (intersects && rangesOverlapNums(A.range, B.range)) {
                            rangeConflict = true; markConflictRow(A.$row); markConflictRow(B.$row); break;
                        }
                    }
                }
            }

            if (rangeConflict) {
                const $confRows = $rulesTbody.find('tr.knsdd-row-duplicate');
                if ($confRows.length) { $confRows.first().addClass('knsdd-row-duplicate-start'); $confRows.last().addClass('knsdd-row-duplicate-end'); $('html, body').animate({ scrollTop: $confRows.first().offset().top - 120 }, 300); }
                const msg = (knsdd_data.i18n && knsdd_data.i18n.conflict_scope_qty_range)
                    ? knsdd_data.i18n.conflict_scope_qty_range
                    : 'Aynı kapsamda miktar aralığı çakışan kurallar var. Lütfen aralıkları ayrıştırın.';
                // Ayar kontrolü: satır içi veya üstte göster
                if (knsdd_data.settings && knsdd_data.settings.warning_location === 'top_notice') {
                    showNotice('error', msg);
                } else {
                    // Satır içi: ayarlar sayfasındaki tema ile geçici göster
                    const $conflictRows = $rulesTbody.find('tr.knsdd-row-duplicate');
                    if ($conflictRows.length) {
                        showInlineWarning($conflictRows.first(), msg);
                    } else {
                        showNotice('error', msg);
                    }
                }
                return; // Kaydı blokla
            }

            // --- Devam: Aynı grupta kategori–ürün çatışması + Gruplar arası kapsam çatışması ---
            // Not: categoryOnlyRows, productRows, collectProductIds yukarıda dolduruldu

            // Gruplar arası: tarih çakışan gruplardaki ürünleri de batch'e ekle
            const datesMapForXS = (knsdd_data.data && knsdd_data.data.dates) ? knsdd_data.data.dates : {};
            const myDatesForXS = (datesMapForXS && datesMapForXS[group]) ? datesMapForXS[group] : { start: '', end: '' };
            const parseY = (s) => { if (!s) return null; const [y, m, d] = String(s).split('-').map(Number); return (y && m && d) ? new Date(y, m - 1, d) : null; };
            const rOverlap = (aS, aE, bS, bE) => { if (!aS || !aE || !bS || !bE) return false; const A1 = parseY(aS), A2 = parseY(aE), B1 = parseY(bS), B2 = parseY(bE); if (!A1 || !A2 || !B1 || !B2) return false; A1.setHours(0, 0, 0, 0); A2.setHours(0, 0, 0, 0); B1.setHours(0, 0, 0, 0); B2.setHours(0, 0, 0, 0); return A1 <= B2 && B1 <= A2; };

            // Grup tipi bazlı filtreleme: Sadece aynı tipteki gruplarla çakışma kontrolü
            const myRuleType = (knsdd_data.rule_types && knsdd_data.rule_types[group]) || 'fixed_discount';

            const otherGroups = (knsdd_data.groups || []).filter(g => {
                if (g === group) return false;
                // Farklı tipteki grupları atla (sabit indirim vs özel kampanya)
                const otherRuleType = (knsdd_data.rule_types && knsdd_data.rule_types[g]) || 'fixed_discount';
                if (myRuleType !== otherRuleType) return false;

                // Tamamlanmış kampanyaları atla (performans optimizasyonu)
                // Yeni kampanya bugün veya gelecek tarihli olduğundan çakışma imkansız
                // NOT: Bugün biten kampanyalar kontrol edilmeli (çakışma olabilir)
                const otherDates = knsdd_data.data.dates && knsdd_data.data.dates[g];
                if (otherDates && otherDates.end) {
                    const endDate = parseY(otherDates.end);
                    const today = new Date();
                    today.setHours(0, 0, 0, 0);
                    // Bitiş tarihi bugünden ÖNCE mi? (bugün değil, ÖNCE!)
                    if (endDate && endDate < today) {
                        return false; // Tamamlanmış kampanya
                    }
                }

                // Tarih çakışması kontrolü
                return rOverlap(myDatesForXS.start, myDatesForXS.end, (knsdd_data.data.dates && knsdd_data.data.dates[g] ? knsdd_data.data.dates[g].start : ''), (knsdd_data.data.dates && knsdd_data.data.dates[g] ? knsdd_data.data.dates[g].end : ''));
            });

            const otherRulesByGroup = {};
            otherGroups.forEach(g => { otherRulesByGroup[g] = (knsdd_data.data.rules && knsdd_data.data.rules[g]) || []; });
            const otherGroupCategoryOnly = new Set();
            const otherGroupCategoryRanges = {}; // catId -> [{min,max}]
            const otherGroupProductIds = new Set();
            otherGroups.forEach(g => {
                const arr = otherRulesByGroup[g] || [];
                arr.forEach(r => {
                    if (r && r.rule_type === 'special_campaign' && r.campaign_type === 'cart_total_discount') return;
                    if (r && r.category && (!r.product || r.product.length === 0)) {
                        const catId = parseInt(r.category, 10);
                        otherGroupCategoryOnly.add(catId);
                        // Kategori–kategori aralık çakışması için diğer grupların aralıklarını topla
                        const rng = parseRange(r.min, r.max);
                        if (!otherGroupCategoryRanges[catId]) otherGroupCategoryRanges[catId] = [];
                        otherGroupCategoryRanges[catId].push(rng);
                    }
                    if (r && Array.isArray(r.product)) { r.product.forEach(pid => { const v = parseInt(pid, 10); if (!isNaN(v)) otherGroupProductIds.add(v); }); }
                });
            });
            otherGroupProductIds.forEach(id => collectProductIds.add(id));

            const afterGotMap = (map) => {
                const catSetCurrent = new Set(categoryOnlyRows.map(x => x.category));

                // 1) Aynı grupta kategori–ürün kesişimi
                let conflictFound = false;
                const markRow = ($r) => {
                    $r.addClass('knsdd-row-duplicate');
                };
                productRows.forEach(pr => {
                    const cats = new Set((pr.products || []).flatMap(pid => (map[pid] || [])));
                    for (const c of cats) { if (catSetCurrent.has(parseInt(c, 10))) { conflictFound = true; markRow(pr.$row); break; } }
                });
                if (conflictFound) {
                    // İlk işaretli satıra kenarlık sınıfları ve scroll
                    const $confRows = $rulesTbody.find('tr.knsdd-row-duplicate');
                    if ($confRows.length) { $confRows.first().addClass('knsdd-row-duplicate-start'); $confRows.last().addClass('knsdd-row-duplicate-end'); $('html, body').animate({ scrollTop: $confRows.first().offset().top - 120 }, 300); }
                    const conflictMsg = (knsdd_data.i18n && knsdd_data.i18n.conflict_category_product) ? knsdd_data.i18n.conflict_category_product : 'Kategori–Ürün kural çakışması tespit edildi. Lütfen düzenleyin.';
                    // Ayar kontrolü: satır içi veya üstte göster
                    if (knsdd_data.settings && knsdd_data.settings.warning_location === 'top_notice') {
                        showNotice('error', conflictMsg);
                    } else {
                        // Satır içi: ayarlar sayfasındaki tema ile geçici göster
                        showInlineWarning($confRows.first(), conflictMsg);
                    }
                    return;
                }

                // 2) Gruplar arası kapsam: tarih çakışıyorsa
                let xConflict = false;
                // a) Bizdeki ürünler vs diğer grupların kategori-only seti
                productRows.forEach(pr => {
                    const cats = new Set((pr.products || []).flatMap(pid => (map[pid] || [])));
                    for (const c of cats) { if (otherGroupCategoryOnly.has(parseInt(c, 10))) { xConflict = true; markRow(pr.$row); break; } }
                });
                // b) Bizdeki kategori-only vs diğer grupların ürünleri
                if (!xConflict) {
                    categoryOnlyRows.forEach(cr => {
                        for (const pid of otherGroupProductIds) {
                            const cats = new Set(map[pid] || []);
                            if (cats.has(parseInt(cr.category, 10))) { xConflict = true; markRow(cr.$row); break; }
                        }
                    });
                }
                // c) Kategori–Kategori: aynı kategori ve aralık çakışması
                if (!xConflict) {
                    categoryOnlyRows.forEach(cr => {
                        const catId = parseInt(cr.category, 10);
                        const ranges = otherGroupCategoryRanges[catId] || [];
                        if (ranges.some(rg => rangesOverlapNums(rg, cr.range))) { xConflict = true; markRow(cr.$row); }
                    });
                }

                if (xConflict) {
                    const $confRows = $rulesTbody.find('tr.knsdd-row-duplicate');
                    if ($confRows.length) { $confRows.first().addClass('knsdd-row-duplicate-start'); $confRows.last().addClass('knsdd-row-duplicate-end'); $('html, body').animate({ scrollTop: $confRows.first().offset().top - 120 }, 300); }
                    const conflictMsg2 = (knsdd_data.i18n && knsdd_data.i18n.conflict_category_product) ? knsdd_data.i18n.conflict_category_product : 'Kategori–Ürün kural çakışması tespit edildi. Lütfen düzenleyin.';
                    // Ayar kontrolü: satır içi veya üstte göster
                    if (knsdd_data.settings && knsdd_data.settings.warning_location === 'top_notice') {
                        showNotice('error', conflictMsg2);
                    } else {
                        // Satır içi: ayarlar sayfasındaki tema ile geçici göster
                        showInlineWarning($confRows.first(), conflictMsg2);
                    }
                    return;
                }

                // Çatışma yoksa kayda geç
                proceedSaveFlow(map);
            }; // afterGotMap fonksiyonunun kapanışı

            if (collectProductIds.size === 0) {
                // Ürün yoksa direkt devam
                afterGotMap({});
            } else {
                ajaxRequest('get_product_categories', { product_ids: Array.from(collectProductIds) }, (resp) => {
                    if (!resp || typeof resp !== 'object') {
                        const networkMsg = (knsdd_data.i18n && knsdd_data.i18n.network_error) ? knsdd_data.i18n.network_error : 'Ağ hatası';
                        // Ağ hataları her zaman üstte gösterilsin
                        showNotice('error', networkMsg); return;
                    }
                    const map = resp.map || {};
                    afterGotMap(map);
                });
            }
            return; // Asenkron akış; burada biter
        });

        // --- Tablo içi olaylar (Delegated Events) ---
        $rulesTbody
            .on('click', '.knsdd-delete-rule', function () {
                const $tbody = $(this).closest('tbody');
                $(this).closest('tr').remove();

                // Özel kampanya grubunda kural sayısını kontrol et ve butonu güncelle
                const groupName = $('#knsdd-select-group').val();
                const groupRuleType = knsdd_data.group_rule_types && knsdd_data.group_rule_types[groupName];
                if (groupRuleType === 'special_campaign') {
                    const ruleCount = $tbody.find('tr[data-rule-id]').length;
                    const $addButton = $('#knsdd-add-rule');
                    if (ruleCount === 0) {
                        $addButton.show();
                    } else {
                        $addButton.hide();
                    }
                }
            })
            .on('click', '.knsdd-duplicate-rule', function (e) {
                // Özel kampanyada kopyalama deaktif - event'i tamamen durdur
                if ($(this).prop('disabled') || $(this).hasClass('knsdd-btn-disabled')) {
                    e.preventDefault();
                    e.stopPropagation();
                    return false;
                }

                const groupName = $('#knsdd-select-group').val();
                if (isFreeFixedDiscountLimitReached(groupName, true)) {
                    e.preventDefault();
                    e.stopPropagation();
                    openUpgradePage();
                    if (groupName && KNSDDRules.render.applyGroupRuleTypeRestrictions) {
                        KNSDDRules.render.applyGroupRuleTypeRestrictions(groupName);
                    }
                    return false;
                }

                const $currentRow = $(this).closest('tr');
                const currentData = $currentRow.data('ruleData') || {};

                // Kopyalama için temel verileri oku.
                const newRuleData = {
                    ...currentData, // Başlangıç olarak tüm veriyi kopyala
                    rule_id: undefined, // Yeni kuralın ID'si olmayacak
                    category: $currentRow.find('.knsdd-rule-category').val(),
                    product: $currentRow.find('.knsdd-rule-product').val(),
                    // Görsel/stok şablonlarında tutarlılık için thumb/sku + stok alanlarını da kopyala
                    product_details: ($currentRow.find('.knsdd-rule-product').select2('data') || []).map(d => {
                        // d.* alanları yoksa option data-* üzerinden çek
                        let thumb = d.thumb; let sku = d.sku;
                        let status = d.stock_status; let mstock = d.manage_stock; let qty = d.stock_qty;
                        if (d.element) {
                            const $opt = jQuery(d.element);
                            if (!thumb) thumb = $opt.attr('data-thumb') || '';
                            if (!sku) sku = $opt.attr('data-sku') || '';
                            if (!status) status = $opt.attr('data-stock-status') || '';
                            if (typeof mstock === 'undefined') { const ms = $opt.attr('data-manage-stock'); mstock = (ms === '1' || ms === 'true'); }
                            if (typeof qty === 'undefined') {
                                const q = $opt.attr('data-stock-qty');
                                if (typeof q !== 'undefined') { const n = Number(q); qty = Number.isNaN(n) ? null : n; }
                            }
                        }
                        return ({ id: d.id, name: d.text, thumb: thumb || '', sku: sku || '', stock_status: status || '', manage_stock: !!mstock, stock_qty: (typeof qty === 'number') ? qty : null });
                    }),
                    min: $currentRow.find('.knsdd-rule-min').val(),
                    max: $currentRow.find('.knsdd-rule-max').val(),
                    login_required: $currentRow.find('.knsdd-rule-login-required').is(':checked'),
                    allowed_customers: $currentRow.find('.knsdd-customer-select').val(),
                    allowed_customer_details: ($currentRow.find('.knsdd-customer-select').select2('data') || []).map(d => ({ id: d.id, name: d.text })),
                    rule_type: currentData.rule_type || 'standard_discount',
                    first_order_only: $currentRow.find('.knsdd-rule-first-order').is(':checked')
                };

                // *** DÜZELTME: Sadece standart indirim ise DOM'dan oku. ***
                // Özel kampanyalarda bu alanlar DOM'da olmadığı için, okunursa `undefined` ile
                // `currentData`'dan gelen doğru verinin üzerine yazılır.
                if (newRuleData.rule_type === 'standard_discount') {
                    newRuleData.discount_type = $currentRow.find('.knsdd-rule-discount-type').val();
                    newRuleData.discount_value = $currentRow.find('.knsdd-rule-discount-value').val();
                }

                const $newRow = KNSDDRules.render.ruleRow(newRuleData);
                $currentRow.after($newRow);

                // Yeni satır eklendikten sonra kısıtlamaları tekrar uygula
                if (groupName && KNSDDRules.render.applyGroupRuleTypeRestrictions) {
                    KNSDDRules.render.applyGroupRuleTypeRestrictions(groupName);
                }
            })
            // Artık dropdown yok, kural tipi grup tarafından belirleniyor
            // Kural tipi değiştirilemez (grup oluşturulurken belirlenir)
            .on('click', '.knsdd-limits-rule', function (e) {
                e.preventDefault();
                e.stopPropagation();
                const upgradeUrl = knsdd_data.license.upgrade_url || '#';
                if (upgradeUrl && upgradeUrl !== '#') {
                    window.open(upgradeUrl, '_blank');
                } else {
                    showNotice('warning', knsdd_data.i18n.usage_limits_pro_notice || 'Kullanım limitleri Pro sürümde kullanılabilir.');
                }
                return false;
            })
            .on('click', '.knsdd-configure-campaign-btn', function () {
                KNSDDRules.modals.openCampaignModal($(this).closest('tr'));
            })
            .on('click', '.knsdd-messages-rule', function () {
                KNSDDRules.modals.openMessagesModal($(this).closest('tr'));
            })
            // Kategori değiştiğinde: o kategoriye ait olmayan ürünleri temizle
            .on('change', '.knsdd-rule-category', function () {
                pruneProductsNotInCategory($(this).closest('tr'));
            })
            // Ürün seçimi değiştiğinde: kategori boşsa ortak kategori tekse otomatik doldur
            .on('select2:select select2:unselect', '.knsdd-rule-product', function () {
                try {
                    const cfg = (window.knsdd_data && knsdd_data.settings) ? knsdd_data.settings : {};
                    if (cfg.auto_fill_category_from_products) {
                        autoFillCategoryIfNeeded($(this).closest('tr'));
                    }
                } catch (_e) { }
            });
    };

    /**
     * Sayfayı başlatan ana fonksiyon.
     */
    const init = () => {
        // Modal olaylarını başlat
        KNSDDRules.modals.init();

        // Sayfa olaylarını bağla
        bindEvents();

        // Sayfa ilk yüklendiğinde grupları ve kuralları çiz
        const urlParams = new URLSearchParams(window.location.search);
        const initialGroup = urlParams.get('group');
        KNSDDRules.render.groupOptions(initialGroup, $selectGroup);
        $selectGroup.trigger('change');

        // NOT: autoAddFirstRule özelliği kaldırıldı
        // render.rules() fonksiyonu zaten boş gruplar için otomatik boş satır ekliyor
    };

    // Başlat!
    init();
});
