const MAP_WIDTH = 2982;
const MAP_HEIGHT = 1592;

document.addEventListener('DOMContentLoaded', () => {
   loadBeacons();
   loadGateways();
   loadFingerprints();
   setupFloorSelector();

   // Setup mouse tracking
   const wrapper0 = document.getElementById('wrapper-floor-0');
   if (wrapper0) wrapper0.addEventListener('click', (e) => handleClick(e, 0));

   const wrapper1 = document.getElementById('wrapper-floor-1');
   if (wrapper1) wrapper1.addEventListener('click', (e) => handleClick(e, 1));
});

function setupFloorSelector() {
   const selector = document.getElementById('floor-select');
   selector.addEventListener('change', (e) => {
      const selectedFloor = e.target.value;
      // Hide all floors
      document.getElementById('container-floor-0').classList.add('hidden');
      document.getElementById('container-floor-1').classList.add('hidden');

      // Show selected
      const target = document.getElementById(`container-floor-${selectedFloor}`);
      if (target) target.classList.remove('hidden');
   });
}

async function loadBeacons() {
   try {
      const response = await fetch('beacon.csv'); // Adjust path if needed relative to index.html
      if (!response.ok) throw new Error('Failed to load beacon.csv');
      const text = await response.text();
      const beacons = parseCSV(text);
      renderIcons(beacons, 'beacon');
   } catch (error) {
      console.error('Error loading beacons:', error);
      showError('Failled to load beacon.csv. If you are opening this file locally, you might need to run a local server (e.g., "python3 -m http.server") due to CORS restrictions.');
   }
}

async function loadGateways() {
   try {
      const response = await fetch('gateway.csv');
      if (!response.ok) throw new Error('Failed to load gateway.csv');
      const text = await response.text();
      const gateways = parseCSV(text);
      renderIcons(gateways, 'gateway');
   } catch (error) {
      console.error('Error loading gateways:', error);
      showError('Failed to load gateway.csv. Check console for details.');
   }
}

function showError(message) {
   const errorDiv = document.createElement('div');
   errorDiv.style.backgroundColor = '#fee';
   errorDiv.style.color = 'red';
   errorDiv.style.padding = '10px';
   errorDiv.style.margin = '10px 0';
   errorDiv.style.border = '1px solid red';
   errorDiv.textContent = message;
   document.body.insertBefore(errorDiv, document.querySelector('.floor-container'));
}

function parseCSV(text) {
   const lines = text.trim().split('\n');
   const headers = lines[0].split(';').map(h => h.trim());

   // We expect headers to include: Floor, X, Y, etc.
   // CSV format based on file view: Position;Floor;RoomName;X;Y;Z;[Name];MAC

   const data = [];
   for (let i = 1; i < lines.length; i++) {
      const line = lines[i].trim();
      if (!line) continue;

      const values = line.split(';');
      const entry = {};

      headers.forEach((header, index) => {
         entry[header] = values[index] ? values[index].trim() : '';
      });

      // Parse numbers
      entry.Floor = parseInt(entry.Floor, 10);
      entry.X = parseFloat(entry.X);
      entry.Y = parseFloat(entry.Y);

      data.push(entry);
   }
   return data;
}


// Fingerprint data storage
let fingerprintData = {
   0: [], // Floor 0
   1: []  // Floor 1
};

async function loadFingerprints() {
   try {
      const [response0, response1] = await Promise.all([
         fetch('fingerprints-floor0.json'),
         fetch('fingerprints-floor1.json')
      ]);

      if (response0.ok) fingerprintData[0] = await response0.json();
      else console.error('Failed to load fingerprints-floor0.json');

      if (response1.ok) fingerprintData[1] = await response1.json();
      else console.error('Failed to load fingerprints-floor1.json');

      console.log('Fingerprints loaded:', fingerprintData);

   } catch (error) {
      console.error('Error loading fingerprints:', error);
   }
}


function renderIcons(items, type) {
   items.forEach(item => {
      // Validation: Ensure valid coordinates and floor
      if (isNaN(item.X) || isNaN(item.Y) || isNaN(item.Floor)) {
         console.warn('Invalid item skipped:', item);
         return;
      }

      const overlayId = `overlay-floor-${item.Floor}`;
      const overlay = document.getElementById(overlayId);

      if (!overlay) {
         console.warn(`Overlay not found for floor: ${item.Floor}`);
         return;
      }

      // Container: Absolute at coordinates
      const iconContainer = document.createElement('div');
      // Structure: Flex column, centered horizontally.
      // Positioning:
      // left/top put the top-left corner of div at the coordinate.
      // -translate-x-1/2 centers it horizontally.
      // -translate-y-[20px] moves it up by 20px (half of 40px icon), so the CENTER of the icon is at the coordinate.
      // If we used -translate-y-1/2, it would center the whole text+icon group, which varies in height.
      iconContainer.className = `absolute flex flex-col items-center pointer-events-auto cursor-pointer transform -translate-x-1/2 -translate-y-[20px] z-30 group`;

      // Add identifiers for gateways
      if (type === 'gateway') {
         iconContainer.classList.add('gateway-icon');
         iconContainer.setAttribute('data-gateway-name', item.GatewayName);
         // Set transition for smooth opacity change
         iconContainer.style.transition = 'opacity 0.2s ease-in-out';
      }

      const leftPercent = (item.X / MAP_WIDTH) * 100;
      const topPercent = (item.Y / MAP_HEIGHT) * 100;

      iconContainer.style.left = `${leftPercent}%`;
      iconContainer.style.top = `${topPercent}%`;

      // Icon
      const iconSpan = document.createElement('span');
      iconSpan.className = 'iconify text-[#008EED] drop-shadow-sm';
      iconSpan.style.width = '40px';
      iconSpan.style.height = '40px'; // Explicit size

      // Label (BeaconName or GatewayName)
      const labelDiv = document.createElement('div');
      // Label styling: small text, centered, semi-transparent bg for readability if overlapping
      labelDiv.className = 'text-[10px] font-bold text-gray-700 bg-white/70 px-1 rounded mt-[-4px] whitespace-nowrap shadow-sm';
      labelDiv.textContent = (type === 'beacon' ? item.BeaconName : item.GatewayName) || item.Position;

      if (type === 'beacon') {
         iconSpan.setAttribute('data-icon', 'heroicons:signal');
      } else {
         iconSpan.setAttribute('data-icon', 'lsicon:online-gateway-outline');
         iconContainer.style.zIndex = '40'; // Gateways on top
      }

      iconContainer.appendChild(iconSpan);
      iconContainer.appendChild(labelDiv);

      // Optional Tooltip for details (MAC)
      const tooltip = document.createElement('div');
      tooltip.className = `hidden group-hover:block absolute bottom-full mb-1 px-2 py-1 bg-black text-white text-xs rounded z-50 whitespace-nowrap`;
      tooltip.textContent = `MAC: ${item.MAC}`;
      iconContainer.appendChild(tooltip);

      overlay.appendChild(iconContainer);
   });
}

function handleClick(e, floor) {
   if (!fingerprintData[floor] || fingerprintData[floor].length === 0) return;

   // Get wrapper relative coordinates
   const wrapper = e.currentTarget;
   const rect = wrapper.getBoundingClientRect();

   // Mouse relative to the wrapper
   const mouseX = e.clientX - rect.left;
   const mouseY = e.clientY - rect.top;

   // Convert to map coordinates
   if (rect.width === 0 || rect.height === 0) return;

   const mapX = (mouseX / rect.width) * MAP_WIDTH;
   const mapY = (mouseY / rect.height) * MAP_HEIGHT;

   // Round to nearest 50
   let roundedX = Math.round(mapX / 50) * 50;
   let roundedY = Math.round(mapY / 50) * 50;

   // If not ending in 50, add 50
   if (String(roundedX).slice(-2) !== '50') roundedX += 50;
   if (String(roundedY).slice(-2) !== '50') roundedY += 50;

   console.log(`Click at: ${mapX.toFixed(0)}, ${mapY.toFixed(0)} -> Rounded: ${roundedX}, ${roundedY}`);

   // Find exact match
   // Note: JSON coords are numbers, strict equality should work if they are exactly 50.0 etc.
   // Use a tolerance just in case, but user said "same position".
   const match = fingerprintData[floor].find(p => p.X === roundedX && p.Y === roundedY);

   if (match) {
      console.log('Match found:', match);
      updateGatewayOpacity(floor, match.gateways);
   } else {
      console.log('No data at rounded coordinates.');
   }
}

function updateGatewayOpacity(floor, signalMap) {
   const container = document.getElementById(`overlay-floor-${floor}`);
   if (!container) return;

   const gateways = container.querySelectorAll('.gateway-icon');

   gateways.forEach(gw => {
      const name = gw.getAttribute('data-gateway-name');
      if (name && signalMap.hasOwnProperty(name)) {
         const signal = signalMap[name];

         // Logic: -60 (best) -> opacity 1, -100 (worst) -> opacity 0
         // Range is 40 (-60 to -100)
         // Normalized: (signal - (-100)) / (-60 - (-100)) = (signal + 100) / 40

         let opacity = (signal + 100) / 40;

         // Clamp
         if (opacity < 0) opacity = 0;
         if (opacity > 1) opacity = 1;

         gw.style.opacity = opacity;
      } else {
         // No signal data for this gateway at this point -> 0 opacity
         gw.style.opacity = 0;
      }
   });
}
