// script.js

const BRANDS = {
        dailymarket: { name: "دیلی‌مارکت",  icon: "assets/img/dailymarket.png", color: "#2E7D32",  clusterClass: "marker-cluster-dailymarket", defaultChecked: true  },
    okcs:        { name: "افق کوروش",   icon: "assets/img/okcs.png",        color: "#C62828",  clusterClass: "marker-cluster-okcs",        defaultChecked: true  },
    canbo:       { name: "جانبو",       icon: "assets/img/canbo.png",       color: "#000000",  clusterClass: "marker-cluster-canbo",       defaultChecked: false  },
    seven:       { name: "هفت",         icon: "assets/img/seven.png",       color: "#0D47A1",  clusterClass: "marker-cluster-seven",       defaultChecked: false },
    minoo:       { name: "مینو مارت",   icon: "assets/img/minoo.png",       color: "#FF9800",  clusterClass: "marker-cluster-minoo",       defaultChecked: false },
    amiran:      { name: "امیران",      icon: "assets/img/amiran.png",      color: "#B7D82B",  clusterClass: "marker-cluster-amiran",      defaultChecked: false },
    beheshti:    { name: "بهشتی",       icon: "assets/img/beheshti.png",    color: "#FF5900",  clusterClass: "marker-cluster-beheshti",    defaultChecked: false },
      gandom:     { name: "گندم",        icon: "assets/img/gandoom.png",     color: "#70247B",  clusterClass: "marker-cluster-gandoom",     defaultChecked: false },
};



const $ = (selector) => document.querySelector(selector);
const $$ = (selector) => [...document.querySelectorAll(selector)];
const parseNum = (str) => parseFloat((str || "0").toString().replace(/,/g, ''));
const formatNum = (n) => n ? Number(parseNum(n)).toLocaleString() : "0";

const App = {
    map: null,
    layerGroups: {
        circles: null,
        plain: null,
        clusters: {}
    },
    data: {
        daily: {},
        haft: {},  
        allStores: [],
        allMarkers: [],
        filtered: []
    },
state: {
    isClustering: true,
    radius: 250,
    shouldFitBounds: false, 
    filters: {
        brand: 'all',
        state: '',
        county: '',
        supervisor: '',
        traffic_zone: '',
        oddeven_zone: '',
        franchise: '',
        sales_type: 'all'
    }
},


    icons: {},
    ui: {
        loading: $('#loading-overlay'),
        progressBar: $('#progress-bar'),
        progressText: $('#progress-percent'),
        loadingText: $('#loading-text')
    },

    access: {
        role: 'admin',
        area_supervisor_id: null,
        allowedStates: [], 
        user_name: ''
    },

    async init() {
        this.loadAccessConfig();
        this.initIcons();
        this.initMap();
        this.setupEventListeners();
        try {
            await this.loadAllData();
        } catch (e) {
            console.error(e);
            $('#loading-text').textContent = "خطا در اتصال به سرور";
        }
    },

loadAccessConfig() {
    const ua = window.USER_ACCESS || {};
    this.access.role = ua.role || 'admin';
    this.access.area_supervisor_id = ua.area_supervisor_id || null;
    this.access.area_supervisor_ids = ua.area_supervisor_ids || null; // اضافه شد
    this.access.user_name = ua.user_name || '';

    console.log('[Access] Role:', this.access.role,'| Area Supervisor ID:', this.access.area_supervisor_id,
                '| Area Supervisor IDs:', this.access.area_supervisor_ids);
},

    isAdmin() {
        return this.access.role === 'admin';
    },

    isAreaSupervisor() {
        return this.access.role === 'area_supervisor' && this.access.area_supervisor_id;
    },
    isRegionalManager() {
    return this.access.role === 'regional_manager' && this.access.area_supervisor_ids;
    },


    initIcons() {
        Object.keys(BRANDS).forEach(k => {
            this.icons[k] = L.icon({
                iconUrl: BRANDS[k].icon,
                iconSize: [32, 32], iconAnchor: [16, 32], popupAnchor: [0, -32], tooltipAnchor: [0, 0]
            });
        });
        this.icons.default = L.icon({
            iconUrl: "assets/img/marker-icon-2x-blue.png",
            shadowUrl: "assets/img/marker-shadow.png",
            iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41]
        });
    },

    initMap() {
        const config = window.MAP_CONFIG || {};
        this.map = new L.Map("map", {
            key: config.apiKey,
            maptype: "neshan",
            poi: true, traffic: false,
            center: [35.6892, 51.389],
            zoom: 6,
            zoomControl: true,
            zoomSnap: 0,      
            zoomDelta: 0.25 
            
        });
        this.map.attributionControl.setPrefix(false);

        this.layerGroups.circles = L.layerGroup().addTo(this.map);
        this.layerGroups.plain = L.layerGroup();
        
        Object.keys(BRANDS).forEach(key => {
            this.layerGroups.clusters[key] = L.markerClusterGroup({
                maxClusterRadius: 30, spiderfyOnMaxZoom: true, showCoverageOnHover: false, zoomToBoundsOnClick: true, disableClusteringAtZoom: 15,
                iconCreateFunction: (cluster) => new L.DivIcon({
                    html: `<div><span>${cluster.getChildCount()}</span></div>`,
                    className: `marker-cluster ${BRANDS[key].clusterClass}`,
                    iconSize: new L.Point(40, 40),
                })
            }).addTo(this.map);
        });

        this.map.on("moveend zoomend", () => this.updateVisibleStats());
    },

async loadAllData() {
    const config = window.MAP_CONFIG;
    
    this.updateProgress(5, "در حال دریافت داده‌های دیلی...");
    const dailyText = await this.fetchWithProgress(config.dailyCsv, (pct) => this.updateProgress(5 + (pct * 10)));
    this.parseDailyData(dailyText);

    this.updateProgress(15, "در حال دریافت داده‌های هفت...");
    const haftText = await this.fetchWithProgress(config.haftCsv, (pct) => this.updateProgress(15 + (pct * 10)));
    this.parseHaftData(haftText);

    this.updateProgress(25, "در حال دریافت مختصات فروشگاه‌ها...");
    const totalText = await this.fetchWithProgress(config.totalCsv, (pct) => this.updateProgress(25 + (pct * 55)));

    this.updateProgress(85, "در حال پردازش نقاط...");
    setTimeout(() => {
        this.processMarkers(totalText);
        
        this.applyAccessFilter();
        
        this.buildUIControls(); 

        this.updateProgress(100, "تکمیل شد.");
        setTimeout(() => {
            this.ui.loading.style.display = 'none';
            this.fitToAll();
        }, 500);
    }, 100);
},



applyAccessFilter() {
    if (this.isAdmin()) {
        console.log('[Access] Admin mode - no filtering applied');
        return;
    }

    // مدیر ناحیه - چند منطقه
    if (this.isRegionalManager()) {
        const supIds = this.access.area_supervisor_ids;
        console.log('[Access] Filtering for regional_manager with IDs:', supIds);

        const myDailyStores = this.data.allMarkers.filter(m => {
            const d = m.storeData;
            return d.brand === 'dailymarket' && supIds.includes(d.area_supervisor_id);
        });

        this.access.allowedStates = [...new Set(myDailyStores.map(m => m.storeData.state))].filter(Boolean);
        console.log('[Access] Allowed states:', this.access.allowedStates);

        this.data.allMarkers = this.data.allMarkers.filter(m => {
            const d = m.storeData;
            if (d.brand === 'dailymarket') {
                return supIds.includes(d.area_supervisor_id);
            } else {
                return this.access.allowedStates.includes(d.state);
            }
        });

        this.data.allStores = this.data.allStores.filter(row => {
            if (row.brand === 'dailymarket') {
                const daily = this.data.daily[row.store_code?.trim()];
                return daily && supIds.includes(daily.area_supervisor_id);
            } else {
                return this.access.allowedStates.includes(row.state);
            }
        });

        this.data.filtered = [...this.data.allMarkers];
        console.log(`[Access] After filtering: ${this.data.allMarkers.length} markers`);return;
    }

    // مدیر منطقه - یک منطقه
    if (!this.isAreaSupervisor()) return;

    const supId = this.access.area_supervisor_id;
    console.log('[Access] Filtering for area_supervisor_id:', supId);

    const myDailyStores = this.data.allMarkers.filter(m => {
        const d = m.storeData;
        return d.brand === 'dailymarket' && d.area_supervisor_id === supId;
    });

    this.access.allowedStates = [...new Set(myDailyStores.map(m => m.storeData.state))].filter(Boolean);

    this.data.allMarkers = this.data.allMarkers.filter(m => {
        const d = m.storeData;
        
        if (d.brand === 'dailymarket') {
            return d.area_supervisor_id === supId;
        } else {
            return this.access.allowedStates.includes(d.state);
        }
    });

    this.data.allStores = this.data.allStores.filter(row => {
        if (row.brand === 'dailymarket') {
            const daily = this.data.daily[row.store_code?.trim()];
            return daily && daily.area_supervisor_id === supId;
        } else {
            return this.access.allowedStates.includes(row.state);
        }
    });

    this.data.filtered = [...this.data.allMarkers];
},

    async fetchWithProgress(url, onProgress) {
        const response = await fetch(url);
        if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);

        const contentLength = response.headers.get('content-length');
        if (!contentLength) {
            const text = await response.text();
            onProgress(1);
            return text;
        }

        const total = parseInt(contentLength, 10);
        let loaded = 0;
        const reader = response.body.getReader();
        const chunks = [];

        while (true) {
            const { done, value } = await reader.read();
            if (done) break;
            chunks.push(value);
            loaded += value.length;
            onProgress(loaded / total);
        }
        return await new Blob(chunks).text();
    },

    updateProgress(percent, text) {
        const p = Math.min(100, Math.max(0, percent));
        this.ui.progressBar.style.width = `${p}%`;
        this.ui.progressText.textContent = `${Math.round(p)}%`;
        if (text) this.ui.loadingText.textContent = text;
    },

    parseDailyData(csvText) {
        Papa.parse(csvText, {
            header: true, skipEmptyLines: true,
            complete: (results) => {
                (results.data || []).forEach(row => {
                    if (row.store_code) this.data.daily[row.store_code.trim()] = row;
                });
            }
        });
    },
    
    parseHaftData(csvText) {
    Papa.parse(csvText, {
        header: true, skipEmptyLines: true,
        complete: (results) => {
            (results.data || []).forEach(row => {
                if (row.store_code) this.data.haft[row.store_code.trim()] = row;
            });
            console.log('[Haft] Loaded records:', Object.keys(this.data.haft).length);
        }
    });
},


    processMarkers(csvText) {
        Papa.parse(csvText, {
            header: true, skipEmptyLines: true,
            complete: ({ data }) => {
                this.data.allStores = data || [];
                this.data.allMarkers = this.data.allStores.map(row => this.createMarker(row)).filter(Boolean);
                this.data.filtered = [...this.data.allMarkers];
            }
        });
    },

createMarker(row) {
    const lat = parseFloat(row.lat), lng = parseFloat(row.lng);
    if (Number.isNaN(lat) || Number.isNaN(lng)) return null;

    const brandKey = row.brand || "unknown";
    const icon = this.icons[brandKey] || this.icons.default;
    const storeCode = row.store_code ? row.store_code.trim() : "unknown";
    const dailyInfo = (brandKey === 'dailymarket') ? this.data.daily[storeCode] : null;
    const haftInfo  = (brandKey === 'seven')       ? this.data.haft[storeCode]  : null;  // ← اضافه شد

    const marker = L.marker([lat, lng], { icon });

    // Tooltip دیلی‌مارکت
    if (dailyInfo) {
        const sales = (parseNum(dailyInfo.avg_daily_sales) / 10000000).toFixed(1);
        const content = `
            <div class="dt-tooltip">
                <span class="dt-row sales">${sales} <small>م.ت</small></span>
                <span class="dt-row trans">${parseNum(dailyInfo.avg_daily_transactions)} <small>فاکتور</small></span>
                <span class="dt-row basket">${(parseNum(dailyInfo.avg_basket_value)/10).toLocaleString()} <small>سبد</small></span>
            </div>`;
        marker.bindTooltip(content, { permanent: true, direction: 'top', className: 'daily-tooltip-container', offset: [102, -25] });
    }

    // Tooltip هفت  ← اضافه شد
    if (haftInfo) {
        const sales = (parseNum(haftInfo.avg_daily_sales) / 10000000).toFixed(1);
        const content = `
            <div class="dt-tooltip">
                <span class="dt-row sales">${sales} <small>م.ت</small></span>
                <span class="dt-row trans">${parseNum(haftInfo.avg_daily_transactions)} <small>فاکتور</small></span>
                <span class="dt-row basket">${(parseNum(haftInfo.avg_basket_value)).toLocaleString()} <small>سبد</small></span>
            </div>`;
        marker.bindTooltip(content, { permanent: true, direction: 'top', className: 'daily-tooltip-container', offset: [102, -25] });
    }

    const brandName = BRANDS[brandKey]?.name || brandKey;
const neshanLink = `https://nshn.ir/?lat=${lat}&lng=${lng}`;

const popupContent = `
    <div class="popup-content">
        <div class="popup-header">
            ${BRANDS[brandKey] ? `<img src="${BRANDS[brandKey].icon}" width="24">` : ''}
            <strong>${row.store_name || brandName}</strong>
        </div>
        <div class="popup-row"><span>کد:</span> <b>${storeCode}</b></div>
        ${row.state ? `<div class="popup-row"><span>استان:</span> ${row.state}</div>` : ''}
        ${row.county ? `<div class="popup-row"><span>شهرستان:</span> ${row.county}</div>` : ''}
        ${row.city ? `<div class="popup-row"><span>شهر:</span> ${row.city}</div>` : ''}
        ${row.formatted_address ? `<div class="popup-row"><span>آدرس:</span> ${row.formatted_address}</div>` : ''}
        ${dailyInfo ? `<div class="popup-row supervisor"><span>سرپرست:</span> ${dailyInfo.supervisor_name}</div>` : ''}
        ${dailyInfo ? `<div class="popup-row"><span>مدیر منطقه:</span> ${dailyInfo.area_supervisor_name}</div>` : ''}
        <div class="popup-nav-btn">
            <a href="${neshanLink}" target="_blank" rel="noopener noreferrer" class="neshan-nav-link">
                <span>مسیریابی تا فروشگاه</span>
                <img src="assets/neshan/icon.png" alt="نشان" width="20" height="20">
            </a>
        </div>
    </div>
`;


    marker.bindPopup(popupContent);

    marker.storeData = {
        ...row,
        brand: brandKey,
        dailyInfo,
        haftInfo,   // ← اضافه شد
        supervisor_name: dailyInfo ? dailyInfo.supervisor_name : "",
        area_supervisor_name: dailyInfo ? dailyInfo.area_supervisor_name : "",
        area_supervisor_id: dailyInfo ? dailyInfo.area_supervisor_id : "",
        lat, lng
    };

    marker.on('click', () => this.showDailyDetails(dailyInfo));
    return marker;
},


buildUIControls() {
    const brandBox = $('#brand-list');
    brandBox.innerHTML = this.createBrandCheckboxHtml('all', 'همه برندها', true) + 
                         Object.keys(BRANDS).map(b => this.createBrandCheckboxHtml(b, BRANDS[b].name)).join('');

    let states;
    if (this.isAreaSupervisor() || this.isRegionalManager()) {  // ← اضافه شد
        states = [...this.access.allowedStates].sort();
    } else {
        states = [...new Set(this.data.allStores.map(r => r.state))].filter(Boolean).sort();
    }
    this.setupDropdown('state', states);

    this.updateSupervisorOptions();

    $('#radius-slider').addEventListener('input', (e) => {
        const val = parseInt(e.target.value);
        this.state.radius = val;
        $('#radius-value').textContent = val >= 1000 ? (val/1000) + ' کیلومتر' : val + ' متر';
        
        this.layerGroups.circles.eachLayer((layer) => {
            if(layer.setRadius) layer.setRadius(val);
        });
    });

    this.state.shouldFitBounds = true;
    this.applyFilters();
},



    updateSupervisorOptions() {
        const { state, county } = this.state.filters;
        
        const availableMarkers = this.data.allMarkers.filter(m => {
            const d = m.storeData;
            if (d.brand !== 'dailymarket') return false;
            if (state && d.state !== state) return false;
            if (county && d.county !== county) return false;
            return true;
        });

        const supervisors = [...new Set(availableMarkers.map(m => m.storeData.supervisor_name))].filter(Boolean).sort();
        
        const currentSup = this.state.filters.supervisor;
        if (currentSup && !supervisors.includes(currentSup)) {
            this.state.filters.supervisor = '';
            $('#supervisor-search').value = '';
        }

        this.setupDropdown('supervisor', supervisors);
    },

createBrandCheckboxHtml(key, label, isAll = false) {
    let isChecked;
    if (isAll) {
        isChecked = Object.keys(BRANDS).every(b => BRANDS[b].defaultChecked);
    } else {
        isChecked = BRANDS[key]?.defaultChecked !== false; 
    }

    return `
        <div class="brand-checkbox">
            <input type="checkbox" id="brand-${key}" ${isAll ? 'data-all="true"' : ''} ${isChecked ? 'checked' : ''}>
            <label for="brand-${key}">
                ${label}
                ${!isAll && BRANDS[key] ? `<img src="${BRANDS[key].icon}">` : ''}
            </label>
        </div>`;
},


setupDropdown(name, options) {
    const input = $(`#${name}-search`);
    const dropdown = $(`#${name}-dropdown`);
    
    const renderOpts = (list) => {
        dropdown.innerHTML = `<div class="select-option selected" data-value="">همه</div>` +
            list.map(o => `<div class="select-option" data-value="${o}">${o}</div>`).join('');
    };
    renderOpts(options);

    // Clone to clear events
    const newInput = input.cloneNode(true);
    input.parentNode.replaceChild(newInput, input);
    const activeInput = $(`#${name}-search`);

    activeInput.addEventListener('focus', () => {
         $$('.select-dropdown').forEach(d => d.style.display = 'none');
         dropdown.style.display = 'block'; 
    });
    
    activeInput.addEventListener('input', (e) => {
        const val = e.target.value.toLowerCase();
        const filtered = options.filter(o => o.toLowerCase().includes(val));
        renderOpts(filtered);
        dropdown.style.display = 'block';
    });

    dropdown.onclick = (e) => {
        const opt = e.target.closest('.select-option');
        if(!opt) return;
        
        const val = opt.dataset.value;
        activeInput.value = val ? opt.textContent : '';
        this.state.filters[name] = val;
        dropdown.style.display = 'none';

        if (name === 'state') this.handleStateChange(val);
        if (name === 'county') this.updateSupervisorOptions();

        // فیلترهای جغرافیایی → fitBounds بزن
        if (['state', 'county', 'supervisor'].includes(name)) {
            this.state.shouldFitBounds = true;
        }

        this.applyFilters();
    };

    document.addEventListener('click', (e) => {
        if(!e.target.closest('.custom-select')) dropdown.style.display = 'none';
    });
},


    handleStateChange(state) {
        this.state.filters.county = '';
        
        const countyDropdown = $('#county-dropdown');

        if (state) {
            const counties = [...new Set(this.data.allStores.filter(r => r.state === state).map(r => r.county))].sort();
            
            this.setupDropdown('county', counties); 
            
            const newCountyInput = $('#county-search');
            newCountyInput.disabled = false;
            newCountyInput.value = '';
            newCountyInput.placeholder = "انتخاب شهرستان...";
        } else {
            const input = $('#county-search');
            input.disabled = true;
            input.value = '';
            input.placeholder = "ابتدا استان را انتخاب کنید";
            countyDropdown.innerHTML = '';
        }

        this.updateSupervisorOptions();
    },

setupEventListeners() {
    $('#mobile-menu-btn').addEventListener('click', () => $('#sidebar').classList.add('open'));
    $('#close-sidebar').addEventListener('click', () => $('#sidebar').classList.remove('open'));

    $('#brand-list').addEventListener('change', (e) => {
        if (e.target.tagName !== 'INPUT') return;
        const id = e.target.id.replace('brand-', '');
        if (id === 'all') {
            $$('#brand-list input:not([id="brand-all"])').forEach(cb => cb.checked = e.target.checked);
        } else {
            const allChecked = $$('#brand-list input:not([id="brand-all"])').every(cb => cb.checked);
            $('#brand-all').checked = allChecked;
        }
        // تغییر برند → زوم عوض نشه
        this.state.shouldFitBounds = false;
        this.applyFilters();
    });

    $$('input[type=radio]').forEach(r => {
        r.addEventListener('change', () => {
            this.state.filters[r.name] = r.value;
            // رادیو باتن‌ها (طرح ترافیک، زوج و فرد، ...) → زوم عوض نشه
            this.state.shouldFitBounds = false;
            this.applyFilters();
        });
    });

    $('#toggle-cluster-btn').addEventListener('click', (e) => {
        this.state.isClustering = !this.state.isClustering;
        e.target.textContent = this.state.isClustering ? "غیرفعال کردن کلاسترینگ" : "فعال کردن کلاسترینگ";
        e.target.className = `control-btn ${this.state.isClustering ? 'success' : 'warning'}`;
        this.render();
    });

    $('#reset-filters-btn').addEventListener('click', () => this.resetFilters());
    $('#fit-bounds-btn').addEventListener('click', () => this.fitToAll());
},


applyFilters() {
    const f = this.state.filters;
    const allBrandCb = $('#brand-all');
    const checkedBrands = $$('#brand-list input:not([id="brand-all"]):checked').map(cb => cb.id.replace('brand-', ''));
    const brandMode = allBrandCb.checked ? 'all' : checkedBrands;

    this.data.filtered = this.data.allMarkers.filter(m => {
        const d = m.storeData;
        
        if (brandMode !== 'all' && !brandMode.includes(d.brand)) return false;
        
        if (f.state && d.state !== f.state) return false;
        if (f.county && d.county !== f.county) return false;
        if (f.traffic_zone && d.in_traffic_zone !== f.traffic_zone) return false;
        if (f.oddeven_zone && d.in_odd_even_zone !== f.oddeven_zone) return false;
        if (f.franchise && d.is_franchise !== f.franchise) return false;
        
        // Supervisor Filter
        if (f.supervisor) {
            if (d.brand === 'dailymarket' && d.supervisor_name !== f.supervisor) return false;
        }

        // Sales Type
        if (f.sales_type !== 'all' && d.brand === 'dailymarket') {
            const online = parseNum(d.dailyInfo?.online_sales_amount);
            if (f.sales_type === 'online' && online <= 1) return false;
            if (f.sales_type === 'offline' && online > 1) return false;
        }

        return true;
    });

    this.render();
    
    // فقط وقتی fitBounds بزن که صراحتاً درخواست شده
    if (this.state.shouldFitBounds && this.data.filtered.length > 0) {
        let boundsGroup;
        if (f.supervisor) {
            const supervisorStores = this.data.filtered.filter(m => m.storeData.supervisor_name === f.supervisor);
            if (supervisorStores.length > 0) boundsGroup = new L.featureGroup(supervisorStores);
        }
        if (!boundsGroup) boundsGroup = new L.featureGroup(this.data.filtered);

        const maxZoom = this.data.filtered.length > 1000 ? 10 : 15;
        this.map.fitBounds(boundsGroup.getBounds(), { padding: [50, 50], maxZoom: maxZoom });
    }
    
    // بعد از هر بار اعمال، ریست کن
    this.state.shouldFitBounds = false;
},


    render() {
        this.layerGroups.plain.clearLayers();
        this.layerGroups.circles.clearLayers();
        Object.values(this.layerGroups.clusters).forEach(c => c.clearLayers());

        if (this.data.filtered.length === 0) {
            this.updateVisibleStats();
            return;
        }

        if (this.state.isClustering) {
            const categorized = {};
            this.data.filtered.forEach(m => {
                const b = m.storeData.brand;
                if (!categorized[b]) categorized[b] = [];
                categorized[b].push(m);
            });
            Object.keys(categorized).forEach(b => {
                if (this.layerGroups.clusters[b]) this.layerGroups.clusters[b].addLayers(categorized[b]);
            });
        } else {
            this.data.filtered.forEach(m => this.layerGroups.plain.addLayer(m));
            this.map.addLayer(this.layerGroups.plain);
        }

        this.renderCircles();
        this.updateVisibleStats();
    },

    renderCircles() {
        this.layerGroups.circles.clearLayers();
        if (this.data.filtered.length > 10000) return;
        
        this.data.filtered.forEach(m => {
            const color = BRANDS[m.storeData.brand]?.color || "#333";
            const circle = L.circle([m.storeData.lat, m.storeData.lng], {
                radius: this.state.radius,
                color: color, fillColor: color, fillOpacity: 0.1, opacity: 0.4, weight: 1, interactive: false
            });
            this.layerGroups.circles.addLayer(circle);
        });
    },

    updateVisibleStats() {
        const bounds = this.map.getBounds();
        const visible = this.data.filtered.filter(m => bounds.contains([m.storeData.lat, m.storeData.lng]));
        
        const counts = {};
        visible.forEach(m => {
            const b = m.storeData.brand;
            counts[b] = (counts[b] || 0) + 1;
        });

        const sorted = Object.keys(counts).sort((a,b) => counts[b] - counts[a]);
        const total = visible.length;

        let html = sorted.map(k => {
            const pct = total > 0 ? ((counts[k]/total)*100).toFixed(1) : 0;
            return `
                <div class="stat-row">
                    <div class="stat-name">
                        <img src="${BRANDS[k]?.icon}" width="18">
                        <span>${BRANDS[k]?.name}:</span>
                    </div>
                    <div class="stat-val">${counts[k]} <small>(${pct}%)</small></div>
                </div>
            `;
        }).join('');
        
        html += `<div class="stat-total">کل: ${total}</div>`;
        
        if (this.isAreaSupervisor() || this.isRegionalManager()) {  // ← اضافه شد
    html += `<div class="access-info">
        <small>📍 محدوده: ${this.access.allowedStates.join('، ')}</small>
    </div>`;

        }
        
        $('#info-display').innerHTML = html || '<div style="text-align:center;color:#777">موردی یافت نشد</div>';
    },

    showDailyDetails(info) {
        const box = $('#daily-details-box');
        if (!info) {
            box.style.display = 'none';
            return;
        }

        let tpl = document.getElementById('details-template').innerHTML;
        const keys = {
            store_name: info.store_name,
            store_code: info.store_code,
            supervisor_name: info.supervisor_name,
            opening_date: info.opening_date,
            total_sales: formatNum(info.total_sales_amount),
            offline_sales: formatNum(info.offline_sales_amount),
            online_sales: formatNum(info.online_sales_amount),
            avg_daily_sales: formatNum(info.avg_daily_sales),
            avg_daily_sales_offline: formatNum(info.avg_daily_sales_offline),
            avg_daily_sales_online: formatNum(info.avg_daily_sales_online),
            avg_daily_trans: formatNum(info.avg_daily_transactions),
            avg_daily_trans_offline: formatNum(info.avg_daily_transactions_offline),
            avg_daily_trans_online: formatNum(info.avg_daily_transactions_online),
            avg_basket: formatNum(info.avg_basket_value),
            avg_basket_offline: formatNum(info.avg_basket_value_offline),
            avg_basket_online: formatNum(info.avg_basket_value_online),
            rent_amount: formatNum(info.rent_amount),
            rent_pct: parseFloat(info.rent_to_sales_pct).toFixed(2) + '%',
            rent_ratio: parseFloat(info.rent_to_avg_sales_ratio).toFixed(2) + '%'
        };

        Object.keys(keys).forEach(k => {
            tpl = tpl.replace(new RegExp(`{{${k}}}`, 'g'), keys[k] || '-');
        });

        box.innerHTML = tpl;
        box.style.display = 'block';
    },

resetFilters() {
    $$('#brand-list input').forEach(c => {
        const brandKey = c.id.replace('brand-', '');
        if (brandKey === 'all') {
            c.checked = Object.keys(BRANDS).every(b => BRANDS[b].defaultChecked);
        } else if (BRANDS[brandKey]) {
            c.checked = BRANDS[brandKey].defaultChecked !== false;
        }
    });

    $$('.select-search').forEach(i => i.value = '');
    $('#county-search').disabled = true;
    $$('input[type=radio][value=""], input[type=radio][value="all"]').forEach(r => r.checked = true);
    
    $('#radius-slider').value = 250;
    this.state.radius = 250;
    $('#radius-value').textContent = '250 متر';
    this.layerGroups.circles.eachLayer(l => l.setRadius(250));

    $('#daily-details-box').style.display = 'none';
    
    Object.keys(this.state.filters).forEach(k => this.state.filters[k] = (k === 'brand' || k === 'sales_type') ? 'all' : '');
    
    this.updateSupervisorOptions();
    
    // ریست فیلتر → برگرد به نمای کلی
    this.state.shouldFitBounds = true;
    this.applyFilters();
},



    fitToAll() {
        if(this.data.allMarkers.length) {
            const group = new L.featureGroup(this.data.allMarkers);
            this.map.fitBounds(group.getBounds(), { padding: [20, 20] });
        }
    }
};

document.addEventListener("DOMContentLoaded", () => App.init());
