const statusDiv = document.getElementById('status');
const statusPanel = document.getElementById('statusPanel');
const qcResultDiv = document.getElementById('qcResult');
const loadingOverlay = document.getElementById('loadingOverlay');

// Global endpoint markers layer group for toggling visibility
let endpointMarkersLayer = null;

// ============================================
// STYLE CONFIGURATION
// ============================================
// Centralized styling configuration for easy customization

const LAYER_STYLES = {
  // Zone polygon styles
  zonePolygons: {
    color: '#6366f1',          // Border color (indigo)
    fillColor: '#818cf8',      // Fill color (lighter indigo)
    fillOpacity: 0.15,         // Transparency (15%)
    weight: 2,                 // Border width
    opacity: 0.7               // Border opacity
  },

  // Segment styles
  segments: {
    aerial: {
      color: '#0066cc',        // Blue for aerial
      weight: 4,
      opacity: 0.85
    },
    underground: {
      color: '#cc0000',        // Red for underground
      weight: 4,
      opacity: 0.85
    },
    default: {
      color: '#808080',        // Gray for other types
      weight: 4,
      opacity: 0.7
    }
  },

  // Point marker styles
  markers: {
    sites: {
      radius: 7,
      fillColor: '#3b82f6',
      color: '#ffffff',
      weight: 2,
      fillOpacity: 0.9
    },
    poles: {
      radius: 5,
      fillColor: '#1a1a1a',
      color: '#ffffff',
      weight: 2,
      fillOpacity: 0.9
    },
    handholes: {
      // Square marker created via divIcon
      size: [18, 18],
      backgroundColor: '#10b981',
      borderColor: '#ffffff',
      borderWidth: 2
    }
  }
};

function showStatus(msg, isError = false) {
  statusDiv.textContent = msg;
  statusDiv.style.color = isError ? '#ef4444' : '#6b7280';
  statusPanel.classList.add('visible');

  // Auto-hide after 5 seconds if not an error
  if (!isError && !msg.includes('QC')) {
    setTimeout(() => {
      if (!qcResultDiv.innerHTML) {
        statusPanel.classList.remove('visible');
      }
    }, 5000);
  }
}

function hideStatus() {
  statusPanel.classList.remove('visible');
  qcResultDiv.innerHTML = '';
}

function showLoading(show = true) {
  loadingOverlay.style.display = show ? 'flex' : 'none';
}

function setButtonLoading(button, loading = true) {
  if (loading) {
    button.classList.add('loading');
    button.disabled = true;
  } else {
    button.classList.remove('loading');
    button.disabled = false;
  }
}

const map = L.map('map').setView([29.2, -99.7], 12);

// Create a custom pane for endpoint markers with high z-index
map.createPane('endpointPane');
map.getPane('endpointPane').style.zIndex = 650; // Higher than markerPane (600)

// Initialize endpoint markers layer group for toggling visibility
endpointMarkersLayer = L.layerGroup().addTo(map);

// Define multiple basemap options
const baseMaps = {
  'Clean (Light)': L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
    attribution: '© OpenStreetMap contributors © CARTO',
    subdomains: 'abcd',
    maxZoom: 20
  }),
  'Clean (Dark)': L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
    attribution: '© OpenStreetMap contributors © CARTO',
    subdomains: 'abcd',
    maxZoom: 20
  }),
  'OpenStreetMap': L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors',
    maxZoom: 19
  }),
  'Satellite': L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
    attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community',
    maxZoom: 19
  }),
  'Satellite + Labels': L.layerGroup([
    L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
      attribution: 'Tiles © Esri',
      maxZoom: 19
    }),
    L.tileLayer('https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}{r}.png', {
      attribution: '© CARTO',
      subdomains: 'abcd',
      maxZoom: 20
    })
  ])
};

// Add default basemap (Clean Light)
baseMaps['Clean (Light)'].addTo(map);

const layers = {
  segments: L.layerGroup().addTo(map),
  sites: L.layerGroup().addTo(map),
  info: L.layerGroup().addTo(map),
  handholes: L.layerGroup().addTo(map),
  poles: L.layerGroup().addTo(map),
  permits: L.layerGroup().addTo(map),
};

// Add layer control with basemaps and overlay layers
L.control.layers(baseMaps, {
  'Segments': layers.segments,
  'Sites': layers.sites,
  'Info Objects': layers.info,
  'Handholes': layers.handholes,
  'Poles': layers.poles,
  'Permits': layers.permits
}).addTo(map);

// Create custom legend control
const legend = L.control({ position: 'bottomright' });

legend.onAdd = function(map) {
  const div = L.DomUtil.create('div', 'legend');
  div.innerHTML = `
    <div class="legend-title">Layer Legend</div>
    <div class="legend-section-title">Segments</div>
    <div class="legend-item">
      <input type="checkbox" id="legend-aerial" checked onchange="toggleLayer('segments')">
      <svg width="30" height="6"><line x1="0" y1="3" x2="30" y2="3" stroke="#0066cc" stroke-width="4" stroke-linecap="round" opacity="0.85"/></svg>
      <label for="legend-aerial">Aerial</label>
    </div>
    <div class="legend-item">
      <input type="checkbox" id="legend-underground" checked onchange="toggleLayer('segments')">
      <svg width="30" height="6"><line x1="0" y1="3" x2="30" y2="3" stroke="#cc0000" stroke-width="4" stroke-linecap="round" opacity="0.85"/></svg>
      <label for="legend-underground">Underground</label>
    </div>
    <div class="legend-item-small">
      <svg width="20" height="10"><circle cx="10" cy="5" r="4" fill="#fbbf24" stroke="#1a1a1a" stroke-width="1.5"/></svg>
      <label>Start Point</label>
    </div>
    <div class="legend-item-small">
      <svg width="20" height="10"><circle cx="10" cy="5" r="4" fill="#ef4444" stroke="#1a1a1a" stroke-width="1.5"/></svg>
      <label>End Point</label>
    </div>
    <div class="legend-section-title">Features</div>
    <div class="legend-item">
      <input type="checkbox" id="legend-poles" checked onchange="toggleLayer('poles')">
      <svg width="30" height="14"><circle cx="15" cy="7" r="5" fill="#1a1a1a" stroke="white" stroke-width="2"/></svg>
      <label for="legend-poles">Poles</label>
    </div>
    <div class="legend-item">
      <input type="checkbox" id="legend-handholes" checked onchange="toggleLayer('handholes')">
      <svg width="30" height="14"><rect x="8" y="0" width="14" height="14" fill="#10b981" stroke="white" stroke-width="2" rx="2"/></svg>
      <label for="legend-handholes">Handholes</label>
    </div>
    <div class="legend-item">
      <input type="checkbox" id="legend-sites" checked onchange="toggleLayer('sites')">
      <svg width="30" height="14"><circle cx="15" cy="7" r="7" fill="#3b82f6" stroke="white" stroke-width="2"/></svg>
      <label for="legend-sites">Sites</label>
    </div>
    <div class="legend-item">
      <input type="checkbox" id="legend-info" checked onchange="toggleLayer('info')">
      <svg width="30" height="6"><line x1="0" y1="3" x2="30" y2="3" stroke="#9ca3af" stroke-width="2" stroke-dasharray="5,5" opacity="0.6"/></svg>
      <label for="legend-info">Info Objects</label>
    </div>
    <div class="legend-item">
      <input type="checkbox" id="legend-permits" checked onchange="toggleLayer('permits')">
      <svg width="30" height="14"><rect x="5" y="2" width="20" height="10" fill="#fbbf24" opacity="0.2" stroke="#f59e0b" stroke-width="2"/></svg>
      <label for="legend-permits">Permits</label>
    </div>
  `;
  return div;
};

legend.addTo(map);

// Function to toggle layers
function toggleLayer(layerName) {
  if (map.hasLayer(layers[layerName])) {
    map.removeLayer(layers[layerName]);
  } else {
    map.addLayer(layers[layerName]);
  }
}

function clearLayers() {
  Object.values(layers).forEach(layer => layer.clearLayers());
}

function loadMapData(market, zone) {
  clearLayers();
  hideStatus();
  showLoading(true);
  showStatus("Loading map data...");

  const endpoints = {
    segments: '/api/segments',
    sites: '/api/sites',
    info: '/api/info',
    handholes: '/api/access_points',
    poles: '/api/poles',
    permits: '/api/permits'
  };

  let loadedCount = 0;
  const totalLayers = Object.keys(endpoints).length;

  for (const [key, url] of Object.entries(endpoints)) {
    fetch(`${url}?map_id=${market}&zone=${zone}`)
      .then(res => res.json())
      .then(data => {
        console.log(`Loaded ${key} data:`, data);

        const layerOptions = {
          pointToLayer: (f, latlng) => {
            switch (key) {
              case 'sites':
                return L.circleMarker(latlng, {
                  radius: 7,
                  fillColor: '#3b82f6',
                  color: '#ffffff',
                  weight: 2,
                  opacity: 1,
                  fillOpacity: 0.9
                });
              case 'handholes':
                // Create a square marker for handholes (18x18 including 2px border on each side)
                const squareIcon = L.divIcon({
                  className: 'handhole-marker',
                  html: '<div style="background-color: #10b981; width: 14px; height: 14px; border: 2px solid white; border-radius: 2px; box-shadow: 0 2px 4px rgba(0,0,0,0.3);"></div>',
                  iconSize: [18, 18],
                  iconAnchor: [9, 9]
                });
                return L.marker(latlng, { icon: squareIcon });
              case 'poles':
                return L.circleMarker(latlng, {
                  radius: 5,
                  fillColor: '#1a1a1a',
                  color: '#ffffff',
                  weight: 2,
                  opacity: 1,
                  fillOpacity: 0.9
                });
              default: return L.marker(latlng);
            }
          },
          style: (f) => {
            switch (key) {
              case 'segments':
                // Color based on segment type
                const segmentType = f.properties.segment_type?.toLowerCase();
                if (segmentType === 'aerial') {
                  return {
                    color: '#0066cc',
                    weight: 4,
                    opacity: 0.85,
                    lineCap: 'round',
                    lineJoin: 'round'
                  }; // Blue for Aerial
                } else if (segmentType === 'underground') {
                  return {
                    color: '#cc0000',
                    weight: 4,
                    opacity: 0.85,
                    lineCap: 'round',
                    lineJoin: 'round'
                  }; // Red for Underground
                } else {
                  return {
                    color: '#808080',
                    weight: 4,
                    opacity: 0.7,
                    lineCap: 'round',
                    lineJoin: 'round'
                  }; // Gray for other types
                }
              case 'info': return LAYER_STYLES.zonePolygons;
              case 'permits': return {
                color: '#f59e0b',
                fillColor: '#fbbf24',
                fillOpacity: 0.2,
                weight: 2,
                opacity: 0.7
              };
              default: return {};
            }
          },
          filter: (f) => {
            if (key === 'segments') {
              const selectedType = document.getElementById('segmentTypeFilter').value;
              if (!selectedType) return true;
              const segmentType = f.properties.segment_type?.toLowerCase();
              return segmentType === selectedType.toLowerCase();
            }
            return true;
          }
        };

        const geoLayer = L.geoJSON(data, layerOptions).addTo(layers[key]);
        console.log(`${key} layer added`, geoLayer);

        // Add popups to all features
        if (key === 'sites') {
          geoLayer.eachLayer(layer => {
            if (layer.feature && layer.feature.properties) {
              const props = layer.feature.properties;
              layer.bindPopup(`
                <strong>🏠 Site Details</strong><br>
                <strong>ID:</strong> ${props.id || 'N/A'}<br>
                <strong>Name:</strong> ${props.name || 'N/A'}<br>
                <strong>Zone Assignment:</strong> ${props.group1 || props['Group 1'] || '<span style="color: red;">NULL/Unassigned</span>'}<br>
                <strong>Address:</strong> ${props.address || props.address1 || 'N/A'}<br>
                <strong>City:</strong> ${props.city || 'N/A'}<br>
                <strong>State:</strong> ${props.state || 'N/A'}<br>
                <strong>Zip:</strong> ${props.zip || 'N/A'}
              `);
            }
          });
        }

        if (key === 'poles') {
          geoLayer.eachLayer(layer => {
            if (layer.feature && layer.feature.properties) {
              const props = layer.feature.properties;
              layer.bindPopup(`
                <strong>⚡ Pole Details</strong><br>
                <strong>ID:</strong> ${props.id || 'N/A'}<br>
                <strong>Name:</strong> ${props.name || 'N/A'}<br>
                <strong>Zone Assignment:</strong> ${props.group1 || '<span style="color: red;">NULL/Unassigned</span>'}<br>
                <strong>Owner:</strong> ${props.owner || 'N/A'}<br>
                <strong>Height:</strong> ${props.poleheight || 'N/A'} ft<br>
                <strong>Attachment Height:</strong> ${props.attachmentheight || 'N/A'} ft
              `);
            }
          });
        }

        if (key === 'handholes') {
          geoLayer.eachLayer(layer => {
            if (layer.feature && layer.feature.properties) {
              const props = layer.feature.properties;
              layer.bindPopup(`
                <strong>🔧 Handhole/Access Point</strong><br>
                <strong>ID:</strong> ${props.id || 'N/A'}<br>
                <strong>Name:</strong> ${props.name || 'N/A'}<br>
                <strong>Zone Assignment:</strong> ${props.group1 || '<span style="color: red;">NULL/Unassigned</span>'}<br>
                <strong>Manufacturer:</strong> ${props.manufacturer || 'N/A'}<br>
                <strong>Size:</strong> ${props.size || 'N/A'}<br>
                <strong>Description:</strong> ${props.description || 'N/A'}
              `);
            }
          });
        }

        // Add labels and popups to zones
        if (key === 'info') {
          geoLayer.eachLayer(layer => {
            if (layer.feature && layer.feature.properties) {
              const props = layer.feature.properties;
              const zoneName = props.name || props.group_1 || 'Unknown Zone';

              // Add popup
              layer.bindPopup(`
                <strong>Zone: ${zoneName}</strong><br>
                ${props.description ? `<em>${props.description}</em><br>` : ''}
                ${props.group_1 ? `<strong>Group:</strong> ${props.group_1}` : ''}
              `);

              // Add permanent label at center of zone
              const center = layer.getBounds().getCenter();
              L.marker(center, {
                icon: L.divIcon({
                  className: 'zone-label',
                  html: `<div style="background: rgba(99, 102, 241, 0.9); color: white; padding: 4px 8px; border-radius: 4px; font-weight: 600; font-size: 12px; white-space: nowrap; box-shadow: 0 2px 4px rgba(0,0,0,0.3);">${zoneName}</div>`,
                  iconSize: [100, 20],
                  iconAnchor: [50, 10]
                })
              }).addTo(layers[key]);
            }
          });

          // Zoom to zones
          if (geoLayer.getBounds().isValid()) {
            console.log("Zooming to zones bounds:", geoLayer.getBounds());
            map.fitBounds(geoLayer.getBounds(), { padding: [50, 50] });
          }
        }

        // Add interactivity for segments
        if (key === 'segments') {
          geoLayer.eachLayer(layer => {
            // Add hover effect
            layer.on('mouseover', function(e) {
              this.setStyle({ weight: 6, opacity: 1 });
            });
            layer.on('mouseout', function(e) {
              geoLayer.resetStyle(this);
            });

            // Add popup with segment info
            if (layer.feature && layer.feature.properties) {
              const props = layer.feature.properties;
              const zoneDisplay = props.group_1 || props['Group 1'] || '<span style="color: red;">NULL/Unassigned</span>';
              layer.bindPopup(`
                <strong>📏 Segment Details</strong><br>
                <strong>ID:</strong> ${props.id || 'N/A'}<br>
                <strong>Type:</strong> ${props.segment_type || 'N/A'}<br>
                <strong>Zone Assignment:</strong> ${zoneDisplay}<br>
                <strong>Status:</strong> ${props.segment_status || 'N/A'}<br>
                <strong>Protection:</strong> ${props.protection_status || 'N/A'}<br>
                <strong>QC Flag:</strong> ${props.qc_flag || 'None'}
              `);
            }
          });

          // Zoom to segments immediately after they load
          if (geoLayer.getBounds().isValid()) {
            console.log("Zooming to segments bounds:", geoLayer.getBounds());
            map.fitBounds(geoLayer.getBounds(), { padding: [50, 50] });
          }
        }

        loadedCount++;
        if (loadedCount === totalLayers) {
          showLoading(false);
          showStatus("All layers loaded successfully.");
        }
      })
      .catch(err => {
        console.error(`Failed to load ${key}:`, err);
        showLoading(false);
        showStatus(`Error loading ${key}.`, true);
      });
  }
}

// Populate dropdowns
const marketSelect = document.getElementById('marketSelect');
const zoneSelect = document.getElementById('zoneSelect');

function loadMarkets() {
  fetch('/api/markets')
    .then(res => res.json())
    .then(data => {
      console.log('Markets data:', data);
      marketSelect.innerHTML = '<option value="">Select Market</option>';
      data.forEach(m => {
        const opt = document.createElement('option');
        opt.value = m.mapid;
        opt.textContent = m.project;
        marketSelect.appendChild(opt);
      });
    })
    .catch(err => {
      console.error('Failed to load markets:', err);
      marketSelect.innerHTML = '<option value="">Error loading markets</option>';
    });
}

function loadZones() {
  const market = marketSelect.value;
  if (!market) {
    zoneSelect.innerHTML = '<option value="">Select market first</option>';
    zoneSelect.disabled = true;
    return;
  }

  console.log(`/api/zones?map_id=${market}`);
  fetch(`/api/zones?map_id=${market}`)
    .then(res => res.json())
    .then(data => {
      zoneSelect.innerHTML = '<option value="">Select Zone</option>';
      data.forEach(z => {
        const opt = document.createElement('option');
        opt.value = z;
        opt.textContent = z;
        zoneSelect.appendChild(opt);
      });
      zoneSelect.disabled = false;
    })
    .catch(err => {
      console.error('Failed to load zones:', err);
      zoneSelect.innerHTML = '<option value="">Error loading zones</option>';
      zoneSelect.disabled = true;
    });
}

// Show the clear QC button
function showClearQCButton() {
  document.getElementById('clearQCButton').style.display = 'inline-block';
}

function showEndpointToggle() {
  document.getElementById('endpointToggleContainer').style.display = 'flex';
}

// Clear all QC result layers
function clearQCResults() {
  // Clear connectivity layers
  if (connectivityLayers && connectivityLayers.length > 0) {
    connectivityLayers.forEach(layer => map.removeLayer(layer));
    connectivityLayers = [];
  }

  // Clear invalid span layer
  if (invalidSpanLayer) {
    map.removeLayer(invalidSpanLayer);
    invalidSpanLayer = null;
  }

  // Clear disconnected handhole layer
  if (disconnectedHandholeLayer) {
    map.removeLayer(disconnectedHandholeLayer);
    disconnectedHandholeLayer = null;
  }

  // Clear disconnected sites layer
  if (disconnectedSitesLayer) {
    map.removeLayer(disconnectedSitesLayer);
    disconnectedSitesLayer = null;
  }

  // Clear invalid aerial endpoint layer
  if (invalidAerialEndpointLayer) {
    map.removeLayer(invalidAerialEndpointLayer);
    invalidAerialEndpointLayer = null;
  }

  // Clear invalid underground layer
  if (invalidUndergroundLayer) {
    map.removeLayer(invalidUndergroundLayer);
    invalidUndergroundLayer = null;
  }

  // Clear invalid zone containment layer
  if (invalidZoneContainmentLayer) {
    map.removeLayer(invalidZoneContainmentLayer);
    invalidZoneContainmentLayer = null;
  }

  // Clear endpoint markers
  if (endpointMarkersLayer) {
    endpointMarkersLayer.clearLayers();
  }

  // Restore base segments layer if it was hidden
  if (layers.segments && !map.hasLayer(layers.segments)) {
    map.addLayer(layers.segments);
  }

  // Hide clear button
  document.getElementById('clearQCButton').style.display = 'none';

  // Hide endpoint toggle
  document.getElementById('endpointToggleContainer').style.display = 'none';

  // Hide status panel
  hideStatus();

  console.log('All QC results cleared');
}

// Clear QC button handler
document.getElementById('clearQCButton').addEventListener('click', clearQCResults);

// Endpoint toggle handler
document.getElementById('endpointToggle').addEventListener('change', function() {
  if (this.checked) {
    // Show endpoints
    if (endpointMarkersLayer && !map.hasLayer(endpointMarkersLayer)) {
      map.addLayer(endpointMarkersLayer);
    }
  } else {
    // Hide endpoints
    if (endpointMarkersLayer && map.hasLayer(endpointMarkersLayer)) {
      map.removeLayer(endpointMarkersLayer);
    }
  }
});

marketSelect.addEventListener('change', () => {
  const market = marketSelect.value;
  console.log("Selected Market ID:", market);
  loadZones();

  // Clear QC results when changing market
  clearQCResults();

  const zone = zoneSelect.value;
  if (market && zone) {
    loadMapData(market, zone);
  }
});

zoneSelect.addEventListener('change', () => {
  const market = marketSelect.value;
  const zone = zoneSelect.value;
  console.log("Selected Market ID & Zone:", market, zone);

  // Clear QC results when changing zone
  clearQCResults();

  if (market && zone) {
    loadMapData(market, zone);
  }
});

loadMarkets();
loadZones();

const segmentTypeFilter = document.getElementById('segmentTypeFilter');
segmentTypeFilter.addEventListener('change', () => {
  const market = marketSelect.value;
  const zone = zoneSelect.value;
  if (market && zone) {
    loadMapData(market, zone);
  }
});

// Enable/disable Run QC button based on dropdown selection
const qcOperationSelect = document.getElementById('qcOperationSelect');
const runQCButton = document.getElementById('runQCButton');

qcOperationSelect.addEventListener('change', () => {
  runQCButton.disabled = !qcOperationSelect.value;
});

// Consolidated QC button handler
runQCButton.addEventListener('click', () => {
  const operation = qcOperationSelect.value;
  if (!operation) return;

  switch(operation) {
    case 'connectivity':
      runConnectivityQC();
      break;
    case 'single-span':
      runSingleSpanQC();
      break;
    case 'aerial-endpoints':
      runAerialEndpointQC();
      break;
    case 'underground-endpoints':
      runUndergroundEndpointQC();
      break;
    case 'zone-containment':
      runZoneContainmentQC();
      break;
    case 'handhole-connectivity':
      runAccessPointQC();
      break;
    case 'site-connectivity':
      runSiteConnectivityQC();
      break;
  }
});

/// Connectivity QC
let connectivityLayers = [];

function runConnectivityQC() {
  const market = marketSelect.value;
  const zone = zoneSelect.value;

  if (!market || !zone) {
    alert("Select a market and zone first.");
    return;
  }

  setButtonLoading(runQCButton, true);
  hideStatus();

  // Clear previous connectivity layers
  connectivityLayers.forEach(layer => map.removeLayer(layer));
  connectivityLayers = [];

  // Hide the base segments layer temporarily so QC colors are visible
  if (map.hasLayer(layers.segments)) {
    map.removeLayer(layers.segments);
  }

  fetch(`/api/qc/connectivity?map_id=${market}&zone=${zone}`)
    .then(res => res.json())
    .then(data => {
      console.log("Connectivity QC data received:", data);
      console.log("Number of features:", data.features ? data.features.length : 0);
      if (data.features && data.features.length > 0) {
        console.log("First feature:", data.features[0]);
      }

      const { components, totalSegments } = getConnectedComponents(data);

      setButtonLoading(runQCButton, false);
      statusPanel.classList.add('visible');

      if (components.length === 1) {
        qcResultDiv.textContent = "✅ Segment network is fully connected.";
        qcResultDiv.style.color = "#10b981";
        showClearQCButton();

        // Show the single connected network in bright blue with white outline
        // Draw white outline first
        const outlineLayer = L.geoJSON(components[0].segments, {
          style: {
            color: 'white',
            weight: 10,
            opacity: 1.0
          }
        }).addTo(map);
        connectivityLayers.push(outlineLayer);

        // Draw bright blue line on top
        const layer = L.geoJSON(components[0].segments, {
          style: {
            color: '#00bfff',
            weight: 6,
            opacity: 1.0
          },
          onEachFeature: (feature, layer) => {
            const props = feature.properties;

            // Add hover effect
            layer.on('mouseover', function() {
              this.setStyle({ weight: 8, opacity: 1 });
            });
            layer.on('mouseout', function() {
              this.setStyle({ weight: 6, opacity: 1.0 });
            });

            layer.bindPopup(`
              <strong>✅ Main Connected Network</strong><br>
              <strong>Segment ID:</strong> ${props.id || 'N/A'}<br>
              <strong>ID_0:</strong> ${props.id_0 || 'N/A'}<br>
              <strong>Type:</strong> ${props.segment_type || 'N/A'}<br>
              <strong>Status:</strong> ${props.segment_status || 'N/A'}<br>
              <strong>Protection:</strong> ${props.protection_status || 'N/A'}<br>
              <strong>Map ID:</strong> ${props.mapid || 'N/A'}
            `);

            // Add endpoint markers
            if (feature.geometry && feature.geometry.coordinates) {
              let coords = feature.geometry.coordinates;

              // Handle MultiLineString - extract first linestring
              if (feature.geometry.type === 'MultiLineString' && coords.length > 0) {
                coords = coords[0];
              }

              console.log('Adding endpoint markers for segment:', props.id, 'coords length:', coords.length);

              if (coords && coords.length >= 2) {
                const startCoord = [coords[0][1], coords[0][0]];
                const endCoord = [coords[coords.length - 1][1], coords[coords.length - 1][0]];

                console.log('Start coord:', startCoord, 'End coord:', endCoord);

                // Start point (yellow)
                L.circleMarker(startCoord, {
                  radius: 6,
                  fillColor: '#fbbf24',
                  color: '#000000',
                  weight: 2,
                  opacity: 1,
                  fillOpacity: 1,
                  pane: 'endpointPane',
                  zIndexOffset: 1000
                }).bindPopup(`<strong>🟡 Segment Start</strong><br>ID: ${props.id || 'N/A'}`).addTo(endpointMarkersLayer);

                // End point (red)
                L.circleMarker(endCoord, {
                  radius: 6,
                  fillColor: '#ef4444',
                  color: '#000000',
                  weight: 2,
                  opacity: 1,
                  fillOpacity: 1,
                  pane: 'endpointPane',
                  zIndexOffset: 1000
                }).bindPopup(`<strong>🔴 Segment End</strong><br>ID: ${props.id || 'N/A'}`).addTo(endpointMarkersLayer);
              }
            }
          }
        }).addTo(map);
        connectivityLayers.push(layer);

        // Show endpoint toggle since we've added endpoint markers
        showEndpointToggle();

      } else {
        // Multiple components - color code them
        const largestComponent = components[0];
        const disconnectedComponents = components.slice(1);
        const totalDisconnected = disconnectedComponents.reduce((sum, c) => sum + c.segments.length, 0);

        qcResultDiv.innerHTML = `
          📊 Network Connectivity Analysis:<br>
          • Main Network: ${largestComponent.segments.length} segments (bright blue)<br>
          • Disconnected Groups: ${disconnectedComponents.length} (${totalDisconnected} segments)<br>
          • Total Segments: ${totalSegments}
        `;
        qcResultDiv.style.color = "#f59e0b";
        showClearQCButton();

        // Color palette for different components
        // First color is for main network (bright blue with special styling)
        // Remaining colors are for disconnected groups (avoiding blues/cyans)
        const colors = [
          '#00bfff',  // Bright blue for main network (solid, thick)
          '#ff0000',  // Red
          '#ff8c00',  // Orange
          '#00ff00',  // Lime/Green
          '#ff00ff',  // Magenta
          '#ffff00',  // Yellow
          '#ff1493',  // Deep pink
          '#9400d3',  // Violet/Purple
          '#ff6347',  // Tomato/Coral
          '#ffa500',  // Gold/Amber
          '#32cd32',  // Bright lime
          '#ff69b4',  // Hot pink
          '#8b4513',  // Saddle brown
          '#ff4500',  // Orange red
          '#9370db'   // Medium purple
        ];

        // Visualize each component with its color
        components.forEach((component, index) => {
          const color = colors[index % colors.length];
          const isMainNetwork = index === 0;

          // For main network, add a white outline for extra distinction
          if (isMainNetwork) {
            // Draw white outline first (underneath)
            const outlineLayer = L.geoJSON(component.segments, {
              style: {
                color: 'white',
                weight: 10,
                opacity: 1.0
              }
            }).addTo(map);
            connectivityLayers.push(outlineLayer);
          }

          // Draw the main colored line
          const layer = L.geoJSON(component.segments, {
            style: {
              color: color,
              weight: isMainNetwork ? 6 : 7,
              opacity: 1.0,
              dashArray: isMainNetwork ? '' : '10,6'
            },
            onEachFeature: (feature, layer) => {
              const props = feature.properties;
              const componentLabel = isMainNetwork
                ? `<strong>✅ Main Connected Network</strong>`
                : `<strong>🚨 Disconnected Group ${index}</strong>`;
              const componentInfo = isMainNetwork
                ? ``
                : `<strong>Group Size:</strong> ${component.segments.length} segment(s)<br>`;

              // Add hover effect
              layer.on('mouseover', function() {
                this.setStyle({ weight: isMainNetwork ? 8 : 9, opacity: 1 });
              });
              layer.on('mouseout', function() {
                this.setStyle({ weight: isMainNetwork ? 6 : 7, opacity: 1.0 });
              });

              layer.bindPopup(`
                ${componentLabel}<br>
                ${componentInfo}
                <strong>Segment ID:</strong> ${props.id || 'N/A'}<br>
                <strong>ID_0:</strong> ${props.id_0 || 'N/A'}<br>
                <strong>Type:</strong> ${props.segment_type || 'N/A'}<br>
                <strong>Status:</strong> ${props.segment_status || 'N/A'}<br>
                <strong>Protection:</strong> ${props.protection_status || 'N/A'}<br>
                <strong>Map ID:</strong> ${props.mapid || 'N/A'}
              `);

              // Add endpoint markers
              if (feature.geometry && feature.geometry.coordinates) {
                let coords = feature.geometry.coordinates;

                // Handle MultiLineString - extract first linestring
                if (feature.geometry.type === 'MultiLineString' && coords.length > 0) {
                  coords = coords[0];
                }

                console.log('Multi-component: Adding endpoint markers for segment:', props.id, 'coords length:', coords.length, 'Group:', index);

                if (coords && coords.length >= 2) {
                  const startCoord = [coords[0][1], coords[0][0]];
                  const endCoord = [coords[coords.length - 1][1], coords[coords.length - 1][0]];

                  console.log('Multi-component Start coord:', startCoord, 'End coord:', endCoord);

                  // Start point (yellow)
                  L.circleMarker(startCoord, {
                    radius: 6,
                    fillColor: '#fbbf24',
                    color: '#000000',
                    weight: 2,
                    opacity: 1,
                    fillOpacity: 1,
                    pane: 'endpointPane',
                    zIndexOffset: 1000
                  }).bindPopup(`<strong>🟡 Segment Start</strong><br>ID: ${props.id || 'N/A'}<br>Group: ${isMainNetwork ? 'Main Network' : 'Disconnected ' + index}`).addTo(endpointMarkersLayer);

                  // End point (red)
                  L.circleMarker(endCoord, {
                    radius: 6,
                    fillColor: '#ef4444',
                    color: '#000000',
                    weight: 2,
                    opacity: 1,
                    fillOpacity: 1,
                    pane: 'endpointPane',
                    zIndexOffset: 1000
                  }).bindPopup(`<strong>🔴 Segment End</strong><br>ID: ${props.id || 'N/A'}<br>Group: ${isMainNetwork ? 'Main Network' : 'Disconnected ' + index}`).addTo(endpointMarkersLayer);
                }
              }
            }
          }).addTo(map);

          connectivityLayers.push(layer);
        });

        // Show endpoint toggle since we've added endpoint markers
        showEndpointToggle();

        // Zoom to show all segments
        const allBounds = L.latLngBounds();
        connectivityLayers.forEach(layer => {
          // Only GeoJSON layers have getBounds, skip markers
          if (layer.getBounds && typeof layer.getBounds === 'function') {
            const bounds = layer.getBounds();
            if (bounds.isValid()) {
              allBounds.extend(bounds);
            }
          } else if (layer.getLatLng && typeof layer.getLatLng === 'function') {
            // For individual markers, extend by their position
            allBounds.extend(layer.getLatLng());
          }
        });
        if (allBounds.isValid()) {
          map.fitBounds(allBounds, { padding: [30, 30] });
        }

        // Tag disconnected segments in DB
        const disconnectedIds = disconnectedComponents.flatMap(c =>
          c.segments.map(s => s.properties.id)
        );

        fetch('/api/qc/tag-disconnected', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ ids: disconnectedIds })
        })
        .then(res => res.json())
        .then(data => {
          console.log("Tagging complete:", data.message);
        })
        .catch(err => console.error("Error tagging disconnected segments:", err));
      }
    })
    .catch(err => {
      console.error("Connectivity QC error:", err);
      setButtonLoading(runQCButton, false);
      qcResultDiv.textContent = "Error running QC";
      qcResultDiv.style.color = "#ef4444";
      showClearQCButton();
      statusPanel.classList.add('visible');
    });
}

/// Single Span QC - NEW FUNCTIONALITY
let invalidSpanLayer;

function runSingleSpanQC() {
  const market = marketSelect.value;
  const zone = zoneSelect.value;

  if (!market || !zone) {
    alert("Select a market and zone first.");
    return;
  }

  setButtonLoading(runQCButton, true);
  hideStatus();

  // Clear previous invalid span layer
  if (invalidSpanLayer) {
    map.removeLayer(invalidSpanLayer);
    invalidSpanLayer = null;
  }

  showStatus("Running Single Span QC...");

  fetch(`/api/qc/single-span?map_id=${market}&zone=${zone}`)
    .then(res => res.json())
    .then(data => {
      setButtonLoading(runQCButton, false);
      statusPanel.classList.add('visible');

      if (data.invalid_segments === 0) {
        qcResultDiv.innerHTML = `✅ All ${data.total_aerial_segments} aerial segments have valid single spans.`;
        qcResultDiv.style.color = "#10b981";
        showClearQCButton();
        showStatus("Single Span QC completed - All segments valid.");
      } else {
        qcResultDiv.innerHTML = `
          ❌ Single Span QC Results:<br>
          • Total Aerial Segments: ${data.total_aerial_segments}<br>
          • Valid: ${data.valid_segments}<br>
          • Invalid: ${data.invalid_segments}<br>
          • Pass Rate: ${data.pass_rate.toFixed(1)}%
        `;
        qcResultDiv.style.color = "#ef4444";
        showClearQCButton();
        showStatus(`Single Span QC completed - ${data.invalid_segments} segments need attention.`, true);

        // Get invalid segments and highlight them on map
        const invalidSegments = data.results.filter(r => !r.is_valid);
        console.log("Invalid segments:", invalidSegments);
        
        // Create GeoJSON features for invalid segments
        const invalidFeatures = [];
        invalidSegments.forEach(segment => {
          if (segment.geometry) {
            invalidFeatures.push({
              type: "Feature",
              geometry: segment.geometry,
              properties: {
                segment_id: segment.segment_id,
                error_message: segment.error_message,
                vertex_count: segment.vertex_count
              }
            });
          }
          console.log(`Invalid segment ${segment.segment_id}: ${segment.error_message}`);
        });

        // Add invalid segments to map if we have geometry data
        if (invalidFeatures.length > 0) {
          invalidSpanLayer = L.geoJSON(invalidFeatures, {
            style: {
              color: 'orange',
              weight: 5,
              dashArray: '10,5'
            },
            onEachFeature: (feature, layer) => {
              // Add hover effect
              layer.on('mouseover', function() {
                this.setStyle({ weight: 7 });
              });
              layer.on('mouseout', function() {
                this.setStyle({ weight: 5 });
              });

              layer.bindPopup(`
                🚨 Invalid Single Span<br>
                <strong>Segment ID:</strong> ${feature.properties.segment_id}<br>
                <strong>Vertices:</strong> ${feature.properties.vertex_count}<br>
                <strong>Error:</strong> ${feature.properties.error_message}
              `);

              // Add endpoint markers
              if (feature.geometry && feature.geometry.coordinates) {
                let coords = feature.geometry.coordinates;

                // Handle MultiLineString - extract first linestring
                if (feature.geometry.type === 'MultiLineString' && coords.length > 0) {
                  coords = coords[0];
                }

                if (coords && coords.length >= 2) {
                  // Start point (yellow)
                  L.circleMarker([coords[0][1], coords[0][0]], {
                    radius: 6,
                    fillColor: '#fbbf24',
                    color: '#000000',
                    weight: 2,
                    opacity: 1,
                    fillOpacity: 1,
                    pane: 'endpointPane'
                  }).bindPopup(`<strong>Segment Start</strong><br>ID: ${feature.properties.segment_id || 'N/A'}`).addTo(map);

                  // End point (red)
                  L.circleMarker([coords[coords.length - 1][1], coords[coords.length - 1][0]], {
                    radius: 6,
                    fillColor: '#ef4444',
                    color: '#000000',
                    weight: 2,
                    opacity: 1,
                    fillOpacity: 1,
                    pane: 'endpointPane'
                  }).bindPopup(`<strong>Segment End</strong><br>ID: ${feature.properties.segment_id || 'N/A'}`).addTo(map);
                }
              }
            }
          }).addTo(map);
        }
      }
    })
    .catch(err => {
      console.error("Single Span QC error:", err);
      setButtonLoading(runQCButton, false);
      qcResultDiv.textContent = "Error running Single Span QC";
      qcResultDiv.style.color = "#ef4444";
      showClearQCButton();
      statusPanel.classList.add('visible');
      showStatus("Error running Single Span QC", true);
    });
}

function getConnectedComponents(geojson) {
  const nodes = new Map();
  const edges = [];

  console.log("Processing geojson with", geojson.features.length, "features");

  // Build graph from segments
  for (const feat of geojson.features) {
    if (!feat.geometry || !feat.geometry.coordinates) {
      console.warn("Feature missing geometry:", feat);
      continue;
    }

    let coords = feat.geometry.coordinates;

    // Handle MultiLineString - extract first LineString
    if (feat.geometry.type === 'MultiLineString') {
      console.log("MultiLineString detected, coords:", coords);
      if (!coords || coords.length === 0 || !coords[0] || coords[0].length < 2) {
        console.warn("Invalid MultiLineString:", coords);
        continue;
      }
      coords = coords[0]; // Use first linestring
    }

    if (!coords || coords.length < 2) {
      console.warn("Invalid coords:", coords);
      continue;
    }

    // Verify coordinate structure
    if (!coords[0] || !Array.isArray(coords[0]) || coords[0].length < 2) {
      console.warn("Invalid start coordinate:", coords[0]);
      continue;
    }
    if (!coords[coords.length - 1] || !Array.isArray(coords[coords.length - 1])) {
      console.warn("Invalid end coordinate:", coords[coords.length - 1]);
      continue;
    }

    const start = coords[0].join(',');
    const end = coords[coords.length - 1].join(',');

    edges.push([start, end, feat]);

    if (!nodes.has(start)) nodes.set(start, []);
    if (!nodes.has(end)) nodes.set(end, []);
    nodes.get(start).push(end);
    nodes.get(end).push(start);
  }

  // Check if we have any edges to process
  if (edges.length === 0) {
    return { components: [], totalSegments: 0 };
  }

  // Find all connected components using DFS
  const visitedNodes = new Set();
  const components = [];

  // Helper function to perform DFS and collect all nodes in a component
  function dfs(startNode) {
    const componentNodes = new Set();
    const stack = [startNode];

    while (stack.length) {
      const node = stack.pop();
      if (componentNodes.has(node)) continue;
      componentNodes.add(node);
      visitedNodes.add(node);

      for (const neighbor of nodes.get(node) || []) {
        if (!componentNodes.has(neighbor)) {
          stack.push(neighbor);
        }
      }
    }

    return componentNodes;
  }

  // Find all connected components
  for (const node of nodes.keys()) {
    if (!visitedNodes.has(node)) {
      const componentNodes = dfs(node);

      // Collect all edges (segments) that belong to this component
      const componentSegments = [];
      for (const [start, end, feature] of edges) {
        if (componentNodes.has(start) && componentNodes.has(end)) {
          componentSegments.push(feature);
        }
      }

      if (componentSegments.length > 0) {
        components.push({
          nodes: Array.from(componentNodes),
          segments: componentSegments,
          size: componentSegments.length
        });
      }
    }
  }

  // Sort components by size (largest first)
  components.sort((a, b) => b.size - a.size);

  console.log(`Found ${components.length} connected component(s):`,
    components.map(c => `${c.size} segments`));

  return {
    components: components,
    totalSegments: edges.length
  };
}

let disconnectedHandholeLayer;

function runAccessPointQC() {
  const market = marketSelect.value;
  const zone = zoneSelect.value;

  if (!market || !zone) {
    alert("Select a market and zone first.");
    return;
  }

  setButtonLoading(runQCButton, true);
  hideStatus();

  // Clear previous layer
  if (disconnectedHandholeLayer) {
    map.removeLayer(disconnectedHandholeLayer);
    disconnectedHandholeLayer = null;
  }

  showStatus("Running Handhole Connectivity QC...");

  const segmentFeatures = [];
  layers.segments.eachLayer(layer => {
    if (layer.feature) segmentFeatures.push(layer.feature);
  });

  const handholeFeatures = [];
  layers.handholes.eachLayer(layer => {
    if (layer.feature) handholeFeatures.push(layer.feature);
  });

  if (!segmentFeatures.length || !handholeFeatures.length) {
    setButtonLoading(runQCButton, false);
    showStatus("Segments or handholes not loaded.", true);
    return;
  }

  const endpoints = [];
  segmentFeatures.forEach(feature => {
    const coords = feature.geometry.coordinates;
    endpoints.push(turf.point(coords[0]));
    endpoints.push(turf.point(coords[coords.length - 1]));
  });

  const endpointCollection = turf.featureCollection(endpoints);
  const disconnectedHHs = [];

  handholeFeatures.forEach(hh => {
    const hhPoint = turf.point(hh.geometry.coordinates);
    const nearest = turf.nearestPoint(hhPoint, endpointCollection);
    const distance = turf.distance(hhPoint, nearest, { units: 'meters' });

    if (distance > 1.0) {
      disconnectedHHs.push(hh);
    }
  });

  setButtonLoading(runQCButton, false);
  statusPanel.classList.add('visible');

  if (disconnectedHHs.length === 0) {
    qcResultDiv.textContent = "✅ All handholes are connected.";
    qcResultDiv.style.color = "#10b981";
    showClearQCButton();
    showStatus("Handhole Connectivity QC passed.");
  } else {
    qcResultDiv.textContent = `❌ Found ${disconnectedHHs.length} disconnected handhole(s).`;
    qcResultDiv.style.color = "#ef4444";
    showClearQCButton();
    showStatus(`Found ${disconnectedHHs.length} disconnected handhole(s).`, true);

    disconnectedHandholeLayer = L.geoJSON(disconnectedHHs, {
      pointToLayer: (f, latlng) => L.circleMarker(latlng, {
        radius: 8,
        color: 'red',
        fillOpacity: 0.8
      }),
      onEachFeature: (feature, layer) => {
        const id = feature.properties.id || 'Unknown';
        const name = feature.properties.name || 'Unnamed';
        layer.bindPopup(`🚨 Disconnected Handhole<br>ID: ${id}<br>Name: ${name}`);
      }
    }).addTo(map);
  }
}

/// Site Connectivity QC - NEW FUNCTIONALITY
let disconnectedSitesLayer;

function runSiteConnectivityQC() {
  const market = marketSelect.value;
  const zone = zoneSelect.value;

  if (!market) {
    alert("Select a market first.");
    return;
  }

  setButtonLoading(runQCButton, true);
  hideStatus();

  // Clear previous disconnected sites layer
  if (disconnectedSitesLayer) {
    map.removeLayer(disconnectedSitesLayer);
    disconnectedSitesLayer = null;
  }

  showStatus("Checking site connectivity...");

  // Build query parameters
  let queryParams = `map_id=${market}`;
  if (zone) {
    queryParams += `&zone=${zone}`;
  }

  // Add max distance parameter (default 50m, user could modify this)
  queryParams += `&max_distance=50`;

  fetch(`/api/qc/site-connectivity?${queryParams}`)
    .then(res => res.json())
    .then(data => {
      setButtonLoading(runQCButton, false);
      statusPanel.classList.add('visible');

      if (data.disconnected_sites === 0) {
        qcResultDiv.innerHTML = `✅ All ${data.total_sites} sites are connected to the network (within 50m).`;
        qcResultDiv.style.color = "#10b981";
        showClearQCButton();
        showStatus("Site Connectivity QC completed - All sites connected.");
      } else {
        qcResultDiv.innerHTML = `
          📡 Site Connectivity Results:<br>
          • Total Sites: ${data.total_sites}<br>
          • Connected: ${data.connected_sites}<br>
          • Disconnected: ${data.disconnected_sites}<br>
          • Connectivity Rate: ${data.connectivity_rate.toFixed(1)}%<br>
          • Max Distance: ${data.max_distance_meters}m
        `;
        qcResultDiv.style.color = data.disconnected_sites > 0 ? "#ef4444" : "#10b981";
        showClearQCButton();
        showStatus(`Site Connectivity QC completed - ${data.disconnected_sites} sites need attention.`, data.disconnected_sites > 0);

        // Get disconnected sites and highlight them on map
        const disconnectedSites = data.results.filter(r => !r.is_connected);
        console.log("Disconnected sites:", disconnectedSites);
        
        // Create GeoJSON features for disconnected sites
        const disconnectedFeatures = [];
        disconnectedSites.forEach(site => {
          if (site.geometry) {
            disconnectedFeatures.push({
              type: "Feature",
              geometry: JSON.parse(site.geometry),
              properties: {
                site_id: site.site_id,
                site_name: site.site_name,
                address: site.address,
                city: site.city,
                state: site.state,
                nearest_distance: site.nearest_distance,
                connectivity_status: site.connectivity_status
              }
            });
          }
        });

        // Add disconnected sites to map if we have geometry data
        if (disconnectedFeatures.length > 0) {
          disconnectedSitesLayer = L.geoJSON(disconnectedFeatures, {
            pointToLayer: (f, latlng) => L.circleMarker(latlng, {
              radius: 8,
              color: 'red',
              fillColor: 'red',
              fillOpacity: 0.8,
              weight: 3
            }),
            onEachFeature: (feature, layer) => {
              const props = feature.properties;
              layer.bindPopup(`
                🚨 Disconnected Site<br>
                <strong>ID:</strong> ${props.site_id}<br>
                <strong>Name:</strong> ${props.site_name || 'Unnamed'}<br>
                <strong>Address:</strong> ${props.address || 'N/A'}<br>
                <strong>Distance to Network:</strong> ${props.nearest_distance.toFixed(1)}m<br>
                <strong>Status:</strong> ${props.connectivity_status}
              `);
            }
          }).addTo(map);

          // Fit map to disconnected sites if any exist
          if (disconnectedSitesLayer.getBounds().isValid()) {
            map.fitBounds(disconnectedSitesLayer.getBounds(), { padding: [20, 20] });
          }
        }

        // Log database update confirmation
        console.log("Site connectivity status updated in database for QGIS analysis");
      }
    })
    .catch(err => {
      console.error("Site Connectivity QC error:", err);
      setButtonLoading(runQCButton, false);
      qcResultDiv.textContent = "Error running Site Connectivity QC";
      qcResultDiv.style.color = "#ef4444";
      showClearQCButton();
      statusPanel.classList.add('visible');
      showStatus("Error running Site Connectivity QC", true);
    });
}

/// Aerial Endpoint QC - NEW FUNCTIONALITY
let invalidAerialEndpointLayer;

function runAerialEndpointQC() {
  const market = marketSelect.value;
  const zone = zoneSelect.value;

  if (!market || !zone) {
    alert("Select a market and zone first.");
    return;
  }

  setButtonLoading(runQCButton, true);
  hideStatus();

  // Clear previous invalid aerial endpoint layer
  if (invalidAerialEndpointLayer) {
    map.removeLayer(invalidAerialEndpointLayer);
    invalidAerialEndpointLayer = null;
  }

  showStatus("Running Aerial Endpoint QC...");

  fetch(`/api/qc/aerial-endpoints?map_id=${market}&zone=${zone}`)
    .then(res => res.json())
    .then(data => {
      setButtonLoading(runQCButton, false);
      statusPanel.classList.add('visible');

      if (data.invalid_segments === 0) {
        qcResultDiv.innerHTML = `✅ All ${data.total_aerial_segments} aerial segments have exactly one pole at each endpoint.`;
        qcResultDiv.style.color = "#10b981";
        showClearQCButton();
        showStatus("Aerial Endpoint QC completed - All segments valid.");
      } else {
        qcResultDiv.innerHTML = `
          🔌 Aerial Endpoint QC Results:<br>
          • Total Aerial Segments: ${data.total_aerial_segments}<br>
          • Valid: ${data.valid_segments}<br>
          • Invalid: ${data.invalid_segments}<br>
          • Pass Rate: ${data.pass_rate.toFixed(1)}%
        `;
        qcResultDiv.style.color = "#ef4444";
        showClearQCButton();
        showStatus(`Aerial Endpoint QC completed - ${data.invalid_segments} segments need attention.`, true);

        // Get invalid segments and highlight them on map
        const invalidSegments = data.results.filter(r => !r.is_valid);
        console.log("Invalid aerial endpoint segments:", invalidSegments);

        // Create GeoJSON features for invalid segments
        const invalidFeatures = [];
        invalidSegments.forEach(segment => {
          if (segment.geometry) {
            invalidFeatures.push({
              type: "Feature",
              geometry: segment.geometry,
              properties: {
                segment_id: segment.segment_id,
                error_message: segment.error_message,
                start_pole_count: segment.start_pole_count,
                end_pole_count: segment.end_pole_count,
                start_pole_ids: segment.start_pole_ids,
                end_pole_ids: segment.end_pole_ids
              }
            });
          }
          console.log(`Invalid aerial segment ${segment.segment_id}: ${segment.error_message}`);
        });

        // Add invalid segments to map if we have geometry data
        if (invalidFeatures.length > 0) {
          invalidAerialEndpointLayer = L.geoJSON(invalidFeatures, {
            style: {
              color: 'yellow',
              weight: 6,
              dashArray: '10,5'
            },
            onEachFeature: (feature, layer) => {
              const props = feature.properties;
              const startPoleIds = props.start_pole_ids && props.start_pole_ids.length > 0
                ? props.start_pole_ids.join(', ')
                : 'None';
              const endPoleIds = props.end_pole_ids && props.end_pole_ids.length > 0
                ? props.end_pole_ids.join(', ')
                : 'None';

              // Add hover effect
              layer.on('mouseover', function() {
                this.setStyle({ weight: 8 });
              });
              layer.on('mouseout', function() {
                this.setStyle({ weight: 6 });
              });

              layer.bindPopup(`
                🔌 Invalid Aerial Endpoint<br>
                <strong>Segment ID:</strong> ${props.segment_id}<br>
                <strong>Start Poles:</strong> ${props.start_pole_count} (IDs: ${startPoleIds})<br>
                <strong>End Poles:</strong> ${props.end_pole_count} (IDs: ${endPoleIds})<br>
                <strong>Issue:</strong> ${props.error_message}
              `);

              // Add endpoint markers
              if (feature.geometry && feature.geometry.coordinates) {
                let coords = feature.geometry.coordinates;

                // Handle MultiLineString - extract first linestring
                if (feature.geometry.type === 'MultiLineString' && coords.length > 0) {
                  coords = coords[0];
                }

                if (coords && coords.length >= 2) {
                  // Start point (yellow)
                  L.circleMarker([coords[0][1], coords[0][0]], {
                    radius: 6,
                    fillColor: '#fbbf24',
                    color: '#000000',
                    weight: 2,
                    opacity: 1,
                    fillOpacity: 1,
                    pane: 'endpointPane'
                  }).bindPopup(`<strong>Segment Start</strong><br>ID: ${props.segment_id}<br>Poles: ${props.start_pole_count}`).addTo(endpointMarkersLayer);

                  // End point (red)
                  L.circleMarker([coords[coords.length - 1][1], coords[coords.length - 1][0]], {
                    radius: 6,
                    fillColor: '#ef4444',
                    color: '#000000',
                    weight: 2,
                    opacity: 1,
                    fillOpacity: 1,
                    pane: 'endpointPane'
                  }).bindPopup(`<strong>Segment End</strong><br>ID: ${props.segment_id}<br>Poles: ${props.end_pole_count}`).addTo(endpointMarkersLayer);
                }
              }
            }
          }).addTo(map);

          // Show endpoint toggle since we've added endpoint markers
          showEndpointToggle();

          // Update QC flags in database for invalid segments
          const invalidSegmentIds = invalidSegments.map(s => s.segment_id);
          fetch('/api/qc/aerial-endpoints/update-flags', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              segment_ids: invalidSegmentIds,
              map_id: market,
              zone: zone
            })
          })
          .then(res => res.json())
          .then(data => {
            console.log("QC flags updated:", data.message);
          })
          .catch(err => console.error("Error updating QC flags:", err));
        }
      }
    })
    .catch(err => {
      console.error("Aerial Endpoint QC error:", err);
      setButtonLoading(runQCButton, false);
      qcResultDiv.textContent = "Error running Aerial Endpoint QC";
      qcResultDiv.style.color = "#ef4444";
      showClearQCButton();
      statusPanel.classList.add('visible');
      showStatus("Error running Aerial Endpoint QC", true);
    });
}

/// Underground Endpoint QC - NEW FUNCTIONALITY
let invalidUndergroundLayer;

function runUndergroundEndpointQC() {
  const market = marketSelect.value;
  const zone = zoneSelect.value;

  if (!market || !zone) {
    alert("Select a market and zone first.");
    return;
  }

  setButtonLoading(runQCButton, true);
  hideStatus();

  // Clear previous invalid underground layer
  if (invalidUndergroundLayer) {
    map.removeLayer(invalidUndergroundLayer);
    invalidUndergroundLayer = null;
  }

  showStatus("Running Underground Endpoint QC...");

  fetch(`/api/qc/underground-endpoints?map_id=${market}&zone=${zone}`)
    .then(res => res.json())
    .then(data => {
      setButtonLoading(runQCButton, false);
      statusPanel.classList.add('visible');

      if (data.invalid_segments === 0) {
        qcResultDiv.innerHTML = `✅ All ${data.total_underground_segments} underground segments have valid endpoints.`;
        qcResultDiv.style.color = "#10b981";
        showClearQCButton();
        showStatus("Underground Endpoint QC completed - All segments valid.");
      } else {
        qcResultDiv.innerHTML = `
          🔧 Underground Endpoint QC Results:<br>
          • Total Underground Segments: ${data.total_underground_segments}<br>
          • Valid: ${data.valid_segments}<br>
          • Invalid: ${data.invalid_segments}<br>
          • Pass Rate: ${data.pass_rate.toFixed(1)}%
        `;
        qcResultDiv.style.color = "#ef4444";
        showClearQCButton();
        showStatus(`Underground Endpoint QC completed - ${data.invalid_segments} segments need endpoints.`, true);

        // Get invalid segments and highlight them on map
        const invalidSegments = data.results.filter(r => !r.is_valid);
        console.log("Invalid underground segments:", invalidSegments);

        // Create GeoJSON features for invalid segments
        const invalidFeatures = [];
        invalidSegments.forEach(segment => {
          if (segment.geometry) {
            invalidFeatures.push({
              type: "Feature",
              geometry: segment.geometry,
              properties: {
                segment_id: segment.segment_id,
                error_message: segment.error_message,
                start_endpoint: segment.start_endpoint,
                end_endpoint: segment.end_endpoint
              }
            });
          }
          console.log(`Invalid underground segment ${segment.segment_id}: ${segment.error_message}`);
        });

        // Add invalid segments to map if we have geometry data
        if (invalidFeatures.length > 0) {
          invalidUndergroundLayer = L.geoJSON(invalidFeatures, {
            style: {
              color: 'purple',
              weight: 6,
              dashArray: '8,4'
            },
            onEachFeature: (feature, layer) => {
              // Add hover effect
              layer.on('mouseover', function() {
                this.setStyle({ weight: 8 });
              });
              layer.on('mouseout', function() {
                this.setStyle({ weight: 6 });
              });

              layer.bindPopup(`
                🔧 Invalid Underground Endpoint<br>
                <strong>Segment ID:</strong> ${feature.properties.segment_id}<br>
                <strong>Start Endpoint:</strong> ${feature.properties.start_endpoint}<br>
                <strong>End Endpoint:</strong> ${feature.properties.end_endpoint}<br>
                <strong>Issue:</strong> ${feature.properties.error_message}
              `);

              // Add endpoint markers
              if (feature.geometry && feature.geometry.coordinates) {
                let coords = feature.geometry.coordinates;

                // Handle MultiLineString - extract first linestring
                if (feature.geometry.type === 'MultiLineString' && coords.length > 0) {
                  coords = coords[0];
                }

                if (coords && coords.length >= 2) {
                  // Start point (yellow)
                  L.circleMarker([coords[0][1], coords[0][0]], {
                    radius: 6,
                    fillColor: '#fbbf24',
                    color: '#000000',
                    weight: 2,
                    opacity: 1,
                    fillOpacity: 1,
                    pane: 'endpointPane'
                  }).bindPopup(`<strong>Segment Start</strong><br>ID: ${feature.properties.segment_id}<br>Status: ${feature.properties.start_endpoint}`).addTo(endpointMarkersLayer);

                  // End point (red)
                  L.circleMarker([coords[coords.length - 1][1], coords[coords.length - 1][0]], {
                    radius: 6,
                    fillColor: '#ef4444',
                    color: '#000000',
                    weight: 2,
                    opacity: 1,
                    fillOpacity: 1,
                    pane: 'endpointPane'
                  }).bindPopup(`<strong>Segment End</strong><br>ID: ${feature.properties.segment_id}<br>Status: ${feature.properties.end_endpoint}`).addTo(endpointMarkersLayer);
                }
              }
            }
          }).addTo(map);

          // Show endpoint toggle since we've added endpoint markers
          showEndpointToggle();

          // Update QC flags in database for invalid segments
          const invalidSegmentIds = invalidSegments.map(s => s.segment_id);
          fetch('/api/qc/underground-endpoints/update-flags', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              segment_ids: invalidSegmentIds,
              map_id: market,
              zone: zone
            })
          })
          .then(res => res.json())
          .then(data => {
            console.log("QC flags updated:", data.message);
          })
          .catch(err => console.error("Error updating QC flags:", err));
        }
      }
    })
    .catch(err => {
      console.error("Underground Endpoint QC error:", err);
      setButtonLoading(runQCButton, false);
      qcResultDiv.textContent = "Error running Underground Endpoint QC";
      qcResultDiv.style.color = "#ef4444";
      showClearQCButton();
      statusPanel.classList.add('visible');
      showStatus("Error running Underground Endpoint QC", true);
    });
}

/// Zone Containment QC
let invalidZoneContainmentLayer;

function runZoneContainmentQC() {
  const market = marketSelect.value;
  const zone = zoneSelect.value;

  if (!market || !zone) {
    alert("Select a market and zone first.");
    return;
  }

  setButtonLoading(runQCButton, true);
  hideStatus();

  // Clear previous invalid zone containment layer
  if (invalidZoneContainmentLayer) {
    map.removeLayer(invalidZoneContainmentLayer);
    invalidZoneContainmentLayer = null;
  }

  showStatus("Running Zone Containment QC...");

  fetch(`/api/qc/zone-containment?map_id=${market}&zone=${zone}`)
    .then(res => res.json())
    .then(data => {
      setButtonLoading(runQCButton, false);
      statusPanel.classList.add('visible');

      if (data.invalid_elements === 0) {
        qcResultDiv.innerHTML = `✅ All ${data.total_elements} network elements are within their assigned zones.`;
        qcResultDiv.style.color = "#10b981";
        showClearQCButton();
        showStatus("Zone Containment QC completed - All elements valid.");
      } else {
        // Build detailed breakdown by element type
        let typeBreakdown = '';
        for (const [elementType, summary] of Object.entries(data.by_type)) {
          if (summary.total > 0) {
            const icon = summary.invalid > 0 ? '❌' : '✅';
            typeBreakdown += `  ${icon} ${elementType}: ${summary.valid}/${summary.total} valid<br>`;
          }
        }

        qcResultDiv.innerHTML = `
          📍 Zone Containment QC Results:<br>
          • Total Elements: ${data.total_elements}<br>
          • Valid: ${data.valid_elements}<br>
          • Invalid: ${data.invalid_elements}<br>
          • Pass Rate: ${data.pass_rate.toFixed(1)}%<br>
          <br>
          <strong>By Type:</strong><br>
          ${typeBreakdown}
        `;
        qcResultDiv.style.color = "#ef4444";
        showClearQCButton();
        showStatus(`Zone Containment QC completed - ${data.invalid_elements} elements need attention.`, true);

        // Get invalid elements and highlight them on map
        const invalidElements = data.results.filter(r => !r.is_valid);
        console.log("Invalid zone containment elements:", invalidElements);

        // Create GeoJSON features for invalid elements
        const invalidFeatures = [];
        invalidElements.forEach(element => {
          if (element.geometry) {
            invalidFeatures.push({
              type: "Feature",
              geometry: element.geometry,
              properties: {
                element_id: element.element_id,
                element_type: element.element_type,
                element_name: element.element_name,
                assigned_zone: element.assigned_zone,
                actual_zones: element.actual_zones,
                error_message: element.error_message
              }
            });
          }
          console.log(`Invalid ${element.element_type} ${element.element_id}: ${element.error_message}`);
        });

        // Add invalid elements to map if we have geometry data
        if (invalidFeatures.length > 0) {
          invalidZoneContainmentLayer = L.geoJSON(invalidFeatures, {
            pointToLayer: (feature, latlng) => {
              // Different marker colors by element type
              const colors = {
                'site': '#ef4444',        // red
                'pole': '#f59e0b',        // amber
                'access_point': '#8b5cf6' // purple
              };
              const color = colors[feature.properties.element_type] || '#ef4444';

              return L.circleMarker(latlng, {
                radius: 8,
                fillColor: color,
                color: '#ffffff',
                weight: 2,
                opacity: 1,
                fillOpacity: 0.9
              });
            },
            style: (feature) => {
              // For segments (LineString)
              if (feature.geometry.type === 'LineString' || feature.geometry.type === 'MultiLineString') {
                return {
                  color: '#fbbf24', // yellow
                  weight: 6,
                  dashArray: '10,5',
                  opacity: 1
                };
              }
            },
            onEachFeature: (feature, layer) => {
              const props = feature.properties;
              const assignedZone = props.assigned_zone || 'NULL/Blank';
              const actualZones = props.actual_zones && props.actual_zones.length > 0
                ? props.actual_zones.join(', ')
                : 'None';

              // Add hover effect
              layer.on('mouseover', function() {
                if (feature.geometry.type === 'LineString' || feature.geometry.type === 'MultiLineString') {
                  this.setStyle({ weight: 8 });
                } else {
                  this.setStyle({ radius: 10 });
                }
              });
              layer.on('mouseout', function() {
                if (feature.geometry.type === 'LineString' || feature.geometry.type === 'MultiLineString') {
                  this.setStyle({ weight: 6 });
                } else {
                  this.setStyle({ radius: 8 });
                }
              });

              const elementTypeName = props.element_type.replace('_', ' ').replace(/\b\w/g, l => l.toUpperCase());
              layer.bindPopup(`
                📍 Invalid Zone Containment<br>
                <strong>Type:</strong> ${elementTypeName}<br>
                <strong>ID:</strong> ${props.element_id}<br>
                ${props.element_name ? `<strong>Name:</strong> ${props.element_name}<br>` : ''}
                <strong>Assigned Zone:</strong> ${assignedZone}<br>
                <strong>Actual Zones:</strong> ${actualZones}<br>
                <strong>Issue:</strong> ${props.error_message}
              `);
            }
          }).addTo(map);

          // Update QC flags in database for invalid segments
          const invalidSegmentIds = invalidElements
            .filter(e => e.element_type === 'segment')
            .map(e => e.element_id);

          if (invalidSegmentIds.length > 0) {
            fetch('/api/qc/zone-containment/update-flags', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({
                segment_ids: invalidSegmentIds,
                map_id: market,
                zone: zone
              })
            })
            .then(res => res.json())
            .then(data => {
              console.log("QC flags updated:", data.message);
            })
            .catch(err => console.error("Error updating QC flags:", err));
          }

          // Zoom to invalid elements
          const bounds = invalidZoneContainmentLayer.getBounds();
          if (bounds.isValid()) {
            map.fitBounds(bounds, { padding: [50, 50] });
          }
        }
      }
    })
    .catch(err => {
      console.error("Zone Containment QC error:", err);
      setButtonLoading(runQCButton, false);
      qcResultDiv.textContent = "Error running Zone Containment QC";
      qcResultDiv.style.color = "#ef4444";
      showClearQCButton();
      statusPanel.classList.add('visible');
      showStatus("Error running Zone Containment QC", true);
    });
}
