// ============ AUTHENTICATION ============
let currentUser = null;

async function checkAuth() {
    try {
        const response = await fetch('api/get_current_user.php');
        const data = await response.json();
        
        if (data.success && data.user) {
            currentUser = data.user;
            hideLoginForm();
            showUserInfo();
                // Initialize map and the application for existing sessions
                initializeMap();
                initializeApp();
            return true;
        } else {
            showLoginForm();
            return false;
        }
    } catch (error) {
        console.error('Auth check error:', error);
        showLoginForm();
        return false;
    }
}

function showLoginForm() {
    const loginOverlay = document.getElementById('login-overlay');
    const userBar = document.getElementById('user-info-bar');
    const appContainer = document.querySelector('.app-container');
    
    if (loginOverlay) loginOverlay.classList.add('active');
    if (userBar) userBar.style.display = 'none';
    if (appContainer) appContainer.style.display = 'none';
}

function hideLoginForm() {
    const loginOverlay = document.getElementById('login-overlay');
    const userBar = document.getElementById('user-info-bar');
    const appContainer = document.querySelector('.app-container');
    
    if (loginOverlay) loginOverlay.classList.remove('active');
    if (userBar) userBar.style.display = 'flex';
    if (appContainer) appContainer.style.display = 'flex';
}

function showUserInfo() {
    if (!currentUser) return;
    
    const userDisplay = document.getElementById('current-user-display');
    const roleDisplay = document.getElementById('current-role-display');
    
    if (userDisplay) userDisplay.textContent = `Hi, ${currentUser.username}`;
    if (roleDisplay) {
        roleDisplay.textContent = currentUser.role;
        roleDisplay.className = `role-badge role-${currentUser.role.toLowerCase()}`;
    }

    // Update role-based UI elements
    updateAdminUI();
}

async function handleLogin(event) {
    event.preventDefault();
    
    const email = document.getElementById('login-email').value;
    const password = document.getElementById('login-password').value;
    const loginBtn = document.getElementById('login-btn');
    const errorDiv = document.getElementById('login-error');
    
    loginBtn.disabled = true;
    loginBtn.textContent = 'Logging in...';
    errorDiv.classList.remove('show');
    
    try {
        const response = await fetch('api/login.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ email, password })
        });
        
        const data = await response.json();
        
        if (data.success) {
            currentUser = data.user;
            hideLoginForm();
            showUserInfo();
            
            // Reset form
            document.getElementById('login-form').reset();
            
            // Initialize app
            // Ensure the map is initialized for this session
            initializeMap();
            initializeApp();
        } else {
            errorDiv.textContent = data.message || 'Login failed';
            errorDiv.classList.add('show');
        }
    } catch (error) {
        console.error('Login error:', error);
        errorDiv.textContent = 'An error occurred during login';
        errorDiv.classList.add('show');
    } finally {
        loginBtn.disabled = false;
        loginBtn.textContent = 'Login';
    }
}

async function handleLogout() {
    try {
        await fetch('api/logout.php', { method: 'POST' });
        currentUser = null;
        showLoginForm();
        
        // Clear app data
        if (map) {
            map.remove();
            map = null;
        }
    } catch (error) {
        console.error('Logout error:', error);
    }
}

function initializeApp() {
    // Show Beranda tab on startup
    switchTab('beranda');
    
    // Setup modal for all forms
    setupModal();

    // Setup configuration controls
    setupConfigurationSection();

    // Prime the combined report preview so it is ready when Laporan opens
    loadCombinedReportPreview();
}

// ============ GLOBAL STATE ============
let map;
let markers = {};
let markerData = {}; // Store marker data for editing
let markerCount = 0;
let currentMapClickCoords = null;
let currentEditingMarkerId = null;
let markerIcons = {}; // Will be initialized after Leaflet loads
let mapClickMode = 'point';

// Masjid management
let masjidMarkers = {};
let masjidCircles = {};
let masjidData = {};
let masjidCount = 0;
let currentEditingMasjidId = null;

// Special needs point management
let needPointMarkers = {};
let needPointData = {};
let needPointCount = 0;
let currentEditingNeedPointId = null;
// Adaptive rendering state
let allNeedPoints = []; // store normalized records for client-side filtering
let needPointLayer = null; // L.LayerGroup for visible points
let renderingMode = 'auto'; // 'high'|'medium'|'low'
let visibleMarkerThreshold = 1000; // will be adjusted based on device

function getStoredRenderingMode() {
    try { return localStorage.getItem('renderingMode'); } catch (e) { return null; }
}

function setStoredRenderingMode(mode) {
    try {
        if (!mode) localStorage.removeItem('renderingMode');
        else localStorage.setItem('renderingMode', mode);
    } catch (e) {
        // ignore
    }
}

// Household/Assistance/Verification (Phase A)
let households = [];
let householdSummary = null;

// Lines/Roads Management
let lines = {};
let lineData = {};
let lineCount = 0;

// Polygons/Land Parcels Management
let polygons = {};
let polygonData = {};
let polygonCount = 0;

// Drawing state
let drawMode = {
    active: false,
    type: null,  // 'line' or 'polygon'
    coordinates: [],
    temporaryLayer: null,
    defaultClickHandler: null,
    tempMarkers: []  // Store temporary circle markers
};

// Search/Filter state
let filterState = {
    roads: { search: '', dateFrom: '', dateTo: '', condition: '' },
    parcels: { search: '', dateFrom: '', dateTo: '', certificate: '' }
};

// Pontianak choropleth state
let pontianakState = {
    active: false,
    adminLevel: 'kecamatan',
    currentLayers: {        // NEW: Multiple layers can be visible simultaneously
        population: false,
        road_density: false,
        damaged_roads_density: false,
        city_boundary: false
    },
    layers: {},             // RENAMED from areas: layerType -> array of Leaflet GeoJSON layers
    colorScales: {},        // NEW: Store color scale for each layer type
    legendData: null,
    areasData: {},          // Administrative areas data
    dataLoaded: false,      // NEW: Flag to prevent re-fetching
    hasFittedBoundary: false
};

// Search input debounce timers
let searchTimeouts = {
    roads: null,
    parcels: null
};

// Color styles for roads and polygons
const lineStyles = {
    'Nasional': {
        color: '#4CAF50',      // Green
        weight: 4,
        opacity: 0.8,
        dashArray: null,
        lineCap: 'round',
        lineJoin: 'round'
    },
    'Provinsi': {
        color: '#2196F3',      // Blue
        weight: 3.5,
        opacity: 0.8,
        dashArray: null,
        lineCap: 'round',
        lineJoin: 'round'
    },
    'Kabupaten': {
        color: '#FF9800',      // Orange
        weight: 3,
        opacity: 0.8,
        dashArray: null,
        lineCap: 'round',
        lineJoin: 'round'
    }
};

const polygonStyles = {
    'SHM': {
        fillColor: '#4CAF50',  // Green
        weight: 2,
        opacity: 0.8,
        color: '#2E7D32',
        fillOpacity: 0.3,
        dashArray: null
    },
    'HGB': {
        fillColor: '#2196F3',  // Blue
        weight: 2,
        opacity: 0.8,
        color: '#1565C0',
        fillOpacity: 0.3,
        dashArray: null
    },
    'HGU': {
        fillColor: '#FF9800',  // Orange
        weight: 2,
        opacity: 0.8,
        color: '#E65100',
        fillOpacity: 0.3,
        dashArray: null
    },
    'HP': {
        fillColor: '#9C27B0',  // Purple
        weight: 2,
        opacity: 0.8,
        color: '#6A1B9A',
        fillOpacity: 0.3,
        dashArray: null
    }
};

// Initialize on page load
document.addEventListener('DOMContentLoaded', function() {
    checkAuth();
});

function initializeMap() {
    if (map) return; // Map already initialized
    initMap();
}

function setupModal() {
    const modal = document.getElementById('point-modal');
    const addBtn = document.getElementById('add-point-btn');
    const addMasjidBtn = document.getElementById('add-masjid-btn');
    const addNeedPointBtn = document.getElementById('add-need-point-btn');
    const addHouseholdBtn = document.getElementById('add-household-btn');
    const addAssistanceBtn = document.getElementById('add-assistance-btn');
    const addVerificationBtn = document.getElementById('add-verification-btn');
    const computeScoresBtn = document.getElementById('compute-household-scores-btn');
    const closeBtn = document.querySelector('.close');
    const form = document.getElementById('point-form');
    const mapClickModeSelect = document.getElementById('map-click-mode');
    const householdFilterStatus = document.getElementById('household-filter-status');

    if (addBtn) {
        addBtn.onclick = function() {
            openPointModal(null);
        }
    }

    if (addMasjidBtn) {
        addMasjidBtn.onclick = function() {
            openMasjidModal(null);
        }
    }

    if (addNeedPointBtn) {
        addNeedPointBtn.onclick = function() {
            openNeedPointModal(null);
        }
    }

    if (addHouseholdBtn) {
        addHouseholdBtn.onclick = function() {
            openHouseholdModal();
        }
    }

    if (addAssistanceBtn) {
        addAssistanceBtn.onclick = function() {
            openAssistanceModal();
        }
    }

    if (addVerificationBtn) {
        addVerificationBtn.onclick = function() {
            openVerificationModal();
        }
    }

    if (computeScoresBtn) {
        computeScoresBtn.onclick = function() {
            computeHouseholdScores();
        }
    }

    // Wire existing select if present (legacy); we also add map shortcut buttons
    if (mapClickModeSelect) {
        mapClickModeSelect.value = mapClickMode;
        mapClickModeSelect.onchange = function(event) {
            setMapClickMode(event.target.value, false);
        }
    }

    // Map shortcut buttons (overlay)
    function setupMapShortcuts() {
        const shortcuts = [
            { id: 'shortcut-point', mode: 'point' },
            { id: 'shortcut-masjid', mode: 'masjid' },
            { id: 'shortcut-need', mode: 'need' },
            { id: 'shortcut-line', mode: 'line' },
            { id: 'shortcut-polygon', mode: 'polygon' }
        ];

        shortcuts.forEach(s => {
            const el = document.getElementById(s.id);
            if (!el) return;
            el.onclick = function() {
                setMapClickMode(s.mode);
                updateShortcutButtons();
            };
        });

        // Reflect current mode on buttons
        function updateShortcutButtons() {
            const current = (mapClickMode === 'need' || mapClickMode === 'need_point') ? 'need' : mapClickMode;
            shortcuts.forEach(s => {
                const el = document.getElementById(s.id);
                if (!el) return;
                if (current === s.mode) {
                    el.classList.add('active');
                } else {
                    el.classList.remove('active');
                }
            });
        }

        // Expose updater so other parts can refresh visuals
        window.updateShortcutButtons = updateShortcutButtons;
        // initial reflect
        updateShortcutButtons();
    }

    setupMapShortcuts();

    // Wire additional map tool buttons if present
    const addLineBtn = document.getElementById('add-line-btn');
    const addPolygonBtn = document.getElementById('add-polygon-btn');
    if (addLineBtn) addLineBtn.onclick = function() { enableLineDrawMode(); };
    if (addPolygonBtn) addPolygonBtn.onclick = function() { enablePolygonDrawMode(); };

    if (householdFilterStatus) {
        householdFilterStatus.onchange = function() {
            loadHouseholdsForPanel();
        }
    }

    if (closeBtn) {
        closeBtn.onclick = function() {
            closePointModal();
        }
    }

    window.onclick = function(event) {
        if (event.target === modal) {
            closePointModal();
        }
        const editModal = document.getElementById('edit-modal');
        if (event.target === editModal) {
            closeEditModal();
        }
        const lineModal = document.getElementById('line-modal');
        if (event.target === lineModal) {
            closeLineModal();
        }
        const editLineModal = document.getElementById('edit-line-modal');
        if (event.target === editLineModal) {
            closeEditLineModal();
        }
        const polygonModal = document.getElementById('polygon-modal');
        if (event.target === polygonModal) {
            closePolygonModal();
        }
        const editPolygonModal = document.getElementById('edit-polygon-modal');
        if (event.target === editPolygonModal) {
            closeEditPolygonModal();
        }

        const masjidModal = document.getElementById('masjid-modal');
        if (event.target === masjidModal) {
            closeMasjidModal();
        }

        const editMasjidModal = document.getElementById('edit-masjid-modal');
        if (event.target === editMasjidModal) {
            closeEditMasjidModal();
        }

        const needPointModal = document.getElementById('need-point-modal');
        if (event.target === needPointModal) {
            closeNeedPointModal();
        }

        const editNeedPointModal = document.getElementById('edit-need-point-modal');
        if (event.target === editNeedPointModal) {
            closeEditNeedPointModal();
        }

        const householdModal = document.getElementById('household-modal');
        if (event.target === householdModal) {
            closeHouseholdModal();
        }

        const assistanceModal = document.getElementById('assistance-modal');
        if (event.target === assistanceModal) {
            closeAssistanceModal();
        }

        const verificationModal = document.getElementById('verification-modal');
        if (event.target === verificationModal) {
            closeVerificationModal();
        }
    }

    if (form) {
        form.onsubmit = function(e) {
            e.preventDefault();
            submitPointForm();
        }
    }

    // Setup edit modal form
    const editForm = document.getElementById('edit-form');
    if (editForm) {
        editForm.onsubmit = function(e) {
            e.preventDefault();
            saveMarkerEdit();
        }
    }

    const masjidForm = document.getElementById('masjid-form');
    if (masjidForm) {
        masjidForm.onsubmit = function(e) {
            e.preventDefault();
            submitMasjidForm();
        }
    }

    const editMasjidForm = document.getElementById('edit-masjid-form');
    if (editMasjidForm) {
        editMasjidForm.onsubmit = function(e) {
            e.preventDefault();
            saveMasjidEdit();
        }
    }

    const needPointForm = document.getElementById('need-point-form');
    if (needPointForm) {
        needPointForm.onsubmit = function(e) {
            e.preventDefault();
            submitNeedPointForm();
        }
    }

    const editNeedPointForm = document.getElementById('edit-need-point-form');
    if (editNeedPointForm) {
        editNeedPointForm.onsubmit = function(e) {
            e.preventDefault();
            saveNeedPointEdit();
        }
    }

    const householdForm = document.getElementById('household-form');
    if (householdForm) {
        householdForm.onsubmit = function(e) {
            e.preventDefault();
            submitHouseholdForm();
        }
    }

    const assistanceForm = document.getElementById('assistance-form');
    if (assistanceForm) {
        assistanceForm.onsubmit = function(e) {
            e.preventDefault();
            submitAssistanceForm();
        }
    }

    const assistanceHouseholdSelect = document.getElementById('assistance-household-id');
    if (assistanceHouseholdSelect) {
        assistanceHouseholdSelect.onchange = function() {
            updateAssistanceModalSummary();
        };
    }

    const verificationForm = document.getElementById('verification-form');
    if (verificationForm) {
        verificationForm.onsubmit = function(e) {
            e.preventDefault();
            submitVerificationForm();
        }
    }
}

// ============ TAB MANAGEMENT ============

function switchTab(tabName, clickedButton = null) {
    if (!isTabAllowedForCurrentUser(tabName)) {
        showNotification('Akses tab ini tidak tersedia untuk peran Anda', true);
        tabName = 'beranda';
        clickedButton = null;
    }

    // Hide all tab contents
    const tabContents = document.querySelectorAll('.tab-content');
    tabContents.forEach(tab => {
        tab.classList.remove('tab-active');
    });

    // Remove active class from all buttons
    const tabButtons = document.querySelectorAll('.tab-button');
    tabButtons.forEach(btn => {
        btn.classList.remove('tab-active');
    });

    // Get the selected tab element
    const selectedTab = document.getElementById(tabName + '-tab');
    if (selectedTab) {
        // MOVE TAB TO MAIN CONTENT AREA (NEW LAYOUT)
        const mainContent = document.querySelector('.main-content');
        if (mainContent) {
            // Remove all existing tab-content from main (they will be moved back to sidebar when hidden)
            const existingTabs = mainContent.querySelectorAll('.tab-content');
            existingTabs.forEach(tab => {
                // Move back to sidebar (to maintain DOM structure)
                const sidebar = document.querySelector('.sidebar');
                if (sidebar) {
                    sidebar.appendChild(tab);
                }
            });

            // Add selected tab to main content
            selectedTab.classList.add('tab-active');
            mainContent.appendChild(selectedTab);
        } else {
            // Fallback: just show the tab (for old layout compatibility)
            selectedTab.classList.add('tab-active');
        }
    }

    // Set active button (supports both click and programmatic calls)
    let activeButton = clickedButton;
    if (!activeButton) {
        activeButton = Array.from(tabButtons).find(btn => {
            const handler = btn.getAttribute('onclick') || '';
            return handler.includes(`'${tabName}'`) || handler.includes(`"${tabName}"`);
        });
    }

    if (activeButton) {
        activeButton.classList.add('tab-active');
    }

    // Special handling for Beranda tab (home/dashboard)
    if (tabName === 'beranda') {
        loadBerandaDashboard();
        return;
    }

    // Special handling for Peta tab (map)
    if (tabName === 'peta') {
        // Move map into peta-tab container for proper display
        const mapContainer = document.getElementById('peta-map-container');
        const mapElement = document.getElementById('map');
        if (mapContainer && mapElement && mapElement.parentElement !== mapContainer) {
            mapContainer.appendChild(mapElement);
            mapContainer.style.display = 'block';
            // Reinitialize map in new container. Give the layout
            // a bit more time to settle, then force a resize and
            // refresh the view so tiles render correctly.
            if (map) {
                setTimeout(() => {
                    try {
                        map.invalidateSize();
                        map.invalidateSize(true);
                        // re-center to current center to force redraw
                        const c = map.getCenter();
                        map.setView([c.lat, c.lng]);
                    } catch (e) {
                        console.warn('Map resize error', e);
                    }
                }, 300);
            }
        }
        
        loadMarkers();
        loadMasjids();
        loadNeedPoints();
        loadLines();
        loadPolygons();
        loadHouseholdsForPanel();
        loadHouseholdSummary();
        loadHouseholdScoreSummary();
        loadHouseholdPriorityRanking();
        return;
    }

    // Special handling for Managemen tab
    if (tabName === 'managemen') {
        loadManagement();
        return;
    }

    // Special handling for Laporan tab (reports)
    if (tabName === 'laporan') {
        loadCombinedReportPreview();
        return;
    }

    // Special handling for Dashboard tab
    if (tabName === 'dashboard') {
        loadDashboard();
        return;
    }

    // Special handling for Users tab (admin only)
    if (tabName === 'users') {
        if (!currentUser || currentUser.role !== 'Admin') {
            showNotification('Only admins can access this section', true);
            return;
        }
        loadUsersList();
        return;
    }

    // Special handling for Configuration tab (admin only)
    if (tabName === 'konfigurasi') {
        if (!currentUser || currentUser.role !== 'Admin') {
            showNotification('Only admins can access this section', true);
            return;
        }
        loadConfiguration();
        return;
    }

    // Special handling for Pontianak tab
    if (tabName === 'pontianak') {
        // Clear other features
        Object.keys(markers).forEach(id => {
            if (map.hasLayer(markers[id])) map.removeLayer(markers[id]);
        });
        Object.keys(masjidMarkers).forEach(id => {
            if (map.hasLayer(masjidMarkers[id])) map.removeLayer(masjidMarkers[id]);
        });
        Object.keys(masjidCircles).forEach(id => {
            if (map.hasLayer(masjidCircles[id])) map.removeLayer(masjidCircles[id]);
        });
        Object.keys(needPointMarkers).forEach(id => {
            if (map.hasLayer(needPointMarkers[id])) map.removeLayer(needPointMarkers[id]);
        });
        Object.keys(lines).forEach(id => {
            if (map.hasLayer(lines[id])) map.removeLayer(lines[id]);
        });
        Object.keys(polygons).forEach(id => {
            if (map.hasLayer(polygons[id])) map.removeLayer(polygons[id]);
        });

        pontianakState.active = true;
        if (!pontianakState.hasFittedBoundary) {
            map.setView([-0.0263, 109.3425], 12);
        }
        initPontianakMap();
    } else {
        // Unload Pontianak features and reset state
        Object.keys(pontianakState.layers).forEach(layerType => {
            if (pontianakState.layers[layerType]) {
                pontianakState.layers[layerType].forEach(layer => {
                    if (map.hasLayer(layer)) map.removeLayer(layer);
                });
            }
        });
        pontianakState.layers = {};
        pontianakState.areasData = {};
        pontianakState.dataLoaded = false;
        pontianakState.hasFittedBoundary = false;
        pontianakState.active = false;

        // Reload regular features if this is one of the main tabs
        if (tabName === 'points' || tabName === 'peta' || tabName === 'roads' || tabName === 'parcels') {
            loadMarkers();
            loadMasjids();
            loadNeedPoints();
            loadLines();
            loadPolygons();

            if (tabName === 'points' || tabName === 'peta') {
                loadHouseholdsForPanel();
                loadHouseholdSummary();
                loadHouseholdScoreSummary();
                loadHouseholdPriorityRanking();
            }
        }
    }
}

function setMapClickMode(mode, showToast = true) {
    // Normalize mode values (support legacy 'need_point')
    function normalizeMode(m) {
        if (!m) return m;
        if (m === 'need_point') return 'need';
        return m;
    }

    // Accept drawing modes as well
    const validModes = ['point', 'masjid', 'need', 'line', 'polygon'];
    const normalized = normalizeMode(mode);
    if (!validModes.includes(normalized)) return;

    // If switching from an active draw mode, cancel any drawing first
    if (drawMode.active && (mode !== 'line' && mode !== 'polygon')) {
        cancelDrawing();
    }

    mapClickMode = normalized;
    const modeSelect = document.getElementById('map-click-mode');
    if (modeSelect && modeSelect.value !== normalized) modeSelect.value = normalized;

    if (showToast) {
        const modeLabels = {
            point: 'Point Biasa',
            masjid: 'Masjid',
            need: 'Point Berkebutuhan',
            line: 'Gambar Jalan (Draw Road)',
            polygon: 'Gambar Parcel (Draw Polygon)'
        };
        showNotification('Mode peta: ' + (modeLabels[mode] || mode));
    }

    // If user selected drawing modes via the select, activate draw mode
    if (normalized === 'line') {
        enableLineDrawMode();
    } else if (normalized === 'polygon') {
        enablePolygonDrawMode();
    } else {
        // restore default click handler
        if (drawMode.defaultClickHandler) {
            map.off('click', handleMapClickDuringDraw);
            map.on('click', drawMode.defaultClickHandler);
        }
    }
}
    // Update shortcut button visuals if present
    if (window.updateShortcutButtons && typeof window.updateShortcutButtons === 'function') {
        window.updateShortcutButtons();
    }


function openPointModal(coords) {
    const modal = document.getElementById('point-modal');
    const form = document.getElementById('point-form');
    const latInput = document.getElementById('point-latitude');
    const lngInput = document.getElementById('point-longitude');
    const nameInput = document.getElementById('point-name');
    const formInfo = document.getElementById('form-info');
    const modalTitle = document.getElementById('modal-title');

    form.reset();
    currentMapClickCoords = coords;

    if (coords) {
        latInput.value = coords.lat.toFixed(6);
        lngInput.value = coords.lng.toFixed(6);
        latInput.readOnly = true;
        lngInput.readOnly = true;
        modalTitle.textContent = 'Create Point';
        formInfo.textContent = '✓ Coordinates auto-filled from map click. Just add a name!';
        formInfo.classList.add('show');
        nameInput.focus();
    } else {
        latInput.value = '';
        lngInput.value = '';
        latInput.readOnly = false;
        lngInput.readOnly = false;
        modalTitle.textContent = 'Add New Point';
        formInfo.classList.remove('show');
        nameInput.focus();
    }

    modal.classList.add('show');
}

function closePointModal() {
    const modal = document.getElementById('point-modal');
    modal.classList.remove('show');
    currentMapClickCoords = null;
}

function submitPointForm() {
    const name = document.getElementById('point-name').value.trim();
    const nomor_spbu = document.getElementById('point-nomor-spbu').value.trim();
    const latitude = parseFloat(document.getElementById('point-latitude').value);
    const longitude = parseFloat(document.getElementById('point-longitude').value);
    const open_24_hours = document.getElementById('point-24hours').checked ? 1 : 0;

    // Validate inputs
    if (!name) {
        showNotification('Please enter a name for the point', true);
        return;
    }

    if (isNaN(latitude) || latitude < -90 || latitude > 90) {
        showNotification('Please enter a valid latitude (-90 to 90)', true);
        return;
    }

    if (isNaN(longitude) || longitude < -180 || longitude > 180) {
        showNotification('Please enter a valid longitude (-180 to 180)', true);
        return;
    }

    addMarker(name, nomor_spbu, latitude, longitude, open_24_hours);
}

function initMap() {
    // Create map centered on Pontianak by default
    map = L.map('map').setView([-0.0263, 109.3425], 13);

    // Initialize marker icons after Leaflet is loaded
    markerIcons.open = L.divIcon({
        html: `<div style="background-color: #4CAF50; width: 30px; height: 30px; border-radius: 50%; border: 3px solid white; box-shadow: 0 2px 5px rgba(0,0,0,0.3); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 16px;">✓</div>`,
        iconSize: [36, 36],
        iconAnchor: [18, 36],
        popupAnchor: [0, -36],
        className: 'custom-marker open'
    });

    markerIcons.closed = L.divIcon({
        html: `<div style="background-color: #f44336; width: 30px; height: 30px; border-radius: 50%; border: 3px solid white; box-shadow: 0 2px 5px rgba(0,0,0,0.3); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 16px;">✕</div>`,
        iconSize: [36, 36],
        iconAnchor: [18, 36],
        popupAnchor: [0, -36],
        className: 'custom-marker closed'
    });

    markerIcons.masjid = L.divIcon({
        html: `<div style="background-color: #1976d2; width: 32px; height: 32px; border-radius: 50%; border: 3px solid white; box-shadow: 0 2px 5px rgba(0,0,0,0.3); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 15px;">M</div>`,
        iconSize: [38, 38],
        iconAnchor: [19, 38],
        popupAnchor: [0, -36],
        className: 'custom-marker masjid'
    });

    markerIcons.need = L.divIcon({
        html: `<div style="background-color: #ff9800; width: 30px; height: 30px; border-radius: 50%; border: 3px solid white; box-shadow: 0 2px 5px rgba(0,0,0,0.3); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 14px;">K</div>`,
        iconSize: [36, 36],
        iconAnchor: [18, 36],
        popupAnchor: [0, -36],
        className: 'custom-marker need'
    });

    // Add OpenStreetMap tile layer
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap contributors',
        maxZoom: 19
    }).addTo(map);

    // Store default click handler
    drawMode.defaultClickHandler = function(e) {
        if (!drawMode.active) {
            const coords = {
                lat: e.latlng.lat,
                lng: e.latlng.lng
            };

            if (mapClickMode === 'masjid') {
                openMasjidModal(coords);
            } else if (mapClickMode === 'need') {
                openNeedPointModal(coords);
            } else {
                openPointModal(coords);
            }
        }
    };

    // Handle map click to add marker with auto-filled coordinates
    map.on('click', drawMode.defaultClickHandler);
}

function addMarker(name, nomor_spbu, lat, lng, open_24_hours) {
    // Save to database
    fetch('api/save_point.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            name: name,
            nomor_spbu: nomor_spbu,
            latitude: lat,
            longitude: lng,
            open_24_hours: open_24_hours
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            displayMarker(data.id, data.name, data.nomor_spbu, data.latitude, data.longitude, data.open_24_hours);
            updateMarkerCount();
            showNotification('✓ Point added successfully');
            closePointModal();
        } else {
            showNotification('Error adding point: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error adding point', true);
    });
}

function displayMarker(id, name, nomor_spbu, lat, lng, open_24_hours) {
    // Store marker data for editing
    markerData[id] = {
        id: id,
        name: name,
        nomor_spbu: nomor_spbu,
        latitude: lat,
        longitude: lng,
        open_24_hours: open_24_hours
    };

    // Use colored icon based on status
    const icon = open_24_hours ? markerIcons.open : markerIcons.closed;
    const marker = L.marker([lat, lng], { draggable: true, icon: icon }).addTo(map);

    const updateMarkerPopup = (newLat, newLng) => {
        const hoursText = open_24_hours ? '🕐 Open 24 Hours' : '🕐 Limited Hours';
        let popupContent = `
            <div class="marker-popup">
                <div class="marker-popup-name">${escapeHtml(name)}</div>
                <div class="marker-popup-hours">${hoursText}</div>`;

        if (nomor_spbu) {
            popupContent += `<div class="marker-popup-spbu">🏢 SPBU: ${escapeHtml(nomor_spbu)}</div>`;
        }

        popupContent += `
                <div class="marker-popup-info">
                    <span>Lat: ${newLat.toFixed(4)}</span><br>
                    <span>Lng: ${newLng.toFixed(4)}</span>
                </div>
                <div class="marker-popup-actions">
                    <button type="button" onclick="toggleMarkerStatus(${id})">Toggle Status</button>
                    <button type="button" onclick="editMarker(${id})">Edit</button>
                    <button type="button" onclick="deleteMarker(${id})">Delete</button>
                </div>
            </div>
        `;
        marker.setPopupContent(popupContent);
    };

    updateMarkerPopup(lat, lng);
    marker.bindPopup();

    // Handle marker drag
    marker.on('dragend', function() {
        const newLat = marker.getLatLng().lat;
        const newLng = marker.getLatLng().lng;

        // Update in database
        fetch('api/update_point.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                id: id,
                latitude: newLat,
                longitude: newLng
            })
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                updateMarkerPopup(newLat, newLng);
                // Update markerData with new coordinates
                markerData[id].latitude = newLat;
                markerData[id].longitude = newLng;
                // Reopen popup to show updated coordinates
                marker.closePopup();
                marker.openPopup();
                showNotification('✓ Point location updated');
            } else {
                // Revert to old position if update failed
                marker.setLatLng([lat, lng]);
                showNotification('Error updating point location', true);
            }
        })
        .catch(error => {
            console.error('Error:', error);
            marker.setLatLng([lat, lng]);
            showNotification('Error updating point location', true);
        });
    });

    // Store marker and update reference
    markers[id] = marker;
    markerCount++;
}

// ============ BERANDA DASHBOARD ============
function loadBerandaDashboard() {
    Promise.all([
        fetch('api/get_need_points.php').then(response => response.json()),
        fetch('api/get_configuration.php').then(response => response.json()),
        fetch('api/get_dashboard_summary.php').then(response => response.json())
    ])
        .then(([needPointData, configurationData, dashboardData]) => {
            const totalNeedPoints = needPointData?.success && Array.isArray(needPointData.points)
                ? needPointData.points.length
                : 0;
            const populationReference = configurationData?.success
                ? Number(configurationData.configuration?.population_reference || 288315899)
                : 288315899;
            const povertyPercentage = populationReference > 0
                ? (totalNeedPoints / populationReference) * 100
                : 0;
            const targetNasional = configurationData?.success
                ? Number(configurationData.configuration?.target_nasional || 7.50)
                : 7.50;

            document.getElementById('beranda-total-poor').textContent = totalNeedPoints.toLocaleString('id-ID');
            document.getElementById('beranda-percentage').textContent = povertyPercentage.toFixed(6);
            document.getElementById('beranda-target').textContent = targetNasional.toFixed(2);

            if (dashboardData?.success) {
                updateReportSummary(dashboardData.summary);
            }
        })
        .catch(error => console.error('Error loading beranda dashboard:', error));

    // Load regional data
    fetch('api/get_area_breakdown.php')
        .then(response => response.json())
        .then(data => {
            if (data.success && Array.isArray(data.areas)) {
                renderBerandaRegions(data.areas.slice(0, 5));
            }
        })
        .catch(error => console.error('Error loading area breakdown:', error));

    // Load trend chart data
    loadTrendChart();
}

function renderBerandaRegions(areas) {
    const regionList = document.getElementById('beranda-region-list');
    if (!regionList) return;

    if (!Array.isArray(areas) || areas.length === 0) {
        regionList.innerHTML = `
            <div style="background: rgba(255,255,255,0.08); padding: 12px; border-radius: 6px; font-size: 11px; color: rgba(255,255,255,0.75);">
                Belum ada data provinsi yang tersedia.
            </div>
        `;
        return;
    }

    regionList.innerHTML = areas.map((area, index) => `
        <div style="background: rgba(255,255,255,0.08); padding: 10px 12px; border-radius: 6px; font-size: 11px; display: flex; justify-content: space-between; align-items: center; gap: 10px;">
            <span style="color: white;"><strong>${index + 1}. ${area.area_name || 'N/A'}</strong></span>
            <span style="color: rgba(255,255,255,0.75); white-space: nowrap;">${Number(area.household_count || 0).toLocaleString('id-ID')} titik kebutuhan</span>
        </div>
    `).join('');
}

// Load and render trend charts
function loadTrendChart() {
    fetch('api/get_dashboard_trend.php')
        .then(response => response.json())
        .then(data => {
            if (data.success && data.charts) {
                renderTrendCharts(data);
            }
        })
        .catch(error => console.error('Error loading trend data:', error));
}

// Render two Chart.js comparison charts: population totals and poverty percentage
function renderTrendCharts(data) {
    const populationCanvas = document.getElementById('populationChart');
    const populationPlaceholder = document.getElementById('populationChartPlaceholder');
    const percentageCanvas = document.getElementById('percentageChart');
    const percentagePlaceholder = document.getElementById('percentageChartPlaceholder');
    
    if (!populationCanvas || !percentageCanvas || typeof Chart === 'undefined') return;

    // Show canvases and hide placeholders
    populationCanvas.style.display = 'block';
    if (populationPlaceholder) populationPlaceholder.style.display = 'none';
    percentageCanvas.style.display = 'block';
    if (percentagePlaceholder) percentagePlaceholder.style.display = 'none';

    // Destroy existing charts if they exist
    if (window.populationChartInstance) {
        window.populationChartInstance.destroy();
    }
    if (window.percentageChartInstance) {
        window.percentageChartInstance.destroy();
    }

    // CHART 1: Bar chart for absolute population totals
    const chart1Data = data.charts.chart1;
    const popCtx = populationCanvas.getContext('2d');
    
    window.populationChartInstance = new Chart(popCtx, {
        type: 'bar',
        data: {
            labels: chart1Data.labels,
            datasets: [{
                data: chart1Data.data,
                backgroundColor: [
                    '#FF6B6B',
                    '#4ECDC4'
                ],
                borderColor: [
                    '#ff5252',
                    '#45b8ad'
                ],
                borderWidth: 2
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: true,
            plugins: {
                legend: {
                    display: false,
                    labels: {
                        color: '#fff',
                        font: { size: 12 },
                        padding: 15
                    }
                },
                tooltip: {
                    callbacks: {
                        label: function(context) {
                            return context.label + ': ' + formatPopulationValue(context.parsed && typeof context.parsed === 'object' ? context.parsed.y : context.parsed);
                        }
                    },
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    titleColor: '#fff',
                    bodyColor: '#fff'
                }
            },
            scales: {
                x: {
                    ticks: {
                        color: '#fff'
                    },
                    grid: {
                        color: 'rgba(255,255,255,0.12)'
                    }
                },
                y: {
                    beginAtZero: true,
                    ticks: {
                        color: '#fff',
                        callback: function(value) {
                            return formatPopulationAxisValue(value);
                        }
                    },
                    grid: {
                        color: 'rgba(255,255,255,0.12)'
                    }
                }
            }
        }
    });

    // CHART 2: Bar chart for poverty percentage vs target
    const chart2Data = data.charts.chart2;
    const pctCtx = percentageCanvas.getContext('2d');
    
    window.percentageChartInstance = new Chart(pctCtx, {
        type: 'bar',
        data: {
            labels: chart2Data.labels,
            datasets: [{
                data: chart2Data.data,
                backgroundColor: [
                    '#00D4FF',
                    '#FFB84D'
                ],
                borderColor: [
                    '#00b8cc',
                    '#ff9900'
                ],
                borderWidth: 2
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: true,
            plugins: {
                legend: {
                    display: false,
                    labels: {
                        color: '#fff',
                        font: { size: 12 },
                        padding: 15
                    }
                },
                tooltip: {
                    callbacks: {
                        label: function(context) {
                            const value = context.parsed && typeof context.parsed === 'object' ? context.parsed.y : context.parsed;
                            return context.label + ': ' + Number(value).toFixed(4) + '%';
                        }
                    },
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    titleColor: '#fff',
                    bodyColor: '#fff'
                }
            },
            scales: {
                x: {
                    ticks: {
                        color: '#fff'
                    },
                    grid: {
                        color: 'rgba(255,255,255,0.12)'
                    }
                },
                y: {
                    beginAtZero: true,
                    ticks: {
                        color: '#fff',
                        callback: function(value) {
                            return value + '%';
                        }
                    },
                    grid: {
                        color: 'rgba(255,255,255,0.12)'
                    }
                }
            }
        }
    });
}

function formatPopulationValue(value) {
    const numericValue = Number(value) || 0;
    if (numericValue >= 1000000000) return (numericValue / 1000000000).toFixed(1) + 'B';
    if (numericValue >= 1000000) return (numericValue / 1000000).toFixed(1) + 'M';
    if (numericValue >= 1000) return (numericValue / 1000).toFixed(1) + 'K';
    return String(Math.round(numericValue));
}

function formatPopulationAxisValue(value) {
    const numericValue = Number(value) || 0;
    if (numericValue >= 1000000000) return (numericValue / 1000000000).toFixed(1) + 'B';
    if (numericValue >= 1000000) return (numericValue / 1000000).toFixed(1) + 'M';
    if (numericValue >= 1000) return (numericValue / 1000).toFixed(1) + 'K';
    return String(Math.round(numericValue));
}

function updateReportSummary(summary) {
    const reportTotal = document.getElementById('report-total');
    const reportPct = document.getElementById('report-pct');
    const reportHhTotal = document.getElementById('report-hh-total');

    if (reportTotal) reportTotal.textContent = summary.total_households || '0';
    if (reportPct) reportPct.textContent = (summary.avg_poverty_score || 0).toFixed(2);
    if (reportHhTotal) reportHhTotal.textContent = summary.total_households || '0';
}

// ============ LAPORAN DOWNLOAD ============
function loadLaporanSummary() {
    loadCombinedReportPreview();
}

async function loadCombinedReportPreview() {
    const metaElement = document.getElementById('report-preview-meta');
    const frameElement = document.getElementById('report-preview-frame');

    if (!metaElement || !frameElement) return;

    metaElement.textContent = 'Memuat data laporan lengkap...';

    try {
        const [summaryResponse, areaResponse, configResponse, needPointsResponse, allRankings] = await Promise.all([
            fetch('api/get_dashboard_summary.php'),
            fetch('api/get_area_breakdown.php'),
            fetch('api/get_configuration.php'),
            fetch('api/get_need_points.php'),
            fetchAllHouseholdRankingForReport()
        ]);

        const [summaryData, areaData, configurationData, needPointsData] = await Promise.all([
            summaryResponse.json(),
            areaResponse.json(),
            configResponse.json(),
            needPointsResponse.json()
        ]);

        const combinedReport = buildCombinedReportData(summaryData, areaData, configurationData, needPointsData, allRankings);
        const pdfUrl = await renderCombinedPdfPreview(combinedReport);

        if (window.currentCombinedReportPdfUrl) {
            URL.revokeObjectURL(window.currentCombinedReportPdfUrl);
        }

        frameElement.src = pdfUrl;
    metaElement.textContent = `Data dimuat: ${combinedReport.summary.totalNeedPoints.toLocaleString('id-ID')} titik kebutuhan & ${combinedReport.rankings.length.toLocaleString('id-ID')} household skor prioritas`;
        window.currentCombinedReportPdfUrl = pdfUrl;

        updateReportSummary(combinedReport.summary.dashboardSummary);
    } catch (error) {
        console.error('Error loading combined report preview:', error);
        metaElement.textContent = 'Preview laporan gagal dimuat.';
    }
}

async function fetchAllHouseholdRankingForReport() {
    const allRows = [];
    const pageSize = 1000;
    let offset = 0;

    while (true) {
        const response = await fetch(`api/get_household_ranking.php?include_assisted=1&limit=${pageSize}&offset=${offset}`);
        const data = await response.json();

        if (!data || !data.success || !Array.isArray(data.ranking)) {
            throw new Error('Gagal memuat data ranking household');
        }

        allRows.push(...data.ranking);

        if (data.ranking.length < pageSize) {
            break;
        }

        offset += pageSize;
    }

    return allRows;
}

function getCanvasImageDataUrl(canvasId) {
    const canvas = document.getElementById(canvasId);
    if (!canvas || typeof canvas.toDataURL !== 'function') return null;

    try {
        return canvas.toDataURL('image/png');
    } catch (error) {
        console.warn('Gagal mengambil gambar canvas:', canvasId, error);
        return null;
    }
}

function createIndonesiaMapPreviewDataUrl(needPoints) {
    try {
        const canvas = document.createElement('canvas');
        canvas.width = 960;
        canvas.height = 520;
        const ctx = canvas.getContext('2d');

        if (!ctx) return null;

        const w = canvas.width;
        const h = canvas.height;
        const mapLeft = 70;
        const mapTop = 70;
        const mapWidth = w - 120;
        const mapHeight = h - 130;

        // Background and map frame
        const gradient = ctx.createLinearGradient(0, 0, w, h);
        gradient.addColorStop(0, '#e7f0ff');
        gradient.addColorStop(1, '#f6fbff');
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, w, h);

        ctx.fillStyle = '#ffffff';
        ctx.fillRect(mapLeft, mapTop, mapWidth, mapHeight);
        ctx.strokeStyle = '#b8d0ff';
        ctx.lineWidth = 2;
        ctx.strokeRect(mapLeft, mapTop, mapWidth, mapHeight);

        ctx.fillStyle = '#2f4f9b';
        ctx.font = 'bold 18px Arial';
        ctx.fillText('Pratinjau Peta Indonesia (Data Titik Kebutuhan)', 24, 34);

        const lonMin = 95;
        const lonMax = 141;
        const latMin = -11;
        const latMax = 6;

        // Grid lines
        ctx.strokeStyle = '#e1ebff';
        ctx.lineWidth = 1;
        for (let i = 1; i < 6; i++) {
            const x = mapLeft + (i / 6) * mapWidth;
            ctx.beginPath();
            ctx.moveTo(x, mapTop);
            ctx.lineTo(x, mapTop + mapHeight);
            ctx.stroke();
        }
        for (let i = 1; i < 4; i++) {
            const y = mapTop + (i / 4) * mapHeight;
            ctx.beginPath();
            ctx.moveTo(mapLeft, y);
            ctx.lineTo(mapLeft + mapWidth, y);
            ctx.stroke();
        }

        const points = Array.isArray(needPoints) ? needPoints : [];
        ctx.fillStyle = 'rgba(220, 53, 69, 0.35)';
        for (const point of points) {
            const lat = Number(point.latitude);
            const lon = Number(point.longitude);
            if (!Number.isFinite(lat) || !Number.isFinite(lon)) continue;
            if (lat < latMin || lat > latMax || lon < lonMin || lon > lonMax) continue;

            const x = mapLeft + ((lon - lonMin) / (lonMax - lonMin)) * mapWidth;
            const y = mapTop + ((latMax - lat) / (latMax - latMin)) * mapHeight;
            ctx.beginPath();
            ctx.arc(x, y, 1.7, 0, Math.PI * 2);
            ctx.fill();
        }

        ctx.fillStyle = '#3f5fa8';
        ctx.font = '12px Arial';
        ctx.fillText('Batas: 95°E - 141°E, 11°S - 6°N', mapLeft, h - 24);
        ctx.fillText(`Total titik: ${points.length.toLocaleString('id-ID')}`, w - 230, h - 24);

        return canvas.toDataURL('image/png');
    } catch (error) {
        console.warn('Gagal membuat pratinjau peta Indonesia:', error);
        return null;
    }
}

function buildCombinedReportData(summaryData, areaData, configurationData, needPointsData, rankingData) {
    const areas = Array.isArray(areaData?.areas) ? areaData.areas : [];
    const rankings = Array.isArray(rankingData) ? rankingData : [];
    const dashboardSummary = summaryData?.success ? summaryData.summary : {};
    const totalNeedPoints = Array.isArray(needPointsData?.points) ? needPointsData.points.length : 0;
    const needPoints = Array.isArray(needPointsData?.points) ? needPointsData.points : [];
    const populationReference = Number(configurationData?.configuration?.population_reference || 288315899);
    const targetNasional = Number(configurationData?.configuration?.target_nasional || 7.5);
    const povertyPercentage = populationReference > 0 ? (totalNeedPoints / populationReference) * 100 : 0;
    const verifiedCount = needPoints.filter(item => Number(item.is_verified) === 1).length;

    const chartPopulation = getCanvasImageDataUrl('populationChart');
    const chartPercentage = getCanvasImageDataUrl('percentageChart');
    const mapPreview = createIndonesiaMapPreviewDataUrl(needPoints);

    return {
        metadata: {
            createdAt: new Date(),
            populationReference,
            targetNasional,
            povertyPercentage
        },
        summary: {
            totalNeedPoints,
            verifiedCount,
            totalAssistance: 0,
            dashboardSummary
        },
        areas,
        needPoints,
        rankings,
        charts: {
            population: chartPopulation,
            percentage: chartPercentage
        },
        mapPreview
    };
}

async function renderCombinedPdfPreview(report) {
    const jsPDFGlobal = window.jspdf && window.jspdf.jsPDF ? window.jspdf.jsPDF : null;
    if (!jsPDFGlobal) {
        throw new Error('jsPDF library is not available');
    }

    const doc = new jsPDFGlobal({ unit: 'pt', format: 'a4' });
    const pageWidth = doc.internal.pageSize.getWidth();
    const pageHeight = doc.internal.pageSize.getHeight();
    const margin = 40;
    let cursorY = 48;
    const now = report.metadata.createdAt ? new Date(report.metadata.createdAt) : new Date();
    const formattedDate = now.toLocaleDateString('id-ID', { year: 'numeric', month: 'long', day: 'numeric' });

    const addPageNumbers = () => {
        const totalPages = doc.internal.pages.length - 1;
        for (let i = 1; i <= totalPages; i++) {
            doc.setPage(i);
            doc.setFontSize(9);
            doc.setTextColor(150, 150, 150);
            doc.text('Halaman ' + i + ' dari ' + totalPages, pageWidth - margin - 40, pageHeight - 20);
        }
    };

    const addCoverPage = () => {
        doc.setFillColor(102, 126, 234);
        doc.rect(0, 0, pageWidth, pageHeight / 2, 'F');
        doc.setFillColor(118, 75, 162);
        doc.rect(0, pageHeight / 2, pageWidth, pageHeight / 2, 'F');

        doc.setTextColor(255, 255, 255);
        doc.setFont('helvetica', 'bold');
        doc.setFontSize(32);
        doc.text('LAPORAN GABUNGAN', pageWidth / 2, 180, { align: 'center' });
        doc.setFontSize(24);
        doc.text('Sistem Informasi Geografis', pageWidth / 2, 220, { align: 'center' });

        doc.setDrawColor(255, 255, 255);
        doc.setLineWidth(2);
        doc.line(margin * 2, 250, pageWidth - margin * 2, 250);

        doc.setFont('helvetica', 'normal');
        doc.setFontSize(11);
        const summaryY = 300;
        doc.text('Total Point Berkebutuhan: ' + String(report.summary.totalNeedPoints), pageWidth / 2, summaryY, { align: 'center' });
        doc.text('Persentase Kemiskinan: ' + report.metadata.povertyPercentage.toFixed(2) + '%', pageWidth / 2, summaryY + 20, { align: 'center' });
        doc.text('Target Nasional: ' + report.metadata.targetNasional.toFixed(2) + '%', pageWidth / 2, summaryY + 40, { align: 'center' });
        doc.text('Total Populasi: ' + String(report.metadata.populationReference), pageWidth / 2, summaryY + 60, { align: 'center' });

        doc.setFontSize(9);
        doc.setTextColor(255, 255, 255);
        doc.text('Dibuat: ' + formattedDate, pageWidth / 2, pageHeight - 80, { align: 'center' });
        doc.setFontSize(8);
        doc.text('Sistem Informasi Geografis Pontianak', pageWidth / 2, pageHeight - 50, { align: 'center' });
        doc.text('Dokumen Internal', pageWidth / 2, pageHeight - 30, { align: 'center' });

        doc.addPage();
        cursorY = 48;
        doc.setTextColor(25, 25, 25);
    };

    const addTitle = (title, subtitle) => {
        doc.setFillColor(102, 126, 234);
        doc.rect(0, 0, pageWidth, 78, 'F');
        doc.setTextColor(255, 255, 255);
        doc.setFont('helvetica', 'bold');
        doc.setFontSize(20);
        doc.text(title, margin, 32);
        doc.setFont('helvetica', 'normal');
        doc.setFontSize(10);
        doc.text(subtitle, margin, 52);
        cursorY = 100;
        doc.setTextColor(25, 25, 25);
    };

    const addSectionTitle = (title) => {
        if (cursorY > pageHeight - 80) {
            doc.addPage();
            cursorY = 48;
        }
        doc.setFillColor(243, 246, 255);
        doc.rect(margin, cursorY - 6, pageWidth - margin * 2, 32, 'F');
        doc.setDrawColor(102, 126, 234);
        doc.setLineWidth(2);
        doc.line(margin, cursorY + 20, pageWidth - margin, cursorY + 20);
        
        doc.setFont('helvetica', 'bold');
        doc.setFontSize(13);
        doc.setTextColor(102, 126, 234);
        doc.text(title, margin + 10, cursorY + 14);
        cursorY += 36;
        doc.setTextColor(54, 65, 83);
    };

    const addMetricsGrid = (metrics) => {
        const cellWidth = (pageWidth - margin * 2 - 18) / 2;
        metrics.forEach((metric, index) => {
            const x = margin + (index % 2) * (cellWidth + 18);
            const y = cursorY + Math.floor(index / 2) * 58;
            doc.setFillColor(243, 246, 255);
            doc.rect(x, y, cellWidth, 50, 'F');
            doc.setDrawColor(102, 126, 234);
            doc.setLineWidth(0.5);
            doc.rect(x, y, cellWidth, 50);
            doc.setFont('helvetica', 'bold');
            doc.setFontSize(9);
            doc.setTextColor(102, 126, 234);
            doc.text(metric.label, x + 8, y + 16);
            doc.setFontSize(14);
            doc.setTextColor(24, 24, 24);
            doc.text(String(metric.value), x + 8, y + 33);
        });
        cursorY += Math.ceil(metrics.length / 2) * 58 + 6;
    };

    const addParagraph = (text) => {
        const lines = doc.splitTextToSize(text, pageWidth - margin * 2);
        doc.setFont('helvetica', 'normal');
        doc.setFontSize(10);
        doc.setTextColor(60, 60, 60);
        doc.text(lines, margin, cursorY);
        cursorY += lines.length * 12 + 8;
    };

    const addImageBlock = (title, dataUrl, width, height) => {
        if (!dataUrl) return;
        if (cursorY + height + 36 > pageHeight - 35) {
            doc.addPage();
            cursorY = 48;
        }
        doc.setFont('helvetica', 'bold');
        doc.setFontSize(11);
        doc.setTextColor(54, 65, 83);
        doc.text(title, margin, cursorY);
        cursorY += 12;
        doc.addImage(dataUrl, 'PNG', margin, cursorY, width, height);
        cursorY += height + 14;
    };

    const addAutoTable = (head, body, options) => {
        var tableOptions = {
            startY: cursorY,
            head: head,
            body: body,
            theme: 'striped',
            headStyles: { fillColor: [102, 126, 234] },
            styles: { fontSize: 8, cellPadding: 4 },
            margin: { left: margin, right: margin }
        };
        if (options) {
            Object.assign(tableOptions, options);
        }
        doc.autoTable(tableOptions);
        cursorY = doc.lastAutoTable.finalY + 18;
    };

    addCoverPage();

    addTitle('Laporan Gabungan Sistem Informasi Geografis', 'Memuat seluruh data Beranda, Peta, dan Manajemen');

    addSectionTitle('Ringkasan Eksekutif');
    addMetricsGrid([
        { label: 'Total Point Berkebutuhan', value: report.summary.totalNeedPoints.toLocaleString('id-ID') },
        { label: 'Persentase Kemiskinan', value: report.metadata.povertyPercentage.toFixed(6) + '%' },
        { label: 'Target Nasional', value: report.metadata.targetNasional.toFixed(2) + '%' },
        { label: 'Total Populasi Indonesia', value: report.metadata.populationReference.toLocaleString('id-ID') }
    ]);
    addParagraph('Laporan ini memuat seluruh informasi utama dari Beranda, pratinjau peta Indonesia berbasis data peta, serta daftar lengkap titik kebutuhan dan household dengan skor prioritas.');

    addSectionTitle('Grafik Beranda');
    const chartWidth = (pageWidth - margin * 2 - 16) / 2;
    const chartHeight = 170;
    if (cursorY + chartHeight + 40 > pageHeight - 35) {
        doc.addPage();
        cursorY = 48;
    }
    if (report.charts.population) {
        doc.addImage(report.charts.population, 'PNG', margin, cursorY, chartWidth, chartHeight);
    }
    if (report.charts.percentage) {
        doc.addImage(report.charts.percentage, 'PNG', margin + chartWidth + 16, cursorY, chartWidth, chartHeight);
    }
    cursorY += chartHeight + 18;

    addSectionTitle('Pratinjau Peta Indonesia');
    addImageBlock('Sebaran titik kebutuhan dari modul peta', report.mapPreview, pageWidth - margin * 2, 230);

    addSectionTitle('Ringkasan Wilayah (Beranda)');
    const areaRows = report.areas.map(area => [
        area.area_name || '-',
        String(area.household_count || 0),
        String(area.area_type || '-')
    ]);
    addAutoTable(
        [['Wilayah', 'Jumlah Titik Kebutuhan', 'Tipe']],
        areaRows.length > 0 ? areaRows : [['-', '0', '-']]
    );

    addSectionTitle('Daftar Titik Kebutuhan (Semua Data)');
    const needPointRows = report.needPoints.map((point, index) => [
        String(index + 1),
        point.name || '-',
        point.head_name || '-',
        point.economic_status || '-',
        point.masjid_name || '-',
        Number(point.latitude || 0).toFixed(4) + ', ' + Number(point.longitude || 0).toFixed(4)
    ]);
    addAutoTable(
        [['No', 'Nama Titik', 'Kepala Keluarga', 'Status Ekonomi', 'Masjid', 'Koordinat']],
        needPointRows.length > 0 ? needPointRows : [['-', '-', '-', '-', '-', '-']],
        { styles: { fontSize: 7, cellPadding: 3 } }
    );

    addSectionTitle('Household dengan Skor Prioritas (Semua Data)');
    const rankingRows = report.rankings.map((item, index) => [
        String(index + 1),
        item.household_code || '-',
        item.head_name || '-',
        item.priority_level || '-',
        Number(item.skr || 0).toFixed(3),
        Number(item.spi || 0).toFixed(3),
        item.area_name || '-',
        Number(item.assisted || 0) === 1 ? 'Ya' : 'Belum'
    ]);
    addAutoTable(
        [['No', 'Kode Household', 'Kepala Keluarga', 'Prioritas', 'SKR', 'SPI', 'Wilayah', 'Sudah Dibantu']],
        rankingRows.length > 0 ? rankingRows : [['-', '-', '-', '-', '0.000', '0.000', '-', '-']],
        { styles: { fontSize: 7, cellPadding: 3 } }
    );

    addSectionTitle('Data Geospasial');
    addParagraph('Total titik kebutuhan: ' + report.needPoints.length.toLocaleString('id-ID') + ' data. Total household skor prioritas: ' + report.rankings.length.toLocaleString('id-ID') + ' data. Ringkasan wilayah beranda: ' + report.areas.length.toLocaleString('id-ID') + ' data. Export GeoJSON tetap tersedia dari menu peta.');

    addPageNumbers();
    const pdfBlob = doc.output('blob');
    return URL.createObjectURL(pdfBlob);
}

async function downloadCombinedPDF() {
    if (!window.currentCombinedReportPdfUrl) {
        await loadCombinedReportPreview();
    }

    if (!window.currentCombinedReportPdfUrl) {
        showNotification('Preview laporan belum siap', true);
        return;
    }

    const link = document.createElement('a');
    link.href = window.currentCombinedReportPdfUrl;
    link.download = `laporan-gabungan-${new Date().toISOString().slice(0, 10)}.pdf`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
}

async function downloadGeojson() {
    try {
        const response = await fetch('api/export_geojson.php?include_households=true&include_points=true&include_roads=true');
        const geojson =  await response.json();
        
        const element = document.createElement('a');
        element.setAttribute('href', 'data:application/geo+json;charset=utf-8,' + encodeURIComponent(JSON.stringify(geojson, null, 2)));
        element.setAttribute('download', 'geospatial-data-' + new Date().toISOString().slice(0, 10) + '.geojson');
        element.style.display = 'none';
        document.body.appendChild(element);
        element.click();
        document.body.removeChild(element);
        
        showNotification('GeoJSON data berhasil diunduh');
    } catch (error) {
        console.error('Error downloading GeoJSON:', error);
        showNotification('Error downloading GeoJSON', true);
    }
}

// ============ DASHBOARD ============
function loadDashboard() {
    fetch('api/get_dashboard_summary.php')
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                renderDashboardSummary(data);
            }
        })
        .catch(error => console.error('Error loading dashboard:', error));

    fetch('api/get_area_breakdown.php')
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                renderAreaBreakdown(data.areas);
            }
        })
        .catch(error => console.error('Error loading area breakdown:', error));
}

function renderDashboardSummary(data) {
    const summary = data.summary;
    
    // Update summary cards
    document.getElementById('dash-total-households').textContent = summary.total_households;
    document.getElementById('dash-avg-score').textContent = summary.avg_poverty_score;
    document.getElementById('dash-assisted').textContent = summary.households_assisted;
    document.getElementById('dash-assisted-pct').textContent = summary.percentage_assisted + '%';

    // Render status breakdown
    const statusList = document.getElementById('dash-status-list');
    statusList.innerHTML = '';
    
    const statusLabels = {
        'unverified': '⏱️ Belum Verifikasi',
        'field_verified': '✓ Terverifikasi Lapangan',
        'admin_approved': '✅ Admin Approved',
        'needs_review': '🔍 Perlu Review',
        'rejected': '❌ Ditolak'
    };
    
    for (const [status, count] of Object.entries(data.summary.status_breakdown || {})) {
        const item = document.createElement('div');
        item.className = 'dashboard-status-item';
        item.textContent = `${statusLabels[status] || status}: ${count}`;
        statusList.appendChild(item);
    }

    // Render priority breakdown
    const priorityList = document.getElementById('dash-priority-list');
    priorityList.innerHTML = '';
    
    const priorityLabels = {
        'very_high': '🔴 Sangat Tinggi',
        'high': '🟠 Tinggi',
        'medium': '🟡 Menengah',
        'low': '🟢 Rendah'
    };
    
    for (const [priority, count] of Object.entries(data.summary.priority_breakdown || {})) {
        const item = document.createElement('div');
        item.className = 'dashboard-priority-item';
        item.textContent = `${priorityLabels[priority] || priority}: ${count}`;
        priorityList.appendChild(item);
    }
}

function renderAreaBreakdown(areas) {
    const areaList = document.getElementById('dash-area-list');
    areaList.innerHTML = '';
    
    areas.slice(0, 10).forEach(area => {
        const item = document.createElement('div');
        item.className = 'dashboard-area-item';
        item.innerHTML = `
            <div>
                <div class="dashboard-area-item-label">${area.area_name}</div>
                <div class="dashboard-area-item-value">Keluarga: ${area.household_count || 0}</div>
            </div>
            <div>
                <div class="dashboard-area-item-label">Score Avg: ${(area.avg_poverty_score || 0).toFixed(1)}</div>
                <div class="dashboard-area-item-value">Terverif: ${area.verified_count || 0}</div>
            </div>
        `;
        areaList.appendChild(item);
    });
}

function refreshDashboard() {
    loadDashboard();
    showNotification('Dashboard refreshed');
}

// ============ USER MANAGEMENT ============
function loadUsersList() {
    if (!currentUser || currentUser.role !== 'Admin') {
        showNotification('Only admins can manage users', true);
        return;
    }

    fetch('api/get_users.php')
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                renderUsersList(data.users);
            } else {
                showNotification('Error loading users: ' + (data.error || 'Unknown error'), true);
            }
        })
        .catch(error => {
            console.error('Error loading users:', error);
            showNotification('Error loading users', true);
        });
}

function renderUsersList(users) {
    const usersList = document.getElementById('users-list');
    usersList.innerHTML = '';

    const activeCountEl = document.getElementById('users-active-count');
    const inactiveCountEl = document.getElementById('users-inactive-count');
    const activeCount = Array.isArray(users) ? users.filter(user => Number(user.is_active) === 1).length : 0;
    const inactiveCount = Array.isArray(users) ? Math.max(0, users.length - activeCount) : 0;

    if (activeCountEl) activeCountEl.textContent = String(activeCount);
    if (inactiveCountEl) inactiveCountEl.textContent = String(inactiveCount);

    if (users.length === 0) {
        usersList.innerHTML = '<div class="users-empty">Belum ada pengguna yang terdaftar.</div>';
        return;
    }

    users.forEach(user => {
        const item = document.createElement('div');
        item.className = 'user-item';
        
        const roleLabel = {
            'Admin': '👑 Admin',
            'Petugas': '📝 Petugas Data',
            'Pimpinan': '👔 Pimpinan'
        }[user.role] || user.role;

        const statusText = user.is_active ? 'Aktif' : 'Nonaktif';
        const statusClass = user.is_active ? 'status-active' : 'status-inactive';

        item.innerHTML = `
            <div class="user-item-avatar ${user.role ? user.role.toLowerCase() : ''}">${(user.username || '?').charAt(0).toUpperCase()}</div>
            <div class="user-item-info">
                <div class="user-item-username">${user.username}</div>
                <div class="user-item-email">${user.email}</div>
                <div class="user-item-meta">
                    <span class="user-item-role">${roleLabel}</span>
                    <span class="user-item-status ${statusClass}">${statusText}</span>
                </div>
            </div>
            <div class="user-item-actions">
                <button class="btn-edit-user" onclick="openEditUserModal(${user.id}, '${user.role}')">Edit</button>
                <button class="btn-delete-user" onclick="deleteUserConfirm(${user.id}, '${user.username}')">Hapus</button>
            </div>
        `;
        usersList.appendChild(item);
    });
}

async function createNewUser() {
    const username = document.getElementById('new-user-username').value.trim();
    const email = document.getElementById('new-user-email').value.trim();
    const password = document.getElementById('new-user-password').value;
    const role = document.getElementById('new-user-role').value;

    const resultDiv = document.getElementById('user-creation-result');

    // Validation
    if (!username || !email || !password || !role) {
        resultDiv.textContent = '❌ Semua field harus diisi';
        resultDiv.className = 'error';
        resultDiv.style.display = 'block';
        return;
    }

    if (password.length < 6) {
        resultDiv.textContent = '❌ Password minimal 6 karakter';
        resultDiv.className = 'error';
        resultDiv.style.display = 'block';
        return;
    }

    try {
        const response = await fetch('api/create_user.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ username, email, password, role })
        });

        const data = await response.json();

        if (data.success) {
            resultDiv.textContent = `✅ ${data.message}`;
            resultDiv.className = 'users-result success';
            resultDiv.style.display = 'block';
            
            // Clear form
            document.getElementById('new-user-username').value = '';
            document.getElementById('new-user-email').value = '';
            document.getElementById('new-user-password').value = '';
            document.getElementById('new-user-role').value = 'Petugas';

            // Refresh users list
            setTimeout(() => loadUsersList(), 1500);
        } else {
            resultDiv.textContent = `❌ ${data.message || data.error}`;
            resultDiv.className = 'users-result error';
            resultDiv.style.display = 'block';
        }
    } catch (error) {
        console.error('Error creating user:', error);
        resultDiv.textContent = '❌ Error creating user';
        resultDiv.className = 'users-result error';
        resultDiv.style.display = 'block';
    }
}

async function deleteUserConfirm(userId, username) {
    if (confirm(`Are you sure you want to deactivate user "${username}"?`)) {
        try {
            const response = await fetch('api/delete_user.php', {
                method: 'DELETE',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ id: userId })
            });

            const data = await response.json();

            if (data.success) {
                showNotification('User deactivated successfully');
                loadUsersList();
            } else {
                showNotification(`Error: ${data.error}`, true);
            }
        } catch (error) {
            console.error('Error deleting user:', error);
            showNotification('Error deactivating user', true);
        }
    }
}

function openEditUserModal(userId, currentRole) {
    const newRole = prompt('Select new role:\n1 = Admin\n2 = Petugas\n3 = Pimpinan\n\nCurrent: ' + currentRole);
    
    if (newRole === null) return; // User cancelled
    
    const roleMap = { '1': 'Admin', '2': 'Petugas', '3': 'Pimpinan' };
    const role = roleMap[newRole];

    if (!role) {
        showNotification('Invalid role selection', true);
        return;
    }

    updateUserRole(userId, role);
}

async function updateUserRole(userId, newRole) {
    try {
        const response = await fetch('api/update_user.php', {
            method: 'PUT',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ id: userId, role: newRole })
        });

        const data = await response.json();

        if (data.success) {
            showNotification('User role updated successfully');
            loadUsersList();
        } else {
            showNotification(`Error: ${data.error}`, true);
        }
    } catch (error) {
        console.error('Error updating user:', error);
        showNotification('Error updating user role', true);
    }
}

function isTabAllowedForCurrentUser(tabName) {
    if (!currentUser || !currentUser.role) return true;

    const role = String(currentUser.role).toLowerCase();

    if (role === 'pimpinan') {
        return tabName === 'beranda' || tabName === 'laporan';
    }

    return true;
}

// Show users tab button if user is admin
function updateAdminUI() {
    if (!currentUser) return;

    const adminButtons = document.querySelectorAll('.admin-only');
    adminButtons.forEach(button => {
        button.style.display = currentUser.role === 'Admin' ? 'inline-flex' : 'none';
    });

    const restrictedForPimpinan = document.querySelectorAll('.tab-button:not(.admin-only)');
    restrictedForPimpinan.forEach(button => {
        const handler = button.getAttribute('onclick') || '';
        const allowsOnlyHomeAndReport = currentUser.role && String(currentUser.role).toLowerCase() === 'pimpinan';
        if (allowsOnlyHomeAndReport) {
            const isAllowed = handler.includes("'beranda'") || handler.includes('"beranda"') || handler.includes("'laporan'") || handler.includes('"laporan"');
            button.style.display = isAllowed ? 'inline-flex' : 'none';
        } else {
            button.style.display = 'inline-flex';
        }
    });

    if (currentUser.role && String(currentUser.role).toLowerCase() === 'pimpinan') {
        if (!isTabAllowedForCurrentUser(getActiveTabName())) {
            switchTab('beranda');
        }
    }
}

function getActiveTabName() {
    const activeButton = document.querySelector('.tab-button.tab-active');
    if (!activeButton) return 'beranda';

    const handler = activeButton.getAttribute('onclick') || '';
    const match = handler.match(/switchTab\(['\"]([^'\"]+)['\"]/);
    return match ? match[1] : 'beranda';
}

function setupConfigurationSection() {
    const saveButton = document.getElementById('save-configuration-btn');
    if (saveButton) {
        saveButton.onclick = saveConfiguration;
    }

    // wire rendering mode + refresh/export controls (moved into Konfigurasi tab)
    const renderingSelect = document.getElementById('rendering-mode-select');
    const refreshBtn = document.getElementById('refresh-needpoints-btn');
    const exportBtn = document.getElementById('export-needpoints-btn');

    if (renderingSelect) {
        const stored = getStoredRenderingMode();
        renderingSelect.value = stored ? stored : (renderingMode === 'auto' ? 'auto' : renderingMode);
        renderingSelect.onchange = function(e) {
            const val = e.target.value;
            if (val === 'auto') renderingMode = detectRenderingMode(); else renderingMode = val;
            setStoredRenderingMode(val === 'auto' ? null : val);
            if (renderingMode === 'high') visibleMarkerThreshold = 3000;
            else if (renderingMode === 'medium') visibleMarkerThreshold = 1500;
            else if (renderingMode === 'low') visibleMarkerThreshold = 0;
            else visibleMarkerThreshold = 600;
            renderVisibleNeedPoints();
            showNotification('Rendering mode set to ' + renderingMode);
        };
    }

    if (refreshBtn) refreshBtn.onclick = function() { loadNeedPoints(); showNotification('Refreshing need points'); };
    if (exportBtn) exportBtn.onclick = function() { downloadGeojson(); showNotification('GeoJSON export started'); };

    loadConfiguration();
}

function loadConfiguration() {
    fetch('api/get_configuration.php')
        .then(response => response.json())
        .then(data => {
            if (!data.success) return;

            const targetInput = document.getElementById('target-nasional-input');
            if (targetInput) {
                targetInput.value = Number(data.configuration?.target_nasional || 7.5).toFixed(2);
            }

            const populationInput = document.getElementById('population-reference-input');
            if (populationInput) {
                populationInput.value = Number(data.configuration?.population_reference || 288315899);
            }

            const targetDisplay = document.getElementById('beranda-target');
            if (targetDisplay) {
                targetDisplay.textContent = Number(data.configuration?.target_nasional || 7.5).toFixed(2);
            }
        })
        .catch(error => console.error('Error loading configuration:', error));
}

function saveConfiguration() {
    const targetInput = document.getElementById('target-nasional-input');
    const populationInput = document.getElementById('population-reference-input');
    const resultBox = document.getElementById('configuration-result');
    const targetNasional = targetInput ? parseFloat(targetInput.value) : NaN;
    const populationReference = populationInput ? parseInt(populationInput.value, 10) : NaN;

    if (isNaN(targetNasional) || targetNasional < 0 || targetNasional > 100) {
        if (resultBox) {
            resultBox.style.display = 'block';
            resultBox.style.background = 'rgba(244,67,54,0.2)';
            resultBox.style.border = '1px solid rgba(244,67,54,0.4)';
            resultBox.textContent = 'Target nasional harus antara 0 sampai 100.';
        }
        return;
    }

    if (isNaN(populationReference) || populationReference < 1) {
        if (resultBox) {
            resultBox.style.display = 'block';
            resultBox.style.background = 'rgba(244,67,54,0.2)';
            resultBox.style.border = '1px solid rgba(244,67,54,0.4)';
            resultBox.textContent = 'Total populasi Indonesia harus lebih besar dari 0.';
        }
        return;
    }

    fetch('api/save_configuration.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ target_nasional: targetNasional, population_reference: populationReference })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            if (resultBox) {
                resultBox.style.display = 'block';
                resultBox.style.background = 'rgba(76,175,80,0.2)';
                resultBox.style.border = '1px solid rgba(76,175,80,0.4)';
                resultBox.textContent = 'Konfigurasi berhasil disimpan.';
            }
            const targetDisplay = document.getElementById('beranda-target');
            if (targetDisplay) {
                targetDisplay.textContent = Number(data.configuration?.target_nasional || targetNasional).toFixed(2);
            }

            loadBerandaDashboard();
            loadCombinedReportPreview();
        } else if (resultBox) {
            resultBox.style.display = 'block';
            resultBox.style.background = 'rgba(244,67,54,0.2)';
            resultBox.style.border = '1px solid rgba(244,67,54,0.4)';
            resultBox.textContent = data.error || 'Gagal menyimpan konfigurasi.';
        }
    })
    .catch(error => {
        console.error('Error saving configuration:', error);
        if (resultBox) {
            resultBox.style.display = 'block';
            resultBox.style.background = 'rgba(244,67,54,0.2)';
            resultBox.style.border = '1px solid rgba(244,67,54,0.4)';
            resultBox.textContent = 'Gagal menyimpan konfigurasi.';
        }
    });
}

// ============ MANAGEMENT / CONFIGURATION FOR NEED POINTS ============
function loadManagement() {
    // Load a preview list of need points (10 per page) in the Managemen panel
    setupManagementNeedpointControls();
    loadManagementNeedPoints();

    // Ensure household data is available for score computation path
    loadHouseholdsForPanel();

    const computeBtn = document.getElementById('manage-compute-score-btn');
    if (computeBtn) {
        computeBtn.onclick = function() {
            computeHouseholdScores();
            // refresh management preview shortly after compute call starts
            setTimeout(loadManagementScorePreview, 500);
        };
    }

    loadManagementScorePreview();
}

// Management need-point carousel state
let managementNeedPoints = [];
let currentMgmtNeedPage = 0;
const MGMT_NEEDPAGE_SIZE = 10;

function setupManagementNeedpointControls() {
    const prev = document.getElementById('needpoint-prev');
    const next = document.getElementById('needpoint-next');
    if (prev) prev.onclick = function() { renderManagementNeedPointPage(currentMgmtNeedPage - 1); };
    if (next) next.onclick = function() { renderManagementNeedPointPage(currentMgmtNeedPage + 1); };
}

function loadManagementNeedPoints() {
    fetch('api/get_need_points.php')
        .then(r => r.json())
        .then(data => {
            if (data.success && Array.isArray(data.points)) {
                managementNeedPoints = data.points.map(p => normalizeNeedPointRecord(p));
            } else {
                managementNeedPoints = [];
            }
            currentMgmtNeedPage = 0;
            renderManagementNeedPointPage(0);
        })
        .catch(err => {
            console.error('Error loading management need points', err);
            managementNeedPoints = [];
            renderManagementNeedPointPage(0);
        });
}

function renderManagementNeedPointPage(pageIndex) {
    if (!Array.isArray(managementNeedPoints)) managementNeedPoints = [];
    const total = managementNeedPoints.length;
    const maxPage = Math.max(0, Math.ceil(total / MGMT_NEEDPAGE_SIZE) - 1);
    if (pageIndex < 0) pageIndex = 0;
    if (pageIndex > maxPage) pageIndex = maxPage;
    currentMgmtNeedPage = pageIndex;

    const start = pageIndex * MGMT_NEEDPAGE_SIZE;
    const slice = managementNeedPoints.slice(start, start + MGMT_NEEDPAGE_SIZE);
    const container = document.getElementById('management-needpoint-list');
    const pager = document.getElementById('management-needpoint-pager');
    if (!container) return;
    container.innerHTML = '';

    if (slice.length === 0) {
        container.innerHTML = '<div style="color: rgba(255,255,255,0.7); padding: 12px;">No need points available</div>';
    } else {
        let rowsHtml = '';
        slice.forEach(p => {
            const id = Number(p.id) || 0;
            const assisted = Number(p.assisted || 0) === 1;
            const name = escapeHtml(p.name || '-');
            const nameClass = assisted ? 'assisted-point-name' : '';
            const hh = escapeHtml(p.household_name || '-');
            const head = escapeHtml(p.head_name || '-');
            const econRaw = String(p.economic_status || '-').toLowerCase();
            const econClass = econRaw.replace(/[^a-z_]/g, '');
            const econLabel = escapeHtml(econRaw === '-' ? '-' : econRaw.replace(/_/g, ' '));
            const coords = `${Number(p.latitude).toFixed(4)}, ${Number(p.longitude).toFixed(4)}`;
            const verified = Number(p.is_verified || 0) === 1;
            const verifyIcon = verified ? '✓' : '✕';
            const verifyTitle = verified ? 'Verified' : 'Not Verified';
            const bantuanDisabled = !verified;
            const bantuanClass = 'mini-icon-btn bantuan' + (bantuanDisabled ? ' disabled' : '');
            const bantuanTitle = bantuanDisabled ? 'Lock: household not verified' : 'Kelola Bantuan';
            const bantuanOnclick = bantuanDisabled ? '' : `onclick="openNeedPointBantuanModal(${id})"`;
            rowsHtml += `<tr class="${verified ? 'row-verified' : ''}"><td class="col-id ${verified ? 'verified-id' : ''}">${id}</td><td class="${nameClass}">${name}</td><td>${hh}</td><td>${head}</td><td><span class="econ-badge econ-${econClass}">${econLabel}</span></td><td>${coords}</td><td><button class="mini-icon-btn verify ${verified ? 'is-on' : 'is-off'}" title="${verifyTitle}" onclick="toggleNeedPointVerification(${id})">${verifyIcon}</button></td><td><button class="${bantuanClass}" title="${bantuanTitle}" ${bantuanOnclick} ${bantuanDisabled ? 'disabled' : ''}>🎁</button></td></tr>`;
        });

        container.innerHTML = `
            <div class="management-needpoint-table-wrap">
                <table class="management-needpoint-table">
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>Point</th>
                            <th>Nama Rumah/Keluarga</th>
                            <th>Kepala Rumah</th>
                            <th>Keadaan Ekonomi</th>
                            <th>Koordinat</th>
                            <th>Verif</th>
                            <th>Bantuan</th>
                        </tr>
                    </thead>
                    <tbody>${rowsHtml}</tbody>
                </table>
            </div>
        `;
    }

    if (pager) pager.textContent = `Page ${pageIndex + 1} / ${maxPage + 1} • ${total} items`;
}

function toggleNeedPointVerification(id) {
    fetch('api/toggle_need_point_verification.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ id: id })
    })
    .then(r => r.json())
    .then(data => {
        if (!data.success || !data.point) {
            showNotification('Gagal mengubah status verifikasi', true);
            return;
        }

        const updated = normalizeNeedPointRecord(data.point);
        const idx = managementNeedPoints.findIndex(p => Number(p.id) === Number(id));
        if (idx !== -1) {
            managementNeedPoints[idx] = { ...managementNeedPoints[idx], ...updated };
        }

        renderManagementNeedPointPage(currentMgmtNeedPage);
        showNotification(updated.is_verified ? 'Point berkebutuhan diverifikasi' : 'Verifikasi dibatalkan');
    })
    .catch(err => {
        console.error('Verification toggle error:', err);
        showNotification('Gagal mengubah verifikasi', true);
    });
}

function openNeedPointBantuanModal(id) {
    const point = managementNeedPoints.find(p => Number(p.id) === Number(id));
    const pointName = point && point.name ? point.name : ('ID ' + id);

    // Populate modal content
    const modal = document.getElementById('bantuan-manage-modal');
    if (!modal) return;

    const titleEl = modal.querySelector('.bantuan-point-title');
    const instructionsEl = modal.querySelector('.bantuan-instructions');
    const openAssistanceBtn = modal.querySelector('.bantuan-open-assistance');

    if (titleEl) titleEl.textContent = pointName;
    if (instructionsEl) instructionsEl.innerHTML = `
        <div class="bantuan-step-list">
            <div class="bantuan-step-item"><span class="bantuan-step-number">1</span><span>Verifikasi kondisi household.</span></div>
            <div class="bantuan-step-item"><span class="bantuan-step-number">2</span><span>Pilih jenis bantuan yang sesuai.</span></div>
            <div class="bantuan-step-item"><span class="bantuan-step-number">3</span><span>Catat nominal, frekuensi, dan petugas penyalur.</span></div>
            <div class="bantuan-step-item"><span class="bantuan-step-number">4</span><span>Lanjutkan ke form catat bantuan.</span></div>
        </div>
    `;

    if (openAssistanceBtn) {
        openAssistanceBtn.onclick = function() {
            // If there are no households yet, create one from the need_point record automatically
            if (!Array.isArray(households) || households.length === 0) {
                createHouseholdFromNeedPoint(point)
                    .then(household => {
                        // Refresh local selects with the newly created household
                        populateHouseholdSelectOptions();
                        closeBantuanManageModal();
                        openAssistanceModal(household.id);
                    })
                    .catch(err => {
                        console.error('Auto-create household failed:', err);
                        showNotification('Gagal membuat household otomatis: ' + (err.message || err), true);
                    });
                return;
            }

            // Pre-populate assistance modal if possible by matching head_name or household_name
            populateHouseholdSelectOptions();
            const select = document.getElementById('assistance-household-id');
            if (select && point) {
                // Try to find a household id by head_name or household_name
                const match = households.find(h => h.head_name === point.head_name || h.household_name === point.household_name);
                if (match) {
                    select.value = String(match.id);
                }
            }
            closeBantuanManageModal();
            openAssistanceModal(select ? select.value : null);
        };
    }

    modal.classList.add('show');
}

function closeBantuanManageModal() {
    const modal = document.getElementById('bantuan-manage-modal');
    if (modal) modal.classList.remove('show');
}

function loadManagementScorePreview() {
    fetch('api/get_household_score_summary.php')
        .then(response => response.json())
        .then(data => {
            if (!data.success || !data.summary) {
                return;
            }

            const counts = data.summary.priority_counts || {};
            const assistedCount = Number(data.summary.assisted_households || 0);
            const assistedEl = document.getElementById('mgmt-assisted-count');
            const veryHighEl = document.getElementById('mgmt-priority-very-high-count');
            const highEl = document.getElementById('mgmt-priority-high-count');
            const mediumEl = document.getElementById('mgmt-priority-medium-count');
            const lowEl = document.getElementById('mgmt-priority-low-count');

            if (assistedEl) assistedEl.textContent = assistedCount;
            if (veryHighEl) veryHighEl.textContent = Number(counts.very_high || 0);
            if (highEl) highEl.textContent = Number(counts.high || 0);
            if (mediumEl) mediumEl.textContent = Number(counts.medium || 0);
            if (lowEl) lowEl.textContent = Number(counts.low || 0);
        })
        .catch(error => {
            console.error('Error loading management score preview:', error);
        });
}

function loadMarkers() {
    fetch('api/get_points.php')
        .then(response => response.json())
        .then(data => {
            if (data.success && data.markers) {
                // Clear existing markers
                Object.keys(markers).forEach(id => {
                    map.removeLayer(markers[id]);
                });
                markers = {};
                markerCount = 0;

                // Load new markers
                data.markers.forEach(marker => {
                    displayMarker(
                        marker.id,
                        marker.name,
                        marker.nomor_spbu,
                        marker.latitude,
                        marker.longitude,
                        marker.open_24_hours
                    );
                });
                updateMarkerCount();
            }
        })
        .catch(error => console.error('Error loading markers:', error));
}

function updateMarkerCount() {
    const countElement = document.getElementById('marker-count');
    if (countElement) {
        countElement.textContent = markerCount;
    }
}

function deleteMarker(id) {
    if (!confirm('Are you sure you want to delete this point?')) {
        return;
    }

    fetch('api/delete_point.php', {
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ id: id })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            if (markers[id]) {
                map.removeLayer(markers[id]);
                delete markers[id];
                markerCount--;
                updateMarkerCount();
                showNotification('✓ Point deleted');
            }
        } else {
            showNotification('Error deleting point: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error deleting point', true);
    });
}

function editMarker(id) {
    if (!markerData[id]) {
        showNotification('Marker data not found', true);
        return;
    }

    const data = markerData[id];
    currentEditingMarkerId = id;

    // Pre-fill form with current marker data
    document.getElementById('edit-name').value = data.name;
    document.getElementById('edit-nomor-spbu').value = data.nomor_spbu || '';
    document.getElementById('edit-latitude').value = data.latitude;
    document.getElementById('edit-longitude').value = data.longitude;
    document.getElementById('edit-24hours').checked = data.open_24_hours ? true : false;

    // Open edit modal
    const editModal = document.getElementById('edit-modal');
    editModal.classList.add('show');
    document.getElementById('edit-name').focus();
}

function closeEditModal() {
    const editModal = document.getElementById('edit-modal');
    editModal.classList.remove('show');
    currentEditingMarkerId = null;
}

function saveMarkerEdit() {
    if (!currentEditingMarkerId) {
        showNotification('No marker selected for editing', true);
        return;
    }

    const name = document.getElementById('edit-name').value.trim();
    const nomor_spbu = document.getElementById('edit-nomor-spbu').value.trim();
    const latitude = parseFloat(document.getElementById('edit-latitude').value);
    const longitude = parseFloat(document.getElementById('edit-longitude').value);
    const open_24_hours = document.getElementById('edit-24hours').checked ? 1 : 0;

    // Validate inputs
    if (!name) {
        showNotification('Please enter a name for the point', true);
        return;
    }

    if (isNaN(latitude) || latitude < -90 || latitude > 90) {
        showNotification('Please enter a valid latitude (-90 to 90)', true);
        return;
    }

    if (isNaN(longitude) || longitude < -180 || longitude > 180) {
        showNotification('Please enter a valid longitude (-180 to 180)', true);
        return;
    }

    const id = currentEditingMarkerId;

    // Update in database
    fetch('api/update_point.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            id: id,
            name: name,
            nomor_spbu: nomor_spbu,
            latitude: latitude,
            longitude: longitude,
            open_24_hours: open_24_hours
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            const oldStatus = markerData[id].open_24_hours;
            const newStatus = open_24_hours;

            // Update local marker data
            markerData[id] = {
                id: id,
                name: name,
                nomor_spbu: nomor_spbu,
                latitude: latitude,
                longitude: longitude,
                open_24_hours: open_24_hours
            };

            // If status changed, update marker icon and color
            if (oldStatus !== newStatus) {
                const icon = open_24_hours ? markerIcons.open : markerIcons.closed;
                markers[id].setIcon(icon);
            }

            // Update marker position if changed
            const currentPos = markers[id].getLatLng();
            if (currentPos.lat !== latitude || currentPos.lng !== longitude) {
                markers[id].setLatLng([latitude, longitude]);
            }

            // Force popup update
            if (markers[id].isPopupOpen()) {
                markers[id].closePopup();
            }

            closeEditModal();
            showNotification('✓ Point updated successfully');
        } else {
            showNotification('Error updating point: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error updating point', true);
    });
}

function toggleMarkerStatus(id) {
    if (!markerData[id]) {
        showNotification('Marker data not found', true);
        return;
    }

    const currentStatus = markerData[id].open_24_hours;
    const newStatus = currentStatus ? 0 : 1;

    // Update in database
    fetch('api/update_point.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            id: id,
            open_24_hours: newStatus
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            // Update local marker data
            markerData[id].open_24_hours = newStatus;

            // Update marker icon color
            const icon = newStatus ? markerIcons.open : markerIcons.closed;
            markers[id].setIcon(icon);

            // Update popup content
            const marker = markers[id];
            const name = markerData[id].name;
            const nomor_spbu = markerData[id].nomor_spbu;
            const lat = markerData[id].latitude;
            const lng = markerData[id].longitude;

            const hoursText = newStatus ? '🕐 Open 24 Hours' : '🕐 Limited Hours';
            let popupContent = `
                <div class="marker-popup">
                    <div class="marker-popup-name">${escapeHtml(name)}</div>
                    <div class="marker-popup-hours">${hoursText}</div>`;

            if (nomor_spbu) {
                popupContent += `<div class="marker-popup-spbu">🏢 SPBU: ${escapeHtml(nomor_spbu)}</div>`;
            }

            popupContent += `
                    <div class="marker-popup-info">
                        <span>Lat: ${lat.toFixed(4)}</span><br>
                        <span>Lng: ${lng.toFixed(4)}</span>
                    </div>
                    <div class="marker-popup-buttons">
                        <button onclick="toggleMarkerStatus(${id})">Toggle Status</button>
                        <button onclick="editMarker(${id})">Edit</button>
                        <button onclick="deleteMarker(${id})">Delete</button>
                    </div>
                </div>
            `;

            marker.setPopupContent(popupContent);
            marker.closePopup();
            marker.openPopup();
            showNotification('✓ Status updated');
        } else {
            showNotification('Error updating status: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error updating status', true);
    });
}

function distanceMeters(lat1, lng1, lat2, lng2) {
    return L.latLng(lat1, lng1).distanceTo(L.latLng(lat2, lng2));
}

function findNearestCoveringMasjidLocal(latitude, longitude) {
    let nearestMasjid = null;
    let nearestDistance = null;

    Object.keys(masjidData).forEach(id => {
        const masjid = masjidData[id];
        const distance = distanceMeters(latitude, longitude, masjid.latitude, masjid.longitude);
        if (distance <= masjid.radius_meters) {
            if (nearestDistance === null || distance < nearestDistance) {
                nearestMasjid = masjid;
                nearestDistance = distance;
            }
        }
    });

    if (!nearestMasjid) {
        return null;
    }

    return {
        ...nearestMasjid,
        distance_meters: nearestDistance
    };
}

function getMasjidPopupContent(id) {
    const masjid = masjidData[id];
    if (!masjid) {
        return '<div class="feature-popup">Masjid data not found</div>';
    }

    const radiusLabel = Number(masjid.radius_meters).toFixed(0);
    return `
        <div class="feature-popup">
            <div class="feature-popup-name">${escapeHtml(masjid.name)}</div>
            <div class="feature-popup-type">🕌 Masjid</div>
            <div class="feature-popup-info">Radius: ${radiusLabel} m</div>
            <div class="feature-popup-info">Lat: ${masjid.latitude.toFixed(4)} | Lng: ${masjid.longitude.toFixed(4)}</div>
            <div class="feature-popup-actions">
                <button class="edit-action" onclick="editMasjid(${id})">Edit</button>
                <button class="delete-action" onclick="deleteMasjid(${id})">Delete</button>
            </div>
        </div>
    `;
}

function getNeedPointPopupContent(id) {
    const point = needPointData[id];
    if (!point) {
        return '<div class="feature-popup">Point data not found</div>';
    }

    const distanceLabel = Number(point.distance_meters || 0).toFixed(1);
    return `
        <div class="feature-popup">
            <div class="feature-popup-name">${escapeHtml(point.name)}</div>
            <div class="feature-popup-type">♿ Point Berkebutuhan</div>
            <div class="feature-popup-info">Masjid: ${escapeHtml(point.masjid_name || '-')}</div>
            <div class="feature-popup-info">Jarak ke masjid: ${distanceLabel} m</div>
            <div class="feature-popup-info">Lat: ${point.latitude.toFixed(4)} | Lng: ${point.longitude.toFixed(4)}</div>
            <div class="feature-popup-info">Nama Rumah: ${escapeHtml(point.household_name || '-')}</div>
            <div class="feature-popup-info">Kepala Rumah: ${escapeHtml(point.head_name || '-')}</div>
            <div class="feature-popup-info">Keadaan Ekonomi: ${escapeHtml(point.economic_status || '-')}</div>
            <div class="feature-popup-actions">
                <button class="edit-action" onclick="editNeedPoint(${id})">Edit</button>
                <button class="delete-action" onclick="deleteNeedPoint(${id})">Delete</button>
            </div>
        </div>
    `;
}

function updateMasjidCount() {
    const countElement = document.getElementById('masjid-count');
    if (countElement) {
        countElement.textContent = masjidCount;
    }
}

function updateNeedPointCount() {
    const countElement = document.getElementById('need-point-count');
    if (countElement) {
        countElement.textContent = needPointCount;
    }
}

function removeNeedPointsByIds(ids) {
    if (!Array.isArray(ids) || ids.length === 0) {
        return;
    }

    ids.forEach(idValue => {
        const id = Number(idValue);
        if (needPointMarkers[id] && map.hasLayer(needPointMarkers[id])) {
            map.removeLayer(needPointMarkers[id]);
        }
        if (needPointMarkers[id]) {
            delete needPointMarkers[id];
        }
        if (needPointData[id]) {
            delete needPointData[id];
            needPointCount = Math.max(0, needPointCount - 1);
        }
    });

    // remove from allNeedPoints cache
    allNeedPoints = allNeedPoints.filter(p => !ids.includes(String(p.id)) && !ids.includes(p.id));

    // re-render visible layer to keep consistency
    if (needPointLayer) renderVisibleNeedPoints();

    updateNeedPointCount();
}

function normalizeNeedPointRecord(point) {
    return {
        id: Number(point.id),
        name: point.name,
        latitude: Number(point.latitude),
        longitude: Number(point.longitude),
        masjid_id: Number(point.masjid_id),
        household_name: point.household_name || null,
        head_name: point.head_name || null,
        economic_status: point.economic_status || null,
        is_verified: Number(point.is_verified || 0),
        masjid_name: point.masjid_name,
        masjid_latitude: Number(point.masjid_latitude),
        masjid_longitude: Number(point.masjid_longitude),
        radius_meters: Number(point.radius_meters),
        distance_meters: Number(point.distance_meters || 0)
    };
}

function applyNeedPointRecord(record) {
    const normalized = normalizeNeedPointRecord(record);
    const id = normalized.id;
    needPointData[id] = normalized;

    if (needPointMarkers[id]) {
        needPointMarkers[id].setLatLng([normalized.latitude, normalized.longitude]);
        needPointMarkers[id].setPopupContent(getNeedPointPopupContent(id));
    }

    // keep cache in sync
    const idx = allNeedPoints.findIndex(p => Number(p.id) === Number(id));
    if (idx !== -1) {
        allNeedPoints[idx] = normalized;
    } else {
        allNeedPoints.push(normalized);
    }
}

function loadMasjids() {
    fetch('api/get_masjids.php')
        .then(response => response.json())
        .then(data => {
            if (data.success && data.masjids) {
                Object.keys(masjidMarkers).forEach(id => {
                    if (map.hasLayer(masjidMarkers[id])) {
                        map.removeLayer(masjidMarkers[id]);
                    }
                });
                Object.keys(masjidCircles).forEach(id => {
                    if (map.hasLayer(masjidCircles[id])) {
                        map.removeLayer(masjidCircles[id]);
                    }
                });

                masjidMarkers = {};
                masjidCircles = {};
                masjidData = {};
                masjidCount = 0;

                data.masjids.forEach(masjid => {
                    displayMasjid(masjid);
                });

                updateMasjidCount();
            }
        })
        .catch(error => console.error('Error loading masjids:', error));
}

function displayMasjid(masjid) {
    const id = Number(masjid.id);
    const radiusMeters = Number(masjid.radius_meters || 500);

    masjidData[id] = {
        id: id,
        name: masjid.name,
        latitude: Number(masjid.latitude),
        longitude: Number(masjid.longitude),
        radius_meters: radiusMeters,
        need_point_count: Number(masjid.need_point_count || 0)
    };

    const marker = L.marker([masjidData[id].latitude, masjidData[id].longitude], {
        draggable: true,
        icon: markerIcons.masjid
    }).addTo(map);

    const circle = L.circle([masjidData[id].latitude, masjidData[id].longitude], {
        radius: radiusMeters,
        color: '#1976d2',
        fillColor: '#64b5f6',
        fillOpacity: 0.15,
        weight: 2,
        interactive: false
    }).addTo(map);

    marker.bindPopup(getMasjidPopupContent(id));

    marker.on('dragend', function() {
        const oldLat = masjidData[id].latitude;
        const oldLng = masjidData[id].longitude;
        const newPosition = marker.getLatLng();

        fetch('api/update_masjid.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                id: id,
                latitude: newPosition.lat,
                longitude: newPosition.lng
            })
        })
        .then(response => response.json())
        .then(data => {
            if (data.success && data.masjid) {
                masjidData[id].name = data.masjid.name;
                masjidData[id].latitude = Number(data.masjid.latitude);
                masjidData[id].longitude = Number(data.masjid.longitude);
                masjidData[id].radius_meters = Number(data.masjid.radius_meters);

                marker.setLatLng([masjidData[id].latitude, masjidData[id].longitude]);
                marker.setPopupContent(getMasjidPopupContent(id));

                circle.setLatLng([masjidData[id].latitude, masjidData[id].longitude]);
                circle.setRadius(masjidData[id].radius_meters);

                if (Array.isArray(data.deleted_need_point_ids) && data.deleted_need_point_ids.length > 0) {
                    removeNeedPointsByIds(data.deleted_need_point_ids);
                    showNotification('✓ Masjid dipindah, ' + data.deleted_need_point_ids.length + ' point berkebutuhan dihapus otomatis');
                } else {
                    showNotification('✓ Lokasi masjid berhasil diperbarui');
                }
            } else {
                marker.setLatLng([oldLat, oldLng]);
                showNotification('Error updating masjid: ' + (data.error || 'unknown error'), true);
            }
        })
        .catch(error => {
            console.error('Error:', error);
            marker.setLatLng([oldLat, oldLng]);
            showNotification('Error updating masjid location', true);
        });
    });

    masjidMarkers[id] = marker;
    masjidCircles[id] = circle;
    masjidCount++;
}

function openMasjidModal(coords) {
    const modal = document.getElementById('masjid-modal');
    const form = document.getElementById('masjid-form');
    const latInput = document.getElementById('masjid-latitude');
    const lngInput = document.getElementById('masjid-longitude');
    const info = document.getElementById('masjid-form-info');

    if (!modal || !form || !latInput || !lngInput) {
        return;
    }

    form.reset();

    if (coords) {
        latInput.value = coords.lat.toFixed(6);
        lngInput.value = coords.lng.toFixed(6);
        latInput.readOnly = true;
        lngInput.readOnly = true;
        if (info) {
            info.textContent = 'Koordinat masjid diisi otomatis dari klik peta.';
            info.classList.add('show');
        }
    } else {
        latInput.value = '';
        lngInput.value = '';
        latInput.readOnly = false;
        lngInput.readOnly = false;
        if (info) {
            info.classList.remove('show');
        }
    }

    modal.classList.add('show');
    document.getElementById('masjid-name').focus();
}

function closeMasjidModal() {
    const modal = document.getElementById('masjid-modal');
    if (modal) {
        modal.classList.remove('show');
    }
}

function submitMasjidForm() {
    const name = document.getElementById('masjid-name').value.trim();
    const latitude = parseFloat(document.getElementById('masjid-latitude').value);
    const longitude = parseFloat(document.getElementById('masjid-longitude').value);
    const radiusValue = document.getElementById('masjid-radius').value.trim();

    if (!name) {
        showNotification('Nama masjid wajib diisi', true);
        return;
    }

    if (isNaN(latitude) || latitude < -90 || latitude > 90) {
        showNotification('Latitude masjid tidak valid', true);
        return;
    }

    if (isNaN(longitude) || longitude < -180 || longitude > 180) {
        showNotification('Longitude masjid tidak valid', true);
        return;
    }

    if (radiusValue !== '') {
        const radius = parseFloat(radiusValue);
        if (isNaN(radius) || radius < 50 || radius > 5000) {
            showNotification('Radius harus 50-5000 meter', true);
            return;
        }
    }

    addMasjid(name, latitude, longitude, radiusValue);
}

function addMasjid(name, latitude, longitude, radiusValue) {
    fetch('api/save_masjid.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            name: name,
            latitude: latitude,
            longitude: longitude,
            radius_meters: radiusValue === '' ? null : parseFloat(radiusValue)
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success && data.masjid) {
            displayMasjid(data.masjid);
            updateMasjidCount();
            closeMasjidModal();
            showNotification('✓ Masjid berhasil ditambahkan');
        } else {
            showNotification('Error adding masjid: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error adding masjid', true);
    });
}

function editMasjid(id) {
    if (!masjidData[id]) {
        showNotification('Data masjid tidak ditemukan', true);
        return;
    }

    const masjid = masjidData[id];
    currentEditingMasjidId = id;

    document.getElementById('edit-masjid-name').value = masjid.name;
    document.getElementById('edit-masjid-latitude').value = masjid.latitude;
    document.getElementById('edit-masjid-longitude').value = masjid.longitude;
    document.getElementById('edit-masjid-radius').value = masjid.radius_meters;

    const modal = document.getElementById('edit-masjid-modal');
    modal.classList.add('show');
    document.getElementById('edit-masjid-name').focus();
}

function closeEditMasjidModal() {
    const modal = document.getElementById('edit-masjid-modal');
    if (modal) {
        modal.classList.remove('show');
    }
    currentEditingMasjidId = null;
}

function saveMasjidEdit() {
    if (!currentEditingMasjidId) {
        showNotification('Tidak ada masjid yang dipilih', true);
        return;
    }

    const name = document.getElementById('edit-masjid-name').value.trim();
    const latitude = parseFloat(document.getElementById('edit-masjid-latitude').value);
    const longitude = parseFloat(document.getElementById('edit-masjid-longitude').value);
    const radiusValue = document.getElementById('edit-masjid-radius').value.trim();

    if (!name) {
        showNotification('Nama masjid wajib diisi', true);
        return;
    }

    if (isNaN(latitude) || latitude < -90 || latitude > 90) {
        showNotification('Latitude masjid tidak valid', true);
        return;
    }

    if (isNaN(longitude) || longitude < -180 || longitude > 180) {
        showNotification('Longitude masjid tidak valid', true);
        return;
    }

    if (radiusValue !== '') {
        const radius = parseFloat(radiusValue);
        if (isNaN(radius) || radius < 50 || radius > 5000) {
            showNotification('Radius harus 50-5000 meter', true);
            return;
        }
    }

    fetch('api/update_masjid.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            id: currentEditingMasjidId,
            name: name,
            latitude: latitude,
            longitude: longitude,
            radius_meters: radiusValue === '' ? null : parseFloat(radiusValue)
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success && data.masjid) {
            const id = Number(currentEditingMasjidId);
            masjidData[id].name = data.masjid.name;
            masjidData[id].latitude = Number(data.masjid.latitude);
            masjidData[id].longitude = Number(data.masjid.longitude);
            masjidData[id].radius_meters = Number(data.masjid.radius_meters);

            if (masjidMarkers[id]) {
                masjidMarkers[id].setLatLng([masjidData[id].latitude, masjidData[id].longitude]);
                masjidMarkers[id].setPopupContent(getMasjidPopupContent(id));
            }

            if (masjidCircles[id]) {
                masjidCircles[id].setLatLng([masjidData[id].latitude, masjidData[id].longitude]);
                masjidCircles[id].setRadius(masjidData[id].radius_meters);
            }

            if (Array.isArray(data.deleted_need_point_ids) && data.deleted_need_point_ids.length > 0) {
                removeNeedPointsByIds(data.deleted_need_point_ids);
                showNotification('✓ Masjid diperbarui, ' + data.deleted_need_point_ids.length + ' point berkebutuhan dihapus otomatis');
            } else {
                showNotification('✓ Masjid berhasil diperbarui');
            }

            closeEditMasjidModal();
        } else {
            showNotification('Error updating masjid: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error updating masjid', true);
    });
}

function deleteMasjid(id) {
    if (!confirm('Apakah Anda yakin ingin menghapus masjid ini?')) {
        return;
    }

    fetch('api/delete_masjid.php', {
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ id: id })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            if (masjidMarkers[id] && map.hasLayer(masjidMarkers[id])) {
                map.removeLayer(masjidMarkers[id]);
            }
            if (masjidCircles[id] && map.hasLayer(masjidCircles[id])) {
                map.removeLayer(masjidCircles[id]);
            }

            delete masjidMarkers[id];
            delete masjidCircles[id];
            if (masjidData[id]) {
                delete masjidData[id];
                masjidCount = Math.max(0, masjidCount - 1);
            }
            updateMasjidCount();

            if (Array.isArray(data.deleted_need_point_ids) && data.deleted_need_point_ids.length > 0) {
                removeNeedPointsByIds(data.deleted_need_point_ids);
                showNotification('✓ Masjid dihapus, ' + data.deleted_need_point_ids.length + ' point berkebutuhan ikut dihapus');
            } else {
                showNotification('✓ Masjid berhasil dihapus');
            }
        } else {
            showNotification('Error deleting masjid: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error deleting masjid', true);
    });
}

function loadNeedPoints() {
    fetch('api/get_need_points.php')
        .then(response => response.json())
        .then(data => {
            if (data.success && data.points) {
                // store normalized points for viewport-driven rendering
                allNeedPoints = data.points.map(p => normalizeNeedPointRecord(p));
                // detect device capability and set threshold (allow stored override)
                const stored = getStoredRenderingMode();
                renderingMode = stored ? stored : detectRenderingMode();
                if (renderingMode === 'high') visibleMarkerThreshold = 3000;
                else if (renderingMode === 'medium') visibleMarkerThreshold = 1500;
                else visibleMarkerThreshold = 600;

                // initialize layer container
                if (needPointLayer && map && map.hasLayer(needPointLayer)) {
                    map.removeLayer(needPointLayer);
                }
                needPointLayer = L.layerGroup().addTo(map);

                // render only visible points and update on view changes
                renderVisibleNeedPoints();
                // debounce handlers
                let debounceTimer = null;
                map.off('moveend', renderVisibleNeedPoints);
                map.off('zoomend', renderVisibleNeedPoints);
                map.on('moveend', function() {
                    clearTimeout(debounceTimer);
                    debounceTimer = setTimeout(renderVisibleNeedPoints, 120);
                });
                map.on('zoomend', function() {
                    clearTimeout(debounceTimer);
                    debounceTimer = setTimeout(renderVisibleNeedPoints, 120);
                });
            }
        })
        .catch(error => console.error('Error loading need points:', error));
}

function renderVisibleNeedPoints() {
    if (!map || !Array.isArray(allNeedPoints)) return;

    const bounds = map.getBounds().pad(0.25);
    const visible = allNeedPoints.filter(p => bounds.contains([p.latitude, p.longitude]));

    // Clear previous layer
    needPointLayer.clearLayers();
    needPointMarkers = {};
    needPointData = {};
    needPointCount = 0;

    if (visible.length === 0) {
        updateNeedPointCount();
        return;
    }

    // If number of visible points is small, use full markers with popups
    if (visible.length <= visibleMarkerThreshold) {
        visible.forEach(p => {
            const id = p.id;
            needPointData[id] = p;
            const marker = L.marker([p.latitude, p.longitude], { icon: markerIcons.need });
            marker.bindPopup(getNeedPointPopupContent(id));
            marker.on('click', () => {
                marker.openPopup();
            });
            needPointLayer.addLayer(marker);
            needPointMarkers[id] = marker;
            needPointCount++;
        });
    } else {
        // Heavy view: use canvas-rendered circle markers for performance and no per-feature popups
        const canvasRenderer = L.canvas({ padding: 0.5 });
        visible.forEach(p => {
            const id = p.id;
            needPointData[id] = p;
            const circle = L.circleMarker([p.latitude, p.longitude], {
                radius: 4,
                fillColor: '#ff9800',
                color: '#ffffff',
                weight: 1,
                opacity: 0.9,
                fillOpacity: 0.9,
                renderer: canvasRenderer
            });
            needPointLayer.addLayer(circle);
            needPointMarkers[id] = circle;
            needPointCount++;
        });

        // Add a light click handler on the map to show nearest point popup when user clicks
        map.off('click', heavyModeMapClickHandler);
        map.on('click', heavyModeMapClickHandler);
    }

    updateNeedPointCount();
}

function heavyModeMapClickHandler(e) {
    // find nearest point within a small pixel radius
    const clickPoint = map.latLngToContainerPoint(e.latlng);
    let nearest = null;
    let minPx = 40; // pixels
    Object.values(needPointData).forEach(p => {
        const pt = map.latLngToContainerPoint([p.latitude, p.longitude]);
        const dx = pt.x - clickPoint.x;
        const dy = pt.y - clickPoint.y;
        const d = Math.sqrt(dx*dx + dy*dy);
        if (d < minPx) {
            minPx = d;
            nearest = p;
        }
    });

    if (nearest) {
        // show popup at the point
        const popup = L.popup({ maxWidth: 300 })
            .setLatLng([nearest.latitude, nearest.longitude])
            .setContent(getNeedPointPopupContent(nearest.id));
        popup.openOn(map);
    }
}

function detectRenderingMode() {
    try {
        const cores = navigator.hardwareConcurrency || 2;
        const dpr = window.devicePixelRatio || 1;
        if (cores >= 8 && dpr <= 2) return 'high';
        if (cores >= 4) return 'medium';
        return 'low';
    } catch (e) {
        return 'medium';
    }
}

function openNeedPointModal(coords) {
    const modal = document.getElementById('need-point-modal');
    const form = document.getElementById('need-point-form');
    const latInput = document.getElementById('need-point-latitude');
    const lngInput = document.getElementById('need-point-longitude');
    const info = document.getElementById('need-point-form-info');

// Management household state and functions
let managementHouseholds = [];
let currentMgmtPage = 0;
const MGMT_PAGE_SIZE = 10;

function loadManagementHouseholds() {
    fetch('api/get_households.php?limit=1000')
        .then(r => r.json())
        .then(data => {
            if (data.success && Array.isArray(data.households)) {
                managementHouseholds = data.households;
                currentMgmtPage = 0;
                renderManagementHouseholdPage(0);
            } else {
                managementHouseholds = [];
                renderManagementHouseholdPage(0);
            }
        })
        .catch(err => {
            console.error('Error loading management households', err);
            managementHouseholds = [];
            renderManagementHouseholdPage(0);
        });
}

function renderManagementHouseholdPage(pageIndex) {
    if (!Array.isArray(managementHouseholds)) managementHouseholds = [];
    const total = managementHouseholds.length;
    const maxPage = Math.max(0, Math.ceil(total / MGMT_PAGE_SIZE) - 1);
    if (pageIndex < 0) pageIndex = 0;
    if (pageIndex > maxPage) pageIndex = maxPage;
    currentMgmtPage = pageIndex;

    const start = pageIndex * MGMT_PAGE_SIZE;
    const slice = managementHouseholds.slice(start, start + MGMT_PAGE_SIZE);
    const container = document.getElementById('management-household-list');
    const pager = document.getElementById('management-household-pager');
    if (!container) return;
    container.innerHTML = '';

    if (slice.length === 0) {
        container.innerHTML = '<div style="color: rgba(255,255,255,0.7); padding: 12px;">No households available</div>';
    } else {
        slice.forEach(h => {
            const div = document.createElement('div');
            div.className = 'management-household-item';
            const code = escapeHtml(h.household_code || '-');
            const head = escapeHtml(h.head_name || '-');
            const status = escapeHtml(h.verification_status || '-');
            const meta = `Lat: ${Number(h.latitude||0).toFixed(4)} Lng: ${Number(h.longitude||0).toFixed(4)}`;
            div.innerHTML = `<div class="hh-title">${code} • ${head}</div><div class="hh-meta">${meta}</div><div class="hh-meta">Status: ${status}</div>`;
            div.onclick = () => { openHouseholdModal(); };
            container.appendChild(div);
        });
    }

    if (pager) pager.textContent = `Page ${pageIndex + 1} / ${maxPage + 1} • ${total} households`;
}

    if (!modal || !form || !latInput || !lngInput) {
        return;
    }

    form.reset();

    if (coords) {
        latInput.value = coords.lat.toFixed(6);
        lngInput.value = coords.lng.toFixed(6);
        latInput.readOnly = true;
        lngInput.readOnly = true;
        if (info) {
            info.textContent = 'Koordinat point berkebutuhan diisi otomatis dari klik peta.';
            info.classList.add('show');
        }
    } else {
        latInput.value = '';
        lngInput.value = '';
        latInput.readOnly = false;
        lngInput.readOnly = false;
        if (info) {
            info.classList.remove('show');
        }
    }

    modal.classList.add('show');
    document.getElementById('need-point-name').focus();
}

function closeNeedPointModal() {
    const modal = document.getElementById('need-point-modal');
    if (modal) {
        modal.classList.remove('show');
    }
}

function submitNeedPointForm() {
    const name = document.getElementById('need-point-name').value.trim();
    const latitude = parseFloat(document.getElementById('need-point-latitude').value);
    const longitude = parseFloat(document.getElementById('need-point-longitude').value);

    const householdName = document.getElementById('need-point-household') ? document.getElementById('need-point-household').value.trim() : '';
    const headName = document.getElementById('need-point-head') ? document.getElementById('need-point-head').value.trim() : '';
    const economicStatus = document.getElementById('need-point-economic') ? document.getElementById('need-point-economic').value : '';

    if (!name) {
        showNotification('Nama point berkebutuhan wajib diisi', true);
        return;
    }

    if (isNaN(latitude) || latitude < -90 || latitude > 90) {
        showNotification('Latitude point berkebutuhan tidak valid', true);
        return;
    }

    if (isNaN(longitude) || longitude < -180 || longitude > 180) {
        showNotification('Longitude point berkebutuhan tidak valid', true);
        return;
    }

    if (!findNearestCoveringMasjidLocal(latitude, longitude)) {
        showNotification('Point berkebutuhan harus berada dalam radius masjid', true);
        return;
    }

    addNeedPoint(name, latitude, longitude, householdName, headName, economicStatus);
}

function addNeedPoint(name, latitude, longitude) {
    // legacy signature support: addNeedPoint(name, lat, lng, household, head, economic)
    const household = arguments.length >= 4 ? arguments[3] : '';
    const head = arguments.length >= 5 ? arguments[4] : '';
    const economic = arguments.length >= 6 ? arguments[5] : '';

    fetch('api/save_need_point.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            name: name,
            latitude: latitude,
            longitude: longitude,
            household_name: household,
            head_name: head,
            economic_status: economic
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success && data.point) {
            // add to local cache and re-render visible points
            const p = normalizeNeedPointRecord(data.point);
            allNeedPoints.push(p);
            renderVisibleNeedPoints();
            closeNeedPointModal();
            showNotification('✓ Point berkebutuhan berhasil ditambahkan');
        } else {
            showNotification('Error adding point berkebutuhan: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error adding point berkebutuhan', true);
    });
}

function editNeedPoint(id) {
    if (!needPointData[id]) {
        showNotification('Data point berkebutuhan tidak ditemukan', true);
        return;
    }

    const point = needPointData[id];
    currentEditingNeedPointId = id;

    document.getElementById('edit-need-point-name').value = point.name;
    document.getElementById('edit-need-point-latitude').value = point.latitude;
    document.getElementById('edit-need-point-longitude').value = point.longitude;
    document.getElementById('edit-need-point-masjid').value = point.masjid_name || '-';
    // populate new household fields
    const hh = point.household_name || '';
    const head = point.head_name || '';
    const econ = point.economic_status || 'rentan';
    const hhInput = document.getElementById('edit-need-point-household');
    const headInput = document.getElementById('edit-need-point-head');
    const econInput = document.getElementById('edit-need-point-economic');
    if (hhInput) hhInput.value = hh;
    if (headInput) headInput.value = head;
    if (econInput) econInput.value = econ;

    const modal = document.getElementById('edit-need-point-modal');
    modal.classList.add('show');
    document.getElementById('edit-need-point-name').focus();
}

function closeEditNeedPointModal() {
    const modal = document.getElementById('edit-need-point-modal');
    if (modal) {
        modal.classList.remove('show');
    }
    currentEditingNeedPointId = null;
}

function saveNeedPointEdit() {
    if (!currentEditingNeedPointId) {
        showNotification('Tidak ada point berkebutuhan yang dipilih', true);
        return;
    }

    const name = document.getElementById('edit-need-point-name').value.trim();
    const latitude = parseFloat(document.getElementById('edit-need-point-latitude').value);
    const longitude = parseFloat(document.getElementById('edit-need-point-longitude').value);

    if (!name) {
        showNotification('Nama point berkebutuhan wajib diisi', true);
        return;
    }

    if (isNaN(latitude) || latitude < -90 || latitude > 90) {
        showNotification('Latitude point berkebutuhan tidak valid', true);
        return;
    }

    if (isNaN(longitude) || longitude < -180 || longitude > 180) {
        showNotification('Longitude point berkebutuhan tidak valid', true);
        return;
    }

    if (!findNearestCoveringMasjidLocal(latitude, longitude)) {
        showNotification('Point berkebutuhan harus berada dalam radius masjid', true);
        return;
    }

    const householdName = document.getElementById('edit-need-point-household') ? document.getElementById('edit-need-point-household').value.trim() : '';
    const headName = document.getElementById('edit-need-point-head') ? document.getElementById('edit-need-point-head').value.trim() : '';
    const economicStatus = document.getElementById('edit-need-point-economic') ? document.getElementById('edit-need-point-economic').value : '';

    fetch('api/update_need_point.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            id: currentEditingNeedPointId,
            name: name,
            latitude: latitude,
            longitude: longitude,
            household_name: householdName,
            head_name: headName,
            economic_status: economicStatus
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success && data.point) {
            applyNeedPointRecord(data.point);
            closeEditNeedPointModal();
            showNotification('✓ Point berkebutuhan berhasil diperbarui');
        } else {
            showNotification('Error updating point berkebutuhan: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error updating point berkebutuhan', true);
    });
}

function deleteNeedPoint(id) {
    if (!confirm('Apakah Anda yakin ingin menghapus point berkebutuhan ini?')) {
        return;
    }

    fetch('api/delete_need_point.php', {
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ id: id })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            removeNeedPointsByIds([id]);
            showNotification('✓ Point berkebutuhan berhasil dihapus');
        } else {
            showNotification('Error deleting point berkebutuhan: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error deleting point berkebutuhan', true);
    });
}

// ============ HOUSEHOLD / ASSISTANCE / VERIFICATION (PHASE A) ============

// Toggle household panel visibility in peta tab
function toggleHouseholdPanel() {
    const panel = document.getElementById('household-panel-wrapper');
    if (panel) {
        panel.classList.toggle('visible');
    }
}

function refreshHouseholdPanel() {
    loadHouseholdsForPanel();
    loadHouseholdSummary();
    loadHouseholdScoreSummary();
    loadHouseholdPriorityRanking();
}

function openHouseholdModal() {
    const modal = document.getElementById('household-modal');
    const form = document.getElementById('household-form');
    const latInput = document.getElementById('household-latitude');
    const lngInput = document.getElementById('household-longitude');

    if (!modal || !form) {
        return;
    }

    form.reset();

    if (latInput && lngInput && map) {
        const center = map.getCenter();
        latInput.value = center.lat.toFixed(6);
        lngInput.value = center.lng.toFixed(6);
    }

    modal.classList.add('show');

    const headNameInput = document.getElementById('household-head-name');
    if (headNameInput) {
        headNameInput.focus();
    }
}

function closeHouseholdModal() {
    const modal = document.getElementById('household-modal');
    if (modal) {
        modal.classList.remove('show');
    }
}

function openAssistanceModal(preselectedHouseholdId = null) {
    // Always populate household select options; if none exist the form will still open
    populateHouseholdSelectOptions();

    const modal = document.getElementById('assistance-modal');
    const form = document.getElementById('assistance-form');
    const dateInput = document.getElementById('assistance-date');

    if (!modal || !form) {
        return;
    }

    form.reset();
    if (dateInput) {
        dateInput.value = new Date().toISOString().slice(0, 10);
    }

    const householdSelect = document.getElementById('assistance-household-id');
    if (householdSelect && preselectedHouseholdId) {
        householdSelect.value = String(preselectedHouseholdId);
    }

    updateAssistanceModalSummary();

    modal.classList.add('show');

    if (householdSelect) {
        householdSelect.focus();
    }
}

function updateAssistanceModalSummary() {
    const select = document.getElementById('assistance-household-id');
    const labelEl = document.getElementById('assistance-selected-household-label');
    const metaEl = document.getElementById('assistance-selected-household-meta');
    const selectedId = select ? String(select.value || '') : '';
    const selectedHousehold = Array.isArray(households)
        ? households.find(item => String(item.id) === selectedId)
        : null;

    if (labelEl) {
        labelEl.textContent = selectedHousehold
            ? `${selectedHousehold.household_code || 'HH'} - ${selectedHousehold.head_name || 'Tanpa nama'}`
            : 'Pilih household';
    }

    if (metaEl) {
        metaEl.textContent = selectedHousehold
            ? `${selectedHousehold.verification_status || 'unverified'} • ${selectedHousehold.latitude || '-'}, ${selectedHousehold.longitude || '-'}`
            : 'Data akan terisi otomatis jika tersedia.';
    }
}

function createHouseholdFromNeedPoint(point) {
    return new Promise((resolve, reject) => {
        if (!point || !point.latitude || !point.longitude) {
            reject(new Error('Invalid need point data'));
            return;
        }

        const headName = point.head_name || point.household_name || ('Keluarga ' + Math.random().toString(16).slice(2,8));

        const payload = {
            head_name: headName,
            latitude: Number(point.latitude),
            longitude: Number(point.longitude),
            need_point_id: Number(point.id || 0),
            economic_status: point.economic_status || 'unknown',
            verification_status: Number(point.is_verified || 0) === 1 ? 'field_verified' : 'unverified'
        };

        fetch('api/save_household.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(payload)
        })
        .then(r => r.json())
        .then(data => {
            if (data && data.success && data.household) {
                // Insert into local households cache for immediate use
                households = households || [];
                households.unshift(data.household);
                resolve(data.household);
            } else {
                reject(new Error(data && data.error ? data.error : 'Failed to create household'));
            }
        })
        .catch(err => reject(err));
    });
}

function closeAssistanceModal() {
    const modal = document.getElementById('assistance-modal');
    if (modal) {
        modal.classList.remove('show');
    }
}

function openVerificationModal() {
    if (!Array.isArray(households) || households.length === 0) {
        showNotification('Belum ada household. Tambahkan household terlebih dahulu.', true);
        return;
    }

    populateHouseholdSelectOptions();

    const modal = document.getElementById('verification-modal');
    const form = document.getElementById('verification-form');

    if (!modal || !form) {
        return;
    }

    form.reset();
    modal.classList.add('show');

    const householdSelect = document.getElementById('verification-household-id');
    if (householdSelect) {
        householdSelect.focus();
    }
}

function closeVerificationModal() {
    const modal = document.getElementById('verification-modal');
    if (modal) {
        modal.classList.remove('show');
    }
}

function loadHouseholdsForPanel() {
    const statusFilter = document.getElementById('household-filter-status');
    const selectedStatus = statusFilter ? statusFilter.value : '';

    let url = 'api/get_households.php?limit=200';
    if (selectedStatus) {
        url += '&verification_status=' + encodeURIComponent(selectedStatus);
    }

    fetch(url)
        .then(response => response.json())
        .then(data => {
            if (data.success && Array.isArray(data.households)) {
                households = data.households;
                renderHouseholdList(households);
                populateHouseholdSelectOptions();
            } else {
                households = [];
                renderHouseholdList([]);
            }
        })
        .catch(error => {
            console.error('Error loading households:', error);
            households = [];
            renderHouseholdList([]);
            showNotification('Error loading household data', true);
        });
}

function loadHouseholdSummary() {
    fetch('api/get_household_summary.php')
        .then(response => response.json())
        .then(data => {
            if (data.success && data.summary) {
                householdSummary = data.summary;
                updateHouseholdSummaryUI(householdSummary);
            }
        })
        .catch(error => {
            console.error('Error loading household summary:', error);
        });
}

function updateHouseholdSummaryUI(summary) {
    const totalHouseholds = Number(summary?.totals?.total_households || 0);
    const assistedHouseholds = Number(summary?.assistance?.assisted_households || 0);
    const verifiedCount = Number(summary?.totals?.field_verified_count || 0) + Number(summary?.totals?.admin_approved_count || 0);

    const totalEl = document.getElementById('household-total-count');
    const assistedEl = document.getElementById('household-assisted-count');
    const verifiedEl = document.getElementById('household-verified-count');

    if (totalEl) totalEl.textContent = totalHouseholds;
    if (assistedEl) assistedEl.textContent = assistedHouseholds;
    if (verifiedEl) verifiedEl.textContent = verifiedCount;
}

function populateHouseholdSelectOptions() {
    const selectIds = ['assistance-household-id', 'verification-household-id'];

    selectIds.forEach(selectId => {
        const select = document.getElementById(selectId);
        if (!select) {
            return;
        }

        const previousValue = select.value;
        let options = '<option value="">Pilih household...</option>';

        households.forEach(household => {
            const id = Number(household.id);
            const code = household.household_code || 'HH';
            const headName = household.head_name || '-';
            const label = escapeHtml(String(code + ' - ' + headName));
            options += `<option value="${id}">${label}</option>`;
        });

        select.innerHTML = options;

        if (previousValue && households.some(h => String(h.id) === String(previousValue))) {
            select.value = previousValue;
        }
    });
}

function getVerificationStatusLabel(status) {
    const labels = {
        unverified: 'Unverified',
        field_verified: 'Field Verified',
        admin_approved: 'Approved',
        needs_review: 'Needs Review',
        rejected: 'Rejected'
    };

    return labels[status] || status;
}

function formatRupiah(value) {
    const numberValue = Number(value || 0);
    return 'Rp ' + new Intl.NumberFormat('id-ID').format(Math.round(numberValue));
}

function renderHouseholdList(householdItems) {
    const listContainer = document.getElementById('households-list');
    if (!listContainer) {
        return;
    }

    if (!Array.isArray(householdItems) || householdItems.length === 0) {
        listContainer.innerHTML = '<div class="household-empty">Belum ada data household.</div>';
        return;
    }

    const html = householdItems.slice(0, 30).map(household => {
        const status = String(household.verification_status || 'unverified');
        const statusClass = status.replace(/[^a-z_]/g, '');
        const statusLabel = escapeHtml(getVerificationStatusLabel(status));

        const householdCode = escapeHtml(String(household.household_code || '-'));
        const headName = escapeHtml(String(household.head_name || '-'));
        const incomeLabel = escapeHtml(formatRupiah(household.monthly_income));
        const dependentsLabel = Number(household.dependents_count || 0);
        const assistanceCountLabel = Number(household.assistance_count || 0);
        const masjidName = escapeHtml(String(household.masjid_name || '-'));

        return `
            <div class="household-item">
                <div class="household-item-header">
                    <span class="household-code">${householdCode}</span>
                    <span class="household-status ${statusClass}">${statusLabel}</span>
                </div>
                <div class="household-name">${headName}</div>
                <div class="household-meta">
                    <span>Pendapatan: ${incomeLabel}</span>
                    <span>Tanggungan: ${dependentsLabel}</span>
                    <span>Bantuan tercatat: ${assistanceCountLabel}</span>
                    <span>Masjid: ${masjidName}</span>
                </div>
            </div>
        `;
    }).join('');

    listContainer.innerHTML = html;
}

function submitHouseholdForm() {
    const code = document.getElementById('household-code').value.trim();
    const headName = document.getElementById('household-head-name').value.trim();
    const nik = document.getElementById('household-nik').value.trim();
    const latitudeRaw = document.getElementById('household-latitude').value;
    const longitudeRaw = document.getElementById('household-longitude').value;
    const monthlyIncomeRaw = document.getElementById('household-monthly-income').value;
    const dependentsRaw = document.getElementById('household-dependents-count').value;
    const housingScoreRaw = document.getElementById('household-housing-score').value;
    const employmentStatus = document.getElementById('household-employment-status').value;
    const verificationStatus = document.getElementById('household-verification-status').value;
    const vulnerabilityNotes = document.getElementById('household-vulnerability-notes').value.trim();

    const latitude = parseFloat(latitudeRaw);
    const longitude = parseFloat(longitudeRaw);

    if (!headName) {
        showNotification('Nama kepala keluarga wajib diisi', true);
        return;
    }

    if (isNaN(latitude) || latitude < -90 || latitude > 90) {
        showNotification('Latitude tidak valid', true);
        return;
    }

    if (isNaN(longitude) || longitude < -180 || longitude > 180) {
        showNotification('Longitude tidak valid', true);
        return;
    }

    const payload = {
        head_name: headName,
        latitude: latitude,
        longitude: longitude,
        monthly_income: monthlyIncomeRaw === '' ? null : parseFloat(monthlyIncomeRaw),
        dependents_count: dependentsRaw === '' ? null : parseInt(dependentsRaw, 10),
        housing_condition_score: housingScoreRaw === '' ? null : parseInt(housingScoreRaw, 10),
        employment_status: employmentStatus,
        verification_status: verificationStatus,
        vulnerability_notes: vulnerabilityNotes || null
    };

    if (code) payload.household_code = code;
    if (nik) payload.nik = nik;

    fetch('api/save_household.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(payload)
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            closeHouseholdModal();
            refreshHouseholdPanel();
            showNotification('✓ Household berhasil ditambahkan');
        } else {
            showNotification('Error menambah household: ' + (data.error || 'unknown error'), true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error menambah household', true);
    });
}

function submitAssistanceForm() {
    const householdIdRaw = document.getElementById('assistance-household-id').value;
    const assistanceType = document.getElementById('assistance-type').value;
    const assistanceValueRaw = document.getElementById('assistance-value').value;
    const assistanceFrequency = document.getElementById('assistance-frequency').value;
    const distributionDate = document.getElementById('assistance-date').value;
    const deliveryStatus = document.getElementById('assistance-delivery-status').value;
    const deliveredBy = document.getElementById('assistance-delivered-by').value.trim();
    const notes = document.getElementById('assistance-notes').value.trim();

    if (!householdIdRaw || isNaN(parseInt(householdIdRaw, 10))) {
        showNotification('Household wajib dipilih', true);
        return;
    }

    if (!distributionDate) {
        showNotification('Tanggal distribusi wajib diisi', true);
        return;
    }

    const payload = {
        household_id: parseInt(householdIdRaw, 10),
        assistance_type: assistanceType,
        assistance_value: assistanceValueRaw === '' ? 0 : parseFloat(assistanceValueRaw),
        assistance_frequency: assistanceFrequency,
        distribution_date: distributionDate,
        delivery_status: deliveryStatus,
        delivered_by: deliveredBy || null,
        notes: notes || null
    };

    fetch('api/save_assistance_distribution.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(payload)
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            closeAssistanceModal();
            refreshHouseholdPanel();
            showNotification('✓ Data bantuan berhasil disimpan');
        } else {
            showNotification('Error menyimpan bantuan: ' + (data.error || 'unknown error'), true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error menyimpan bantuan', true);
    });
}

function submitVerificationForm() {
    const householdIdRaw = document.getElementById('verification-household-id').value;
    const verificationStatus = document.getElementById('verification-status').value;
    const verifierRole = document.getElementById('verification-verifier-role').value.trim();
    const verifierName = document.getElementById('verification-verifier-name').value.trim();
    const evidenceCountRaw = document.getElementById('verification-evidence-count').value;
    const confidenceScoreRaw = document.getElementById('verification-confidence-score').value;
    const fieldNote = document.getElementById('verification-field-note').value.trim();

    if (!householdIdRaw || isNaN(parseInt(householdIdRaw, 10))) {
        showNotification('Household wajib dipilih', true);
        return;
    }

    if (!verifierName) {
        showNotification('Nama verifikator wajib diisi', true);
        return;
    }

    if (confidenceScoreRaw !== '') {
        const confidence = parseFloat(confidenceScoreRaw);
        if (isNaN(confidence) || confidence < 0 || confidence > 1) {
            showNotification('Skor kepercayaan data harus di antara 0 sampai 1', true);
            return;
        }
    }

    const payload = {
        household_id: parseInt(householdIdRaw, 10),
        verification_status: verificationStatus,
        verifier_name: verifierName,
        verifier_role: verifierRole || null,
        evidence_photo_count: evidenceCountRaw === '' ? 0 : parseInt(evidenceCountRaw, 10),
        data_confidence_score: confidenceScoreRaw === '' ? null : parseFloat(confidenceScoreRaw),
        field_note: fieldNote || null
    };

    fetch('api/save_verification_log.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(payload)
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            closeVerificationModal();
            refreshHouseholdPanel();
            showNotification('✓ Verifikasi berhasil disimpan');
        } else {
            showNotification('Error menyimpan verifikasi: ' + (data.error || 'unknown error'), true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error menyimpan verifikasi', true);
    });
}

function computeHouseholdScores() {
    fetch('api/compute_household_scores.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({})
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            const computedCount = Number(data.computed_count || 0);
            loadHouseholdScoreSummary();
            loadManagementScorePreview();
            loadHouseholdPriorityRanking();
            showNotification('✓ Skor prioritas dihitung untuk ' + computedCount + ' household');
        } else {
            showNotification('Error menghitung skor: ' + (data.error || 'unknown error'), true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error menghitung skor prioritas', true);
    });
}

function loadHouseholdScoreSummary() {
    fetch('api/get_household_score_summary.php')
        .then(response => response.json())
        .then(data => {
            if (!data.success || !data.summary) {
                return;
            }

            const counts = data.summary.priority_counts || {};
            const assistedCount = Number(data.summary.assisted_households || 0);

            const assistedEl = document.getElementById('priority-assisted-count');
            const veryHighEl = document.getElementById('priority-very-high-count');
            const highEl = document.getElementById('priority-high-count');
            const mediumEl = document.getElementById('priority-medium-count');
            const lowEl = document.getElementById('priority-low-count');

            if (assistedEl) assistedEl.textContent = assistedCount;
            if (veryHighEl) veryHighEl.textContent = Number(counts.very_high || 0);
            if (highEl) highEl.textContent = Number(counts.high || 0);
            if (mediumEl) mediumEl.textContent = Number(counts.medium || 0);
            if (lowEl) lowEl.textContent = Number(counts.low || 0);
        })
        .catch(error => {
            console.error('Error loading household score summary:', error);
        });
}

function loadHouseholdPriorityRanking() {
    fetch('api/get_household_ranking.php?limit=10')
        .then(response => response.json())
        .then(data => {
            if (data.success && Array.isArray(data.ranking)) {
                renderHouseholdPriorityList(data.ranking);
            }
        })
        .catch(error => {
            console.error('Error loading household ranking:', error);
        });
}

function getPriorityLevelLabel(level) {
    const labels = {
        very_high: 'Very High',
        high: 'High',
        medium: 'Medium',
        low: 'Low'
    };

    return labels[level] || level;
}

function renderHouseholdPriorityList(rankingItems) {
    const container = document.getElementById('household-priority-list');
    if (!container) {
        return;
    }

    if (!Array.isArray(rankingItems) || rankingItems.length === 0) {
        container.innerHTML = '<div class="household-empty">Belum ada data skor prioritas.</div>';
        return;
    }

    const html = rankingItems.map(item => {
        const priorityLevel = String(item.priority_level || 'low');
        const priorityClass = priorityLevel.replace(/[^a-z_]/g, '');
        const priorityLabel = escapeHtml(getPriorityLevelLabel(priorityLevel));
        const householdCode = escapeHtml(String(item.household_code || '-'));
        const headName = escapeHtml(String(item.head_name || '-'));
        const spiValue = Number(item.spi || 0).toFixed(3);
        const assisted = Number(item.assisted || 0) === 1;
        const statusLabel = assisted ? 'Assisted' : priorityLabel;
        const statusClass = assisted ? 'assisted' : priorityClass;
        const nameClass = assisted ? 'priority-item-name assisted-point-name' : 'priority-item-name';

        return `
            <div class="priority-item">
                <div class="priority-item-main">
                    <span class="priority-item-code">${householdCode}</span>
                    <span class="${nameClass}">${headName}</span>
                </div>
                <div class="priority-item-main" style="text-align: right; align-items: flex-end;">
                    <span class="priority-item-score">SPI ${spiValue}</span>
                    <span class="priority-item-status ${statusClass}">${statusLabel}</span>
                </div>
            </div>
        `;
    }).join('');

    container.innerHTML = html;
}

function showNotification(message, isError = false) {
    const notification = document.createElement('div');
    notification.className = 'notification' + (isError ? ' error' : '');
    notification.textContent = message;
    document.body.appendChild(notification);

    setTimeout(() => {
        notification.remove();
    }, 3000);
}

function escapeHtml(text) {
    const map = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;'
    };
    return text.replace(/[&<>"']/g, m => map[m]);
}

// ============ LINES/ROADS MANAGEMENT ============

function calculatePolylineLength(coordinates) {
    let totalDistance = 0;
    for (let i = 0; i < coordinates.length - 1; i++) {
        const latlng1 = L.latLng(coordinates[i][0], coordinates[i][1]);
        const latlng2 = L.latLng(coordinates[i + 1][0], coordinates[i + 1][1]);
        totalDistance += latlng1.distanceTo(latlng2);
    }
    return Math.round(totalDistance * 100) / 100;
}

function loadLines() {
    fetch('api/get_lines.php')
        .then(response => response.json())
        .then(data => {
            if (data.success && data.lines) {
                // Clear existing lines
                Object.keys(lines).forEach(id => {
                    if (map.hasLayer(lines[id])) {
                        map.removeLayer(lines[id]);
                    }
                });
                lines = {};
                lineCount = 0;

                // Load new lines
                data.lines.forEach(line => {
                    displayLine(
                        line.id,
                        line.name,
                        line.road_type,
                        line.coordinates,
                        line.length_meters
                    );
                });
                updateLineCount();
            }
        })
        .catch(error => console.error('Error loading lines:', error));
}

function displayLine(id, name, road_type, coordinates, length_meters, condition_status = 'normal') {
    lineData[id] = {
        id: id,
        name: name,
        road_type: road_type,
        coordinates: coordinates,
        length_meters: length_meters,
        condition_status: condition_status
    };

    const baseStyle = lineStyles[road_type] || lineStyles['Nasional'];
    const finalStyle = applyConditionStyle(baseStyle, condition_status);
    const polyline = L.polyline(coordinates, finalStyle).addTo(map);

    const conditionLabel = condition_status.replace('_', ' ').replace(/\b\w/g, l => l.toUpperCase());
    const conditionIcon = condition_status === 'normal' ? '✓' : (condition_status === 'minor_damage' ? '⚠️' : '🔴');

    const popupContent = `
        <div class="feature-popup">
            <div class="feature-popup-name">${escapeHtml(name)}</div>
            <div class="feature-popup-type">🛣️ ${road_type}</div>
            <div class="feature-popup-condition">${conditionIcon} Condition: ${conditionLabel}</div>
            <div class="feature-popup-info">Length: ${(length_meters/1000).toFixed(2)} km</div>
            <div class="feature-popup-info">Points: ${coordinates.length}</div>
            <div class="feature-popup-actions">
                <button onclick="editLine(${id})">Edit</button>
                <button onclick="deleteLine(${id})">Delete</button>
            </div>
        </div>
    `;

    polyline.bindPopup(popupContent);
    lines[id] = polyline;
    lineCount++;
}

function applyConditionStyle(baseStyle, condition) {
    const conditionStyles = {
        'normal': { dashArray: null, opacity: 0.8 },
        'minor_damage': { dashArray: '5, 5', opacity: 0.7 },
        'major_damage': { color: '#d32f2f', dashArray: '2, 3', opacity: 0.85 }
    };

    return { ...baseStyle, ...conditionStyles[condition] };
}

function updateLineCount() {
    const countElement = document.getElementById('line-count');
    if (countElement) {
        countElement.textContent = lineCount;
    }
}

function addLine(name, road_type, coordinates, length_meters) {
    fetch('api/save_line.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            name: name,
            road_type: road_type,
            coordinates: coordinates,
            length_meters: length_meters
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            displayLine(data.id, data.name, data.road_type, data.coordinates, data.length_meters);
            updateLineCount();
            showNotification('✓ Road added successfully');
            closeLineModal();
        } else {
            showNotification('Error adding road: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error adding road', true);
    });
}

function editLine(id) {
    if (!lineData[id]) {
        showNotification('Line data not found', true);
        return;
    }

    const data = lineData[id];
    document.getElementById('edit-line-name').value = data.name;
    document.getElementById('edit-line-road-type').value = data.road_type;
    document.getElementById('edit-line-length').value = (data.length_meters / 1000).toFixed(2);
    document.getElementById('edit-line-points').value = data.coordinates.length;
    document.getElementById('edit-line-condition').value = data.condition_status || 'normal';

    document.getElementById('current-editing-line-id').value = id;
    const editModal = document.getElementById('edit-line-modal');
    editModal.classList.add('show');
    document.getElementById('edit-line-name').focus();
}

function closeLineModal() {
    const modal = document.getElementById('line-modal');
    modal.classList.remove('show');

    // Clean up drawing mode
    drawMode.active = false;
    drawMode.type = null;
    drawMode.coordinates = [];

    if (drawMode.temporaryLayer) {
        map.removeLayer(drawMode.temporaryLayer);
        drawMode.temporaryLayer = null;
    }

    // Remove temporary markers
    drawMode.tempMarkers.forEach(marker => {
        map.removeLayer(marker);
    });
    drawMode.tempMarkers = [];

    // Restore default click handler
    if (drawMode.defaultClickHandler) {
        map.on('click', drawMode.defaultClickHandler);
    }
}

function closeEditLineModal() {
    const editModal = document.getElementById('edit-line-modal');
    editModal.classList.remove('show');
}

function saveLineEdit() {
    const id = parseInt(document.getElementById('current-editing-line-id').value);
    const name = document.getElementById('edit-line-name').value.trim();
    const road_type = document.getElementById('edit-line-road-type').value;
    const condition_status = document.getElementById('edit-line-condition').value;

    if (!name) {
        showNotification('Please enter a name for the road', true);
        return;
    }

    fetch('api/update_line.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            id: id,
            name: name,
            road_type: road_type,
            condition_status: condition_status
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            const line = data.line;
            lineData[id].name = line.name;
            lineData[id].road_type = line.road_type;
            lineData[id].condition_status = line.condition_status;

            const baseStyle = lineStyles[line.road_type] || lineStyles['Nasional'];
            const finalStyle = applyConditionStyle(baseStyle, line.condition_status);
            lines[id].setStyle(finalStyle);

            closeEditLineModal();
            showNotification('✓ Road updated successfully');
        } else {
            showNotification('Error updating road: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error updating road', true);
    });
}

function deleteLine(id) {
    if (!confirm('Are you sure you want to delete this road?')) {
        return;
    }

    fetch('api/delete_line.php', {
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ id: id })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            if (lines[id] && map.hasLayer(lines[id])) {
                map.removeLayer(lines[id]);
                delete lines[id];
                delete lineData[id];
                lineCount--;
                updateLineCount();
                showNotification('✓ Road deleted');
            }
        } else {
            showNotification('Error deleting road: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error deleting road', true);
    });
}

// ============ POLYGONS/LAND PARCELS MANAGEMENT ============

function calculatePolygonArea(coordinates) {
    // Close the polygon if not already closed
    const closed = (coordinates[coordinates.length - 1][0] === coordinates[0][0] &&
                    coordinates[coordinates.length - 1][1] === coordinates[0][1])
                   ? coordinates : [...coordinates, coordinates[0]];

    // Shoelace formula
    let area = 0;
    for (let i = 0; i < closed.length - 1; i++) {
        const lat1 = closed[i][0], lng1 = closed[i][1];
        const lat2 = closed[i + 1][0], lng2 = closed[i + 1][1];
        area += (lng2 - lng1) * (lat2 + lat1) / 2;
    }

    // Convert from degrees to approximate square meters
    const metersPerDegree = 111320;
    const areaSqMeters = Math.abs(area) * metersPerDegree * metersPerDegree;

    return Math.round(areaSqMeters * 100) / 100;
}

function loadPolygons() {
    fetch('api/get_polygons.php')
        .then(response => response.json())
        .then(data => {
            if (data.success && data.polygons) {
                // Clear existing polygons
                Object.keys(polygons).forEach(id => {
                    if (map.hasLayer(polygons[id])) {
                        map.removeLayer(polygons[id]);
                    }
                });
                polygons = {};
                polygonCount = 0;

                // Load new polygons
                data.polygons.forEach(polygon => {
                    displayPolygon(
                        polygon.id,
                        polygon.name,
                        polygon.certificate_type,
                        polygon.coordinates,
                        polygon.area_sqm
                    );
                });
                updatePolygonCount();
            }
        })
        .catch(error => console.error('Error loading polygons:', error));
}

function displayPolygon(id, name, certificate_type, coordinates, area_sqm) {
    polygonData[id] = {
        id: id,
        name: name,
        certificate_type: certificate_type,
        coordinates: coordinates,
        area_sqm: area_sqm
    };

    const style = polygonStyles[certificate_type] || polygonStyles['SHM'];
    const polygon = L.polygon(coordinates, style).addTo(map);

    const popupContent = `
        <div class="feature-popup">
            <div class="feature-popup-name">${escapeHtml(name)}</div>
            <div class="feature-popup-type">🏞️ ${certificate_type}</div>
            <div class="feature-popup-info">Area: ${(area_sqm/10000).toFixed(2)} hectares</div>
            <div class="feature-popup-info">Points: ${coordinates.length}</div>
            <div class="feature-popup-actions">
                <button onclick="editPolygon(${id})">Edit</button>
                <button onclick="deletePolygon(${id})">Delete</button>
            </div>
        </div>
    `;

    polygon.bindPopup(popupContent);
    polygons[id] = polygon;
    polygonCount++;
}

function updatePolygonCount() {
    const countElement = document.getElementById('polygon-count');
    if (countElement) {
        countElement.textContent = polygonCount;
    }
}

function addPolygon(name, certificate_type, coordinates, area_sqm) {
    fetch('api/save_polygon.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            name: name,
            certificate_type: certificate_type,
            coordinates: coordinates,
            area_sqm: area_sqm
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            displayPolygon(data.id, data.name, data.certificate_type, data.coordinates, data.area_sqm);
            updatePolygonCount();
            showNotification('✓ Parcel added successfully');
            closePolygonModal();
        } else {
            showNotification('Error adding parcel: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error adding parcel', true);
    });
}

function editPolygon(id) {
    if (!polygonData[id]) {
        showNotification('Polygon data not found', true);
        return;
    }

    const data = polygonData[id];
    document.getElementById('edit-polygon-name').value = data.name;
    document.getElementById('edit-polygon-cert-type').value = data.certificate_type;
    document.getElementById('edit-polygon-area').value = (data.area_sqm / 10000).toFixed(2);
    document.getElementById('edit-polygon-points').value = data.coordinates.length;

    document.getElementById('current-editing-polygon-id').value = id;
    const editModal = document.getElementById('edit-polygon-modal');
    editModal.classList.add('show');
    document.getElementById('edit-polygon-name').focus();
}

function closePolygonModal() {
    const modal = document.getElementById('polygon-modal');
    modal.classList.remove('show');

    // Clean up drawing mode
    drawMode.active = false;
    drawMode.type = null;
    drawMode.coordinates = [];

    if (drawMode.temporaryLayer) {
        map.removeLayer(drawMode.temporaryLayer);
        drawMode.temporaryLayer = null;
    }

    // Remove temporary markers
    drawMode.tempMarkers.forEach(marker => {
        map.removeLayer(marker);
    });
    drawMode.tempMarkers = [];

    // Restore default click handler
    if (drawMode.defaultClickHandler) {
        map.on('click', drawMode.defaultClickHandler);
    }
}

function closeEditPolygonModal() {
    const editModal = document.getElementById('edit-polygon-modal');
    editModal.classList.remove('show');
}

function savePolygonEdit() {
    const id = parseInt(document.getElementById('current-editing-polygon-id').value);
    const name = document.getElementById('edit-polygon-name').value.trim();
    const certificate_type = document.getElementById('edit-polygon-cert-type').value;

    if (!name) {
        showNotification('Please enter a name for the parcel', true);
        return;
    }

    fetch('api/update_polygon.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            id: id,
            name: name,
            certificate_type: certificate_type
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            const polygon = data.polygon;
            polygonData[id].name = polygon.name;
            polygonData[id].certificate_type = polygon.certificate_type;

            const newStyle = polygonStyles[polygon.certificate_type] || polygonStyles['SHM'];
            polygons[id].setStyle(newStyle);

            closeEditPolygonModal();
            showNotification('✓ Parcel updated successfully');
        } else {
            showNotification('Error updating parcel: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error updating parcel', true);
    });
}

function deletePolygon(id) {
    if (!confirm('Are you sure you want to delete this parcel?')) {
        return;
    }

    fetch('api/delete_polygon.php', {
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ id: id })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            if (polygons[id] && map.hasLayer(polygons[id])) {
                map.removeLayer(polygons[id]);
                delete polygons[id];
                delete polygonData[id];
                polygonCount--;
                updatePolygonCount();
                showNotification('✓ Parcel deleted');
            }
        } else {
            showNotification('Error deleting parcel: ' + data.error, true);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showNotification('Error deleting parcel', true);
    });
}

// ============ DRAWING MODE ============

function enableLineDrawMode() {
    if (drawMode.active) {
        showNotification('Drawing mode already active', true);
        return;
    }

    drawMode.active = true;
    drawMode.type = 'line';
    drawMode.coordinates = [];
    drawMode.tempMarkers = [];

    // Disable default point click handler
    if (drawMode.defaultClickHandler) {
        map.off('click', drawMode.defaultClickHandler);
    }

    showNotification('Click map points to draw road. Double-click to finish.');
    document.getElementById('drawing-instructions').textContent = 'Click map points to draw road. Double-click to finish.';
    document.getElementById('drawing-toolbar').classList.remove('hidden');

    map.on('click', handleMapClickDuringDraw);
    map.on('dblclick', completeLineDrawing);
}

function enablePolygonDrawMode() {
    if (drawMode.active) {
        showNotification('Drawing mode already active', true);
        return;
    }

    drawMode.active = true;
    drawMode.type = 'polygon';
    drawMode.coordinates = [];
    drawMode.tempMarkers = [];

    // Disable default point click handler
    if (drawMode.defaultClickHandler) {
        map.off('click', drawMode.defaultClickHandler);
    }

    showNotification('Click map points to draw parcel. Right-click to finish.');
    document.getElementById('drawing-instructions').textContent = 'Click map points to draw parcel. Right-click to finish.';
    document.getElementById('drawing-toolbar').classList.remove('hidden');

    map.on('click', handleMapClickDuringDraw);
    map.on('contextmenu', completePolygonDrawing);
}

function handleMapClickDuringDraw(e) {
    if (!drawMode.active) return;

    // Prevent default behavior and opening point modal
    L.DomEvent.stopPropagation(e);
    L.DomEvent.preventDefault(e.originalEvent);

    const latlng = e.latlng;
    drawMode.coordinates.push([latlng.lat, latlng.lng]);

    // Update point counter
    document.getElementById('point-count').textContent = drawMode.coordinates.length;

    // Draw temporary polyline or polygon
    if (drawMode.type === 'line') {
        if (drawMode.temporaryLayer) {
            map.removeLayer(drawMode.temporaryLayer);
        }
        drawMode.temporaryLayer = L.polyline(drawMode.coordinates, {
            color: '#667eea',
            weight: 3,
            opacity: 0.7,
            dashArray: '5, 5'
        }).addTo(map);

        // Draw markers at each point
        const marker = L.circleMarker([latlng.lat, latlng.lng], {
            radius: 5,
            fillColor: '#667eea',
            color: '#fff',
            weight: 2,
            opacity: 1,
            fillOpacity: 0.8
        }).addTo(map);
        drawMode.tempMarkers.push(marker);

    } else if (drawMode.type === 'polygon') {
        if (drawMode.temporaryLayer) {
            map.removeLayer(drawMode.temporaryLayer);
        }
        drawMode.temporaryLayer = L.polygon(drawMode.coordinates, {
            fillColor: '#667eea',
            weight: 2,
            opacity: 0.7,
            color: '#667eea',
            fillOpacity: 0.3
        }).addTo(map);

        // Draw markers at each point
        const marker = L.circleMarker([latlng.lat, latlng.lng], {
            radius: 5,
            fillColor: '#667eea',
            color: '#fff',
            weight: 2,
            opacity: 1,
            fillOpacity: 0.8
        }).addTo(map);
        drawMode.tempMarkers.push(marker);
    }
}

function completeLineDrawing() {
    if (!drawMode.active || drawMode.type !== 'line') return;

    map.off('click', handleMapClickDuringDraw);
    map.off('dblclick', completeLineDrawing);

    if (drawMode.coordinates.length < 2) {
        showNotification('Need at least 2 points to create a road', true);
        cancelDrawing();
        return;
    }

    const length_meters = calculatePolylineLength(drawMode.coordinates);

    document.getElementById('line-name').value = '';
    document.getElementById('line-road-type').value = '';
    document.getElementById('line-length').value = (length_meters / 1000).toFixed(2);
    document.getElementById('line-points').value = drawMode.coordinates.length;
    document.getElementById('line-coordinates').value = JSON.stringify(drawMode.coordinates);
    document.getElementById('line-length-meters').value = length_meters;

    // Clean up drawing state but keep active until modal closes
    if (drawMode.temporaryLayer) {
        map.removeLayer(drawMode.temporaryLayer);
        drawMode.temporaryLayer = null;
    }

    // Remove temporary markers
    drawMode.tempMarkers.forEach(marker => {
        map.removeLayer(marker);
    });
    drawMode.tempMarkers = [];

    document.getElementById('drawing-toolbar').classList.add('hidden');
    document.getElementById('line-modal').classList.add('show');
}

function completePolygonDrawing(e) {
    if (!drawMode.active || drawMode.type !== 'polygon') return;

    if (e) {
        L.DomEvent.preventDefault(e);
    }

    map.off('click', handleMapClickDuringDraw);
    map.off('contextmenu', completePolygonDrawing);

    if (drawMode.coordinates.length < 3) {
        showNotification('Need at least 3 points to create a parcel', true);
        cancelDrawing();
        return;
    }

    const area_sqm = calculatePolygonArea(drawMode.coordinates);

    document.getElementById('polygon-name').value = '';
    document.getElementById('polygon-cert-type').value = '';
    document.getElementById('polygon-area').value = (area_sqm / 10000).toFixed(2);
    document.getElementById('polygon-points').value = drawMode.coordinates.length;
    document.getElementById('polygon-coordinates').value = JSON.stringify(drawMode.coordinates);
    document.getElementById('polygon-area-sqm').value = area_sqm;

    // Clean up drawing state but keep active until modal closes
    if (drawMode.temporaryLayer) {
        map.removeLayer(drawMode.temporaryLayer);
        drawMode.temporaryLayer = null;
    }

    // Remove temporary markers
    drawMode.tempMarkers.forEach(marker => {
        map.removeLayer(marker);
    });
    drawMode.tempMarkers = [];

    document.getElementById('drawing-toolbar').classList.add('hidden');
    document.getElementById('polygon-modal').classList.add('show');
}

function cancelDrawing() {
    map.off('click', handleMapClickDuringDraw);
    map.off('dblclick', completeLineDrawing);
    map.off('contextmenu', completePolygonDrawing);

    if (drawMode.temporaryLayer) {
        map.removeLayer(drawMode.temporaryLayer);
        drawMode.temporaryLayer = null;
    }

    // Remove temporary markers
    drawMode.tempMarkers.forEach(marker => {
        map.removeLayer(marker);
    });
    drawMode.tempMarkers = [];

    drawMode.active = false;
    drawMode.type = null;
    drawMode.coordinates = [];

    // Restore default click handler for point modal
    if (drawMode.defaultClickHandler) {
        map.on('click', drawMode.defaultClickHandler);
    }

    document.getElementById('drawing-toolbar').classList.add('hidden');
    showNotification('Drawing cancelled');
}

// Helper to complete current drawing depending on active draw type
function completeDrawing() {
    if (!drawMode || !drawMode.active) return;
    if (drawMode.type === 'line') {
        completeLineDrawing();
    } else if (drawMode.type === 'polygon') {
        completePolygonDrawing();
    }
}

function submitLineForm() {
    const name = document.getElementById('line-name').value.trim();
    const road_type = document.getElementById('line-road-type').value;
    const coordinates = JSON.parse(document.getElementById('line-coordinates').value);
    const length_meters = parseFloat(document.getElementById('line-length-meters').value);

    if (!name) {
        showNotification('Please enter a name for the road', true);
        return;
    }

    if (!road_type) {
        showNotification('Please select a road type', true);
        return;
    }

    addLine(name, road_type, coordinates, length_meters);
}

function submitPolygonForm() {
    const name = document.getElementById('polygon-name').value.trim();
    const certificate_type = document.getElementById('polygon-cert-type').value;
    const coordinates = JSON.parse(document.getElementById('polygon-coordinates').value);
    const area_sqm = parseFloat(document.getElementById('polygon-area-sqm').value);

    if (!name) {
        showNotification('Please enter a name for the parcel', true);
        return;
    }

    if (!certificate_type) {
        showNotification('Please select a certificate type', true);
        return;
    }

    addPolygon(name, certificate_type, coordinates, area_sqm);
}

// ============ SEARCH & FILTER FOR ROADS ============

function applyRoadsFilter() {
    const search = document.getElementById('roads-search').value;
    const dateFrom = document.getElementById('roads-date-from').value;
    const dateTo = document.getElementById('roads-date-to').value;
    const condition = document.getElementById('roads-condition').value;

    const params = new URLSearchParams();
    if (search) params.append('search', search);
    if (dateFrom) params.append('from_date', dateFrom);
    if (dateTo) params.append('to_date', dateTo);
    if (condition) params.append('condition_status', condition);

    fetch(`api/search_roads.php?${params}`)
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                Object.keys(lines).forEach(id => {
                    if (map.hasLayer(lines[id])) map.removeLayer(lines[id]);
                });
                lines = {};
                lineData = {};
                lineCount = 0;

                data.lines.forEach(line => {
                    displayLine(line.id, line.name, line.road_type, line.coordinates, line.length_meters, line.condition_status);
                });
                updateLineCount();
                showNotification(`✓ ${data.total} roads found`);
            } else {
                showNotification('Error applying filter', true);
            }
        })
        .catch(error => {
            console.error('Error:', error);
            showNotification('Error searching roads', true);
        });
}

function clearRoadsFilter() {
    document.getElementById('roads-search').value = '';
    document.getElementById('roads-date-from').value = '';
    document.getElementById('roads-date-to').value = '';
    document.getElementById('roads-condition').value = '';
    loadLines();
    showNotification('✓ Filter cleared');
}

// ============ SEARCH & FILTER FOR PARCELS ============

function applyParcelsFilter() {
    const search = document.getElementById('parcels-search').value;
    const dateFrom = document.getElementById('parcels-date-from').value;
    const dateTo = document.getElementById('parcels-date-to').value;
    const certificate = document.getElementById('parcels-certificate').value;

    const params = new URLSearchParams();
    if (search) params.append('search', search);
    if (dateFrom) params.append('from_date', dateFrom);
    if (dateTo) params.append('to_date', dateTo);
    if (certificate) params.append('certificate_type', certificate);

    fetch(`api/search_parcels.php?${params}`)
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                Object.keys(polygons).forEach(id => {
                    if (map.hasLayer(polygons[id])) map.removeLayer(polygons[id]);
                });
                polygons = {};
                polygonData = {};
                polygonCount = 0;

                data.polygons.forEach(polygon => {
                    displayPolygon(polygon.id, polygon.name, polygon.certificate_type, polygon.coordinates, polygon.area_sqm);
                });
                updatePolygonCount();
                showNotification(`✓ ${data.total} parcels found`);
            } else {
                showNotification('Error applying filter', true);
            }
        })
        .catch(error => {
            console.error('Error:', error);
            showNotification('Error searching parcels', true);
        });
}

function clearParcelsFilter() {
    document.getElementById('parcels-search').value = '';
    document.getElementById('parcels-date-from').value = '';
    document.getElementById('parcels-date-to').value = '';
    document.getElementById('parcels-certificate').value = '';
    loadPolygons();
    showNotification('✓ Filter cleared');
}

// ============ DEBOUNCED SEARCH ============

setTimeout(function() {
    const roadsSearchInput = document.getElementById('roads-search');
    if (roadsSearchInput) {
        roadsSearchInput.addEventListener('input', function() {
            clearTimeout(searchTimeouts.roads);
            searchTimeouts.roads = setTimeout(() => applyRoadsFilter(), 300);
        });
    }

    const parcelsSearchInput = document.getElementById('parcels-search');
    if (parcelsSearchInput) {
        parcelsSearchInput.addEventListener('input', function() {
            clearTimeout(searchTimeouts.parcels);
            searchTimeouts.parcels = setTimeout(() => applyParcelsFilter(), 300);
        });
    }
}, 500);

// ============ PONTIANAK CHOROPLETH MAP ============

function buildChoroplethQuery(layerType) {
    const params = new URLSearchParams({ layer_type: layerType });
    if (layerType !== 'city_boundary') {
        params.set('admin_level', pontianakState.adminLevel || 'kecamatan');
    }
    return params.toString();
}

// Toggle layer visibility on/off
function toggleChoroplethLayer(layerType) {
    // 1. Update state
    pontianakState.currentLayers[layerType] = !pontianakState.currentLayers[layerType];

    // 2. If toggling OFF, remove from map
    if (!pontianakState.currentLayers[layerType]) {
        if (pontianakState.layers[layerType]) {
            pontianakState.layers[layerType].forEach(layer => {
                if (map.hasLayer(layer)) map.removeLayer(layer);
            });
            delete pontianakState.layers[layerType];
        }
    } else {
        // 3. If toggling ON, fetch and render
        fetchAndRenderChoroplethLayer(layerType);
    }

    // 4. Update legend to reflect current visible layers
    updateChoroplethLegend();
}

// Fetch and render a specific layer
function fetchAndRenderChoroplethLayer(layerType) {
    fetch(`api/get_choropleth_data.php?${buildChoroplethQuery(layerType)}`)
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                renderChoroplethLayer(data, layerType);
            }
        })
        .catch(error => {
            console.error('Error fetching layer:', layerType, error);
            pontianakState.currentLayers[layerType] = false; // Revert on error
            showNotification(`Error loading ${layerType} layer`, true);
        });
}

function initPontianakMap() {
    if (pontianakState.dataLoaded) return;

    // Load administrative areas data
    fetch('api/get_pontianak_areas.php')
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                data.areas.forEach(area => {
                    pontianakState.areasData[area.id] = area;
                });
            }
        })
        .catch(error => {
            console.error('Error loading Pontianak areas:', error);
            showNotification('Error loading Pontianak areas', true);
        });

    // Render only currently visible layers (from checkboxes)
    Object.keys(pontianakState.currentLayers).forEach(layerType => {
        if (pontianakState.currentLayers[layerType]) {
            if (layerType === 'city_boundary') {
                renderCityBoundary();
            } else {
                fetchAndRenderChoroplethLayer(layerType);
            }
        }
    });

    pontianakState.dataLoaded = true;
}

function switchChoropleathLayer(layerType) {
    pontianakState.currentLayer = layerType;

    fetch(`api/get_choropleth_data.php?${buildChoroplethQuery(layerType)}`)
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                renderChoroplethLayer(data, layerType);
                updateChoroplethLegend();
            } else {
                showNotification('Error loading choropleth data', true);
            }
        })
        .catch(error => {
            console.error('Error:', error);
            showNotification('Error loading choropleth data', true);
        });
}

function renderChoroplethLayer(data, layerType) {
    // Re-render this layer cleanly
    if (pontianakState.layers[layerType]) {
        pontianakState.layers[layerType].forEach(layer => {
            if (map.hasLayer(layer)) map.removeLayer(layer);
        });
    }
    pontianakState.layers[layerType] = [];

    // Special handling for city boundary
    if (layerType === 'city_boundary') {
        renderCityBoundary();
        return;
    }

    // Create color scale for this layer
    pontianakState.colorScales[layerType] = createColorScale(data.min_value, data.max_value);

    // Render each area
    data.data.forEach(feature => {
        const color = pontianakState.colorScales[layerType](feature.value);

        const geoJsonFeature = {
            type: 'Feature',
            geometry: typeof feature.geometry === 'string' ? JSON.parse(feature.geometry) : feature.geometry,
            properties: {
                area_id: feature.area_id,
                area_name: feature.area_name,
                value: feature.value,
                layer_type: layerType,
                value_source: feature.value_source || ''
            }
        };

        const layer = L.geoJSON(geoJsonFeature, {
            style: {
                fillColor: color,
                fillOpacity: 0.6,  // Slightly reduced for layer overlap visibility
                color: '#1f2a44',
                weight: 1.1,
                className: `choropleth-layer-${layerType}`
            },
            onEachFeature: function(feature, layer) {
                const name = feature.properties.area_name;
                const value = feature.properties.value.toFixed(2);
                const label = getLayerLabel(layerType);
                const valueSource = feature.properties.value_source ? `<br/><small>Source: ${feature.properties.value_source}</small>` : '';
                layer.bindPopup(
                    `<div class="choropleth-popup">
                        <strong>${escapeHtml(name)}</strong><br/>
                        <span class="popup-value">${value}</span><br/>
                        <span class="popup-label">${label}</span>${valueSource}
                    </div>`
                );
            }
        }).addTo(map);

        pontianakState.layers[layerType].push(layer);
    });
}

function renderCityBoundary() {
    if (!pontianakState.areasData.city_boundary && Object.keys(pontianakState.areasData).length === 0) {
        // Fetch city boundary if areas not loaded yet
        fetch('api/get_pontianak_areas.php?area_type=city')
            .then(response => response.json())
            .then(data => {
                if (data.success && data.areas.length > 0) {
                    const cityBoundary = data.areas[0];
                    pontianakState.areasData.city_boundary = cityBoundary;
                    renderCityBoundaryLayer(cityBoundary);
                }
            })
            .catch(error => console.error('Error loading city boundary:', error));
    } else if (pontianakState.areasData.city_boundary) {
        renderCityBoundaryLayer(pontianakState.areasData.city_boundary);
    } else {
        // Fetch from areas data
        fetch('api/get_pontianak_areas.php?area_type=city')
            .then(response => response.json())
            .then(data => {
                if (data.success && data.areas.length > 0) {
                    const cityBoundary = data.areas[0];
                    pontianakState.areasData.city_boundary = cityBoundary;
                    renderCityBoundaryLayer(cityBoundary);
                }
            });
    }
}

function renderCityBoundaryLayer(cityBoundary) {
    if (pontianakState.layers.city_boundary) {
        pontianakState.layers.city_boundary.forEach(layer => {
            if (map.hasLayer(layer)) map.removeLayer(layer);
        });
    }

    const geom = typeof cityBoundary.geometry === 'string' ? JSON.parse(cityBoundary.geometry) : cityBoundary.geometry;

    const layer = L.geoJSON({
        type: 'Feature',
        geometry: geom,
        properties: { name: 'Pontianak City Boundary' }
    }, {
        style: {
            fillColor: '#7fb3d5',
            fillOpacity: 0.08,
            color: '#0d3557',
            weight: 4,
            dashArray: null,
            className: 'choropleth-layer-city_boundary'
        },
        onEachFeature: function(feature, layer) {
            layer.bindPopup('🏙️ Pontianak City Boundary');
        }
    }).addTo(map);

    if (!pontianakState.layers.city_boundary) {
        pontianakState.layers.city_boundary = [];
    }
    pontianakState.layers.city_boundary.push(layer);

    if (pontianakState.active && !pontianakState.hasFittedBoundary) {
        const bounds = layer.getBounds();
        if (bounds && bounds.isValid()) {
            map.fitBounds(bounds, { padding: [20, 20] });
            pontianakState.hasFittedBoundary = true;
        }
    }
}

function getLayerLabel(layerType) {
    const labels = {
        'population': 'People/km²',
        'road_density': 'Roads/km²',
        'damaged_roads_density': 'Damaged roads/km²',
        'city_boundary': 'City Boundary'
    };
    return labels[layerType] || layerType;
}

function createColorScale(minVal, maxVal) {
    const colors = ['#2E86AB', '#A23B72', '#F18F01', '#C73E1D'];
    if (minVal === maxVal) {
        return () => colors[Math.floor(colors.length / 2)];
    }
    return function(value) {
        const normalized = (value - minVal) / (maxVal - minVal);
        const index = Math.max(0, Math.min(normalized * (colors.length - 1), colors.length - 1));
        return colors[Math.floor(index)];
    };
}

function updateChoroplethLegend() {
    const legendDiv = document.getElementById('choropleth-legend');
    if (!legendDiv) return;

    // Get visible data layers (exclude city_boundary which has no values)
    const visibleLayers = Object.keys(pontianakState.currentLayers)
        .filter(key => pontianakState.currentLayers[key] && key !== 'city_boundary');

    if (visibleLayers.length === 0) {
        legendDiv.innerHTML = '<div style="text-align: center; padding: 10px; opacity: 0.7;">No layers selected</div>';
        return;
    }

    legendDiv.innerHTML = '<div style="text-align: center; padding: 10px; opacity: 0.7;">Loading legend...</div>';

    const requests = visibleLayers.map(layerType =>
        fetch(`api/get_choropleth_data.php?${buildChoroplethQuery(layerType)}`)
            .then(response => response.json())
            .then(data => {
                if (!data.success) {
                    return null;
                }
                return {
                    layerType: layerType,
                    minValue: data.min_value,
                    maxValue: data.max_value
                };
            })
            .catch(error => {
                console.error('Error updating legend for', layerType, error);
                return null;
            })
    );

    Promise.all(requests).then(results => {
        const validResults = results.filter(Boolean);

        if (validResults.length === 0) {
            legendDiv.innerHTML = '<div style="text-align: center; padding: 10px; opacity: 0.7;">Legend unavailable</div>';
            return;
        }

        legendDiv.innerHTML = '';
        validResults.forEach(item => {
            const div = document.createElement('div');
            div.className = 'legend-section';
            div.setAttribute('data-layer', item.layerType);
            div.innerHTML = buildLegendSection(item.layerType, item.minValue, item.maxValue);
            legendDiv.appendChild(div);
        });
    });
}

function buildLegendSection(layerType, minVal, maxVal) {
    const labels = {
        'population': 'Population Density (People/km²)',
        'road_density': 'Road Density (Roads/km²)',
        'damaged_roads_density': 'Damaged Roads Density (Roads/km²)'
    };

    return `
        <div class="legend-layer-name">${labels[layerType] || layerType}</div>
        <div class="legend-range">
            <div class="legend-item">
                <div class="legend-color" style="background-color: #2E86AB;"></div>
                <span>${minVal.toFixed(1)}</span>
            </div>
            <div class="legend-item">
                <div class="legend-color" style="background-color: #A23B72;"></div>
                <span>${((minVal + maxVal) / 2).toFixed(1)}</span>
            </div>
            <div class="legend-item">
                <div class="legend-color" style="background-color: #C73E1D;"></div>
                <span>${maxVal.toFixed(1)}</span>
            </div>
        </div>
    `;
}

function exportChoroplethGeoJSON() {
    window.location.href = 'api/export_geojson.php?type=pontianak_areas';
    showNotification('✓ GeoJSON export started');
}
