// ─── Savuki Drilling — Maps Module ───────────────────────────────────────
import { navigate } from '../app.js';
import { richSelect, teamItems, jobcardItems } from './rich-select.js';

const API = '/api/maps';
function token() { return localStorage.getItem('sd_token') || ''; }

async function apiFetch(path, params = {}) {
  const qs = new URLSearchParams({ ...params, token: token() });
  const res = await fetch(`${API}/${path}?${qs}`);
  const json = await res.json();
  if (!json.success) throw new Error(json.message);
  return json.data;
}

async function fetchTeams() {
  const res = await fetch(`/api/teams/list.php?token=${token()}`);
  const json = await res.json();
  return json.success ? json.data : [];
}

async function fetchJobcards() {
  const res = await fetch(`/api/jobcards/list.php?token=${token()}`);
  const json = await res.json();
  return json.success ? json.data : [];
}

// Status colours & icons
const STATUS_CONFIG = {
  DRILLING: { color: '#F07828', label: 'Drilling' },
  ACTIVE: { color: '#283C8C', label: 'Active' },
  PENDING: { color: '#f59e0b', label: 'Pending' },
  COMPLETE: { color: '#16a34a', label: 'Complete' },
  DEFAULT: { color: '#64748b', label: 'Unknown' },
};

function statusConfig(s) {
  return STATUS_CONFIG[s?.toUpperCase()] || STATUS_CONFIG.DEFAULT;
}

// ── Leaflet lazy loader ───────────────────────────────────────────────────
let _leafletReady = false;
async function ensureLeaflet() {
  if (_leafletReady || window.L) { _leafletReady = true; return; }
  await Promise.all([
    loadResource('https://unpkg.com/leaflet@1.9.4/dist/leaflet.css', 'link'),
    loadResource('https://unpkg.com/leaflet@1.9.4/dist/leaflet.js', 'script'),
  ]);
  await new Promise(resolve => {
    const poll = setInterval(() => { if (window.L) { clearInterval(poll); resolve(); } }, 50);
  });
  _leafletReady = true;
}

function loadResource(src, type) {
  return new Promise((resolve) => {
    if (document.querySelector(`[href="${src}"],[src="${src}"]`)) { resolve(); return; }
    const el = document.createElement(type === 'link' ? 'link' : 'script');
    if (type === 'link') { el.rel = 'stylesheet'; el.href = src; }
    else el.src = src;
    el.onload = resolve;
    el.onerror = resolve;
    document.head.appendChild(el);
  });
}

// Module-level rich select refs so loadMap can read their values
let _teamRs = null;
let _jcRs = null;
let _allJcData = [];

// ═════════════════════════════════════════════════════════════════════════
// INIT MAPS PAGE
// ═════════════════════════════════════════════════════════════════════════
export async function initMaps(role) {
  // Destroy any previous map instance before rebuilding the DOM
  if (_map) {
    try { _map.remove(); } catch { }
    _map = null;
    _markers = null;
    _markerMap = {};
  }
  const c = document.getElementById('view-content');
  c.innerHTML = `
  <div class="page-header" style="margin-bottom:.75rem">
    <div><h1>Jobcard Map</h1><div class="sub">All drilling sites with coordinates</div></div>
  </div>

  <!-- ── Filters bar ───────────────────────────────────────────────── -->
  <div style="background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
              padding:.75rem 1rem;margin-bottom:.75rem">
    <div class="form-row" style="margin-bottom:.5rem">
      <div class="form-group" style="margin-bottom:0">
        <label class="form-label" style="font-size:.75rem">Jump to Jobcard</label>
        <div id="map-jc-rs"></div>
      </div>
      <div class="form-group" style="margin-bottom:0">
        <label class="form-label" style="font-size:.75rem">Filter by Team</label>
        <div id="map-team-rs"></div>
      </div>
      <div class="form-group" style="margin-bottom:0">
        <label class="form-label" style="font-size:.75rem">Filter by Status</label>
        <select class="form-control" id="map-status">
          <option value="">All Statuses</option>
          <option value="DRILLING">Drilling</option>
          <option value="ACTIVE">Active</option>
          <option value="PENDING">Pending</option>
          <option value="COMPLETE">Complete</option>
        </select>
      </div>
    </div>
    <div style="display:flex;gap:.5rem;align-items:center">
      <button class="btn btn-primary btn-sm" id="btn-map-apply">Apply Filters</button>
      <button class="btn btn-ghost btn-sm"   id="btn-map-reset">Reset</button>
      <span id="map-count" style="font-size:.82rem;color:var(--text-muted);margin-left:auto"></span>
    </div>
  </div>

  <!-- ── Legend ────────────────────────────────────────────────────── -->
  <div style="display:flex;gap:.75rem;flex-wrap:wrap;margin-bottom:.75rem;font-size:.78rem">
    ${Object.entries(STATUS_CONFIG).filter(([k]) => k !== 'DEFAULT').map(([k, v]) => `
      <div style="display:flex;align-items:center;gap:.35rem">
        <div style="width:12px;height:12px;border-radius:50%;background:${v.color}"></div>
        <span>${v.label}</span>
      </div>`).join('')}
  </div>

  <!-- ── Map container ─────────────────────────────────────────────── -->
  <div id="map-container" style="width:100%;height:72vh;min-height:500px;border-radius:var(--radius);
       border:1px solid var(--border);overflow:hidden;background:#e5e3df;
       display:flex;align-items:center;justify-content:center">
    <div class="page-loader"><div class="spinner"></div><span style="margin-top:.5rem">Loading map…</span></div>
  </div>`;

  // Load teams + jobcards in parallel for rich selects
  const [teams, jcs] = await Promise.all([
    fetchTeams().catch(() => []),
    fetchJobcards().catch(() => []),
  ]);

  _allJcData = jcs; // keep for jump-to

  // Team rich select
  _teamRs = richSelect('map-team-rs', {
    placeholder: 'All teams…',
    items: [{ value: '', label: 'All Teams', sub: '' }, ...teamItems(teams)],
  });

  // Jobcard rich select — jump-to mode (selecting one flies the map there)
  _jcRs = richSelect('map-jc-rs', {
    placeholder: 'Search jobcard…',
    items: [{ value: '', label: 'All Jobcards', sub: '' }, ...jobcardItems(jcs)],
    onSelect: (val) => {
      if (val) jumpToJobcard(val);
    },
  });

  // Load Leaflet then render
  await ensureLeaflet();
  await loadMap();

  document.getElementById('btn-map-apply')?.addEventListener('click', loadMap);
  document.getElementById('btn-map-reset')?.addEventListener('click', () => {
    _teamRs?.setValue('');
    _jcRs?.setValue('');
    document.getElementById('map-status').value = '';
    loadMap();
  });
  document.getElementById('map-status')?.addEventListener('change', loadMap);
}

// ── Map instance (singleton per page visit) ───────────────────────────────
let _map = null;
let _markers = null;
let _markerMap = {}; // jc_no → marker, for jump-to

async function loadMap() {
  const container = document.getElementById('map-container');
  if (!container || !window.L) return;

  const L = window.L;

  const team_id = _teamRs?.getValue() || '';
  const status = document.getElementById('map-status')?.value || '';

  let data;
  try {
    data = await apiFetch('jobcards.php', { status, team_id });
  } catch (err) {
    container.innerHTML = `<div class="empty-state"><p>Failed to load: ${err.message}</p></div>`;
    return;
  }

  const jcs = data.jobcards || [];
  document.getElementById('map-count').textContent =
    `${jcs.length} site${jcs.length !== 1 ? 's' : ''} plotted`;

  // ── Init or reuse map ────────────────────────────────────────────────
  if (!_map) {
    container.innerHTML = '';
    container.style.cssText += ';display:block';
    // Guard: if Leaflet already initialized this container (e.g. from a stale async call),
    // destroy it first to prevent "Map container is already initialized" error
    if (container._leaflet_id) {
      try { L.map(container).remove(); } catch { }
      delete container._leaflet_id;
    }
    _map = L.map('map-container', {
      center: [-24.9, 31.1],
      zoom: 10,
      zoomControl: true,
    });
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© <a href="https://openstreetmap.org/copyright">OpenStreetMap</a>',
      maxZoom: 19,
    }).addTo(_map);
    _markers = L.layerGroup().addTo(_map);
  } else {
    _markers.clearLayers();
  }

  _markerMap = {};

  if (!jcs.length) {
    document.getElementById('map-count').textContent = 'No sites match your filters';
    return;
  }

  const bounds = [];

  jcs.forEach(jc => {
    const cfg = statusConfig(jc.jc_current_status);

    const svgIcon = L.divIcon({
      className: '',
      html: `<div style="position:relative">
        <svg xmlns="http://www.w3.org/2000/svg" width="28" height="36" viewBox="0 0 28 36">
          <path d="M14 0C6.27 0 0 6.27 0 14c0 9.33 14 22 14 22s14-12.67 14-22C28 6.27 21.73 0 14 0z"
                fill="${cfg.color}" stroke="#fff" stroke-width="1.5"/>
          <circle cx="14" cy="14" r="6" fill="white" opacity="0.9"/>
        </svg>
      </div>`,
      iconSize: [28, 36], iconAnchor: [14, 36], popupAnchor: [0, -36],
    });

    const marker = L.marker([jc.lat, jc.lng], { icon: svgIcon });
    marker.bindPopup(L.popup({ maxWidth: 300 }).setContent(buildPopup(jc, cfg)));
    marker.on('popupopen', () => {
      document.getElementById(`jc-map-view-${jc.record_id}`)
        ?.addEventListener('click', () => navigate('jobcard-view', { id: jc.record_id }));
    });

    _markers.addLayer(marker);
    _markerMap[jc.jc_no] = marker;
    bounds.push([jc.lat, jc.lng]);
  });

  if (bounds.length) _map.fitBounds(bounds, { padding: [40, 40], maxZoom: 14 });
  setTimeout(() => _map.invalidateSize(), 100);
}

// ── Jump to a specific jobcard on the map ─────────────────────────────────
function jumpToJobcard(jcNo) {
  const marker = _markerMap[jcNo];
  if (!marker || !_map) return;
  _map.setView(marker.getLatLng(), 16, { animate: true });
  marker.openPopup();
}

// ── Popup HTML ────────────────────────────────────────────────────────────
function buildPopup(jc, cfg) {
  const statusBadge = `<span style="display:inline-block;background:${cfg.color};color:#fff;
    border-radius:4px;padding:1px 7px;font-size:11px;font-weight:700">${cfg.label}</span>`;

  const row = (label, val) => val
    ? `<div style="display:flex;gap:.5rem;border-bottom:1px solid #f0f0f0;padding:3px 0;font-size:12px">
        <span style="color:#666;min-width:90px">${label}</span>
        <span style="font-weight:600">${esc(val)}</span>
       </div>` : '';

  return `
  <div style="font-family:system-ui,sans-serif;min-width:240px">
    <div style="background:#283C8C;color:#fff;margin:-13px -20px 10px;padding:10px 16px;border-radius:6px 6px 0 0">
      <div style="font-weight:800;font-size:14px">JC #${jc.jc_no}</div>
      <div style="font-size:11px;opacity:.85;margin-top:2px">${esc(jc.client_name || jc.address || '—')}</div>
    </div>
    <div style="margin-bottom:8px">${statusBadge}
      ${jc.team_name ? `<span style="font-size:11px;color:#666;margin-left:6px">· ${esc(jc.team_name)}</span>` : ''}
    </div>
    ${row('Address', jc.address)}
    ${row('Contact', jc.contact_number)}
    ${row('Water Strike', jc.water_strike ? `${jc.water_strike}m` : null)}
    ${row('Water Flow', jc.water_flow)}
    ${row('Date', (jc.action_date || jc.date_created || '').slice(0, 10))}
    ${jc.interested_in_pump === 'YES' ? `<div style="margin-top:6px;font-size:11px;background:#fef3cd;
      border:1px solid #fbbf24;border-radius:4px;padding:3px 8px">💧 Interested in pump</div>` : ''}
    <div style="margin-top:10px">
      <button id="jc-map-view-${jc.record_id}"
        style="width:100%;background:#F07828;color:#fff;border:none;border-radius:5px;
               padding:7px 12px;font-size:12px;font-weight:700;cursor:pointer">
        View Jobcard →
      </button>
    </div>
  </div>`;
}

function esc(v) { return (v || '').toString().replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;'); }