/***************************************************
 * GLOBALS
 ***************************************************/
window.deviceTrackingState = window.deviceTrackingState || {
    markers: {},
    infoWindows: {},
    telemetryMap: {},
    moveIntervals: {},
    map: null,
    realtimeTimer: null
};

function getMap() {
    return window.deviceTrackingState.map;
}

function restoreGeofenceMapReference() {
    const map = getMap();
    if (!map) return;

    Object.values(geofenceShapes).flat().forEach(shape => {
        if (!shape.getMap()) shape.setMap(map);
    });
}

var geofenceHoverInfo = null;
var geocoder = new google.maps.Geocoder();

var devicesMaster = [];

var deviceMap = window.deviceTrackingState.map;
var markers = window.deviceTrackingState.markers;
var infoWindows = window.deviceTrackingState.infoWindows;
var telemetryMap = window.deviceTrackingState.telemetryMap;
var moveIntervals = window.deviceTrackingState.moveIntervals;

var geofences = [];
var geofenceShapes = {
    hotspots: [],
    stations: [],
    routes: []
};

/***************************************************
 * INIT
 ***************************************************/
function mydevicesLoader(){
    buildLayout();
    loadDevicesList();
    loadTelemetryInitial();

    if (!window.deviceTrackingState.realtimeTimer) {
        window.deviceTrackingState.realtimeTimer =
            setInterval(loadTelemetryRealtime, 5000);
    }
}

/***************************************************
 * UI LAYOUT
 ***************************************************/
function buildLayout() {
    let html = `
        <div class="container-fluid">
            <div class="row g-1">

                <div class="col-lg-2">
                    <div class="card shadow-sm border-0 h-80">
                        <div class="card-header text-black fw-semibold">
                            Devices
                        </div>
                        <div class="card-body p-2 bg-light">
                            <div id="device_summary" class="mb-2 small fw-bold"></div>
                            <div id="device_list" style="max-height:750px; overflow-y:auto;"></div>
                        </div>
                    </div>
                </div>

                <div class="col-lg-8">
                    <div class="card shadow-sm border-0 h-80">
                        <div class="card-header text-black fw-semibold">
                            Live Map
                        </div>
                        <div id="all_devices_map" style="height:800px;"></div>
                    </div>
                </div>

                <div class="col-lg-2">
                    <div class="card shadow-sm border-0 h-80">
                        <div class="card-header text-WHITE fw-semibold">
                            Info Panel
                        </div>

                        <div class="p-2 border-bottom bg-light">
                            <div class="fw-bold mb-2">Map Filters</div>

                            <div class="form-check">
                                <input class="form-check-input" type="checkbox" id="filter_hotspots" checked>
                                <label class="form-check-label">Hotspots</label>
                            </div>

                            <div class="form-check">
                                <input class="form-check-input" type="checkbox" id="filter_stations" checked>
                                <label class="form-check-label">Stations</label>
                            </div>

                            <div class="form-check">
                                <input class="form-check-input" type="checkbox" id="filter_routes" checked>
                                <label class="form-check-label">Routes</label>
                            </div>

                            <button class="btn btn-sm btn-outline-primary mt-2 w-100"
                                    onclick="applyGeofenceFilters()">
                                Apply Filter
                            </button>

                            <button class="btn btn-sm btn-outline-primary mt-2 w-100"
                                    onclick="openGeofences()">
                                🟢 Monitoring
                            </button>
                        </div>
                    </div>
                </div>

            </div>
        </div>
    `;

    $(".tab_position").html(html);
}

function openGeofences() {
    window.location.href = "#app/multitracking";
}

function applyGeofenceFilters() {
    toggleShapeGroup(geofenceShapes.hotspots, $("#filter_hotspots").is(":checked"));
    toggleShapeGroup(geofenceShapes.stations, $("#filter_stations").is(":checked"));
    toggleShapeGroup(geofenceShapes.routes, $("#filter_routes").is(":checked"));
}

function toggleShapeGroup(group, visible) {
    const map = getMap();
    group.forEach(shape => shape.setMap(visible ? map : null));
}

/***************************************************
 * DEVICES
 ***************************************************/
function loadDevicesList() {
    controller.getAuthRequest(
        "https://demo2.bsl.co.ke/api/v1/devices/all",
        true,
        data => {
            devicesMaster = data || [];
            $("#device_list").empty();
            devicesMaster.forEach(createDeviceCard);
            updateDeviceSummary();
        }
    );
}

function createDeviceCard(d) {
    $("#device_list").append(`
        <div class="device-card" onclick="focusDevice('${d.serialNo}')">
            <div class="device-left">
                <div class="device-pin"><i class="fa-solid fa-location-dot"></i></div>
                <div class="device-text">
                    <div class="device-title">${d.serialNo}</div>
                    <div class="device-id">ID: ${d.serialNo}</div>
                </div>
            </div>
            <div class="device-badge ${d.isOnline ? 'online' : 'offline'}">
                ${d.isOnline ? 'ONLINE' : 'OFFLINE'}
            </div>
        </div>
    `);
}

/***************************************************
 * TELEMETRY
 ***************************************************/
function loadTelemetryInitial() {
    controller.getAuthRequest(serverURL + "telemetry/latest", true, data => {

        if (!data?.length) return;

        data.forEach(d => telemetryMap[d.deviceSn] = d);

        const first = data.find(d => d.latitude && d.longitude);
        if (!first) return;

        deviceMap = new google.maps.Map(
            document.getElementById("all_devices_map"),
            {
                zoom: 16,
                center: { lat: first.latitude, lng: first.longitude },
                gestureHandling: "greedy",
                zoomControl: true,
                mapTypeControl: true
            }
        );

        window.deviceTrackingState.map = deviceMap;
        geofenceHoverInfo = new google.maps.InfoWindow({ disableAutoPan: true });

        data.forEach(addOrUpdateMarker);
        loadGeofences();
    });
}

function loadTelemetryRealtime() {
    const state = window.deviceTrackingState;

    controller.getAuthRequest(serverURL + "telemetry/latest", true, data => {
        if (!data) return;

        data.forEach(d => {
            if (!d || !d.deviceSn) return;
            state.telemetryMap[d.deviceSn] = d;
            addOrUpdateMarker(d);
        });
    });
}

/***************************************************
 * MARKERS
 ***************************************************/
function addOrUpdateMarker(t) {
    if (!t.latitude || !t.longitude) return;

    const map = getMap();
    if (!map) return;

    if (!markers[t.deviceSn]) {
        markers[t.deviceSn] = new google.maps.Marker({
            map: map,
            position: { lat: t.latitude, lng: t.longitude }
        });

        infoWindows[t.deviceSn] = new google.maps.InfoWindow({
            content: buildInfoContent(t)
        });

        markers[t.deviceSn].addListener("click", () => {
            closeAllInfoWindows();
            infoWindows[t.deviceSn].open(map, markers[t.deviceSn]);
        });

    } else {
        smoothMoveMarker(t);
        infoWindows[t.deviceSn].setContent(buildInfoContent(t));
    }
}

/***************************************************
 * GEOFENCES
 ***************************************************/
function loadGeofences() {
    controller.getAuthRequest(
        "https://demo2.bsl.co.ke/api/v1/geofences?size=1000",
        true,
        res => {
            geofences = res?.content || [];
            drawGeofences();
        }
    );
}


function drawGeofences() {

    if (!deviceMap) {
        setTimeout(drawGeofences, 100);
        return;
    }

    // clear old
    Object.values(geofenceShapes).flat().forEach(s => s.setMap(null));
    geofenceShapes = { hotspots: [], stations: [], routes: [] };

    console.log("Geofences received:", geofences.length);

    geofences.forEach(f => {

        if (!f.isActive) return;

        const color = f.colorHex || "#3b82f6";

        /************** CIRCLE **************/
        if (f.fenceType === "CIRCLE" && f.centerLat && f.centerLng) {

            const circle = new google.maps.Circle({
                map: deviceMap,
                center: { lat: f.centerLat, lng: f.centerLng },
                radius: Number(f.radiusMeters) || 100,
                fillColor: color,
                fillOpacity: 0.25,
                strokeColor: color,
                strokeWeight: 2
            });

            circle.set("name", f.name);

            // classify visually
            if (f.station) geofenceShapes.stations.push(circle);
            else geofenceShapes.hotspots.push(circle);

            return;
        }

        /************** POLYGON **************/
        if (f.fenceType === "POLYGON" && f.coordinatesJson) {

            let coords;
            try {
                coords = JSON.parse(f.coordinatesJson);
            } catch (e) {
                console.warn("Invalid polygon JSON:", f.name);
                return;
            }

            const polygon = new google.maps.Polygon({
                map: deviceMap,
                paths: coords,
                fillColor: color,
                fillOpacity: 0.25,
                strokeColor: color,
                strokeWeight: 2
            });

            polygon.set("name", f.name);

            if (f.station) geofenceShapes.stations.push(polygon);
            else if (f.route) geofenceShapes.routes.push(polygon);
            else geofenceShapes.hotspots.push(polygon);

            return;
        }

        /************** ROUTE LINE **************/
        if (f.fenceType === "LINE" && f.coordinatesJson) {

            let coords;
            try {
                coords = JSON.parse(f.coordinatesJson);
            } catch (e) {
                console.warn("Invalid route JSON:", f.name);
                return;
            }

            const line = new google.maps.Polyline({
                map: deviceMap,
                path: coords,
                strokeColor: color,
                strokeWeight: 4
            });

            line.set("name", f.name);
            geofenceShapes.routes.push(line);
        }

    });

    console.log("Hotspots:", geofenceShapes.hotspots.length);
    console.log("Stations:", geofenceShapes.stations.length);
    console.log("Routes:", geofenceShapes.routes.length);

    applyGeofenceFilters();
}


/***************************************************
 * HELPERS
 ***************************************************/
function smoothMoveMarker(d) {
    const m = markers[d.deviceSn];
    if (!m) return;

    const s = m.getPosition();
    const e = new google.maps.LatLng(d.latitude, d.longitude);
    let i = 0;

    clearInterval(moveIntervals[d.deviceSn]);
    moveIntervals[d.deviceSn] = setInterval(() => {
        i++;
        m.setPosition({
            lat: s.lat() + (e.lat() - s.lat()) * i / 20,
            lng: s.lng() + (e.lng() - s.lng()) * i / 20
        });
        if (i >= 20) clearInterval(moveIntervals[d.deviceSn]);
    }, 100);
}

function closeAllInfoWindows() {
    Object.values(infoWindows).forEach(iw => iw.close());
}

function focusDevice(sn) {
    const m = markers[sn];
    const map = getMap();
    if (!m || !map) return;

    map.panTo(m.getPosition());
    map.setZoom(18);
    closeAllInfoWindows();
    infoWindows[sn]?.open(map, m);
}

function buildInfoContent(d) {

    const safe = (v, suffix = "") =>
        (v !== null && v !== undefined && v !== "")
            ? `${v}${suffix}`
            : "N/A";

    /* ✅ REAL ONLINE LOGIC */
    const online = d.speedKmh > 0 || (d.satellites && d.satellites > 0);

    return `
    <div class="tracker-card">

        <!-- HEADER -->
        <div class="tracker-header">
            <div>
                <strong>${safe(d.deviceName)}</strong><br>
                <small>SN: ${safe(d.deviceSn)}</small>
            </div>
            <span class="dot ${online ? 'online' : 'offline'}"></span>
        </div>

        <!-- STATUS -->
        <div class="tracker-row">
            <strong>Timestamp:</strong>
            <span>${safe(d.timestamp)}</span>
        </div>

        <!-- MOVEMENT -->
        <div class="tracker-row">
            🚗 <strong>Speed:</strong>
            <span>${safe(d.speedKmh, ' km/h')}</span>
        </div>

        <div class="tracker-row">
            🧭 <strong>Direction:</strong>
            <span>${safe(d.direction, '°')}</span>
        </div>

        <!-- LOCATION -->
        <div class="tracker-row">
            🌍 <strong>Latitude:</strong>
            <span>${safe(d.latitude)}</span>
        </div>

        <div class="tracker-row">
            🌍 <strong>Longitude:</strong>
            <span>${safe(d.longitude)}</span>
        </div>

        <div class="tracker-row">
            📍 <strong>Address:</strong>
            <span>${safe(d.address)}</span>
        </div>

        <!-- VEHICLE / DEVICE -->
        <div class="tracker-row">
            🛣 <strong>Mileage:</strong>
            <span>${safe(d.mileageKm, ' km')}</span>
        </div>

        <div class="tracker-row">
            🔋 <strong>Battery:</strong>
            <span>${safe(d.battery, '%')}</span>
        </div>

        <div class="tracker-row">
            🛰 <strong>Satellites:</strong>
            <span>${safe(d.satellites)}</span>
        </div>

        <div class="tracker-row">
            📡 <strong>GPS Status:</strong>
            <span>${safe(d.gpsStatus)}</span>
        </div>

        <div class="tracker-row">
            📶 <strong>GSM Signal:</strong>
            <span>${safe(d.gsmSignal)}</span>
        </div>

        <div class="tracker-row">
            🌡 <strong>Temperature:</strong>
            <span>${safe(d.temperatureC, ' °C')}</span>
        </div>

        <!-- SYSTEM -->
        <div class="tracker-row">
            ⚙️ <strong>Active:</strong>
            <span>${d.active ? 'Yes' : 'No'}</span>
        </div>

        <div class="tracker-row">
            🚨 <strong>Alarm:</strong>
            <span>${safe(d.alarmState)}</span>
        </div>

        <!-- ACTIONS -->
        <div class="tracker-actions">
            <button onclick="focusDevice('${d.deviceSn}')">
                Focus
            </button>
        </div>

    </div>`;
}

function updateDeviceSummary() {
    const total = devicesMaster.length;
    const online = devicesMaster.filter(d => d.isOnline).length;
    $("#device_summary").html(`Total: ${total} | Online: ${online} | Offline: ${total - online}`);
}
