#!/usr/bin/env python3
from PyQt6.QtWebEngineWidgets import QWebEngineView
from PyQt6.QtCore import QTimer, pyqtSignal, QObject, pyqtSlot
from PyQt6.QtWebChannel import QWebChannel

class DroneMap:
    """無人機地圖類別 - 負責管理 Leaflet 地圖顯示"""
    
    def __init__(self):
        """初始化地圖"""
        self.map_view = QWebEngineView()
        self.map_loaded = False
        self.pending_map_updates = {}
        
        # 創建橋接對象
        self.bridge = MapBridge()
        
        # 設置 QWebChannel
        self.channel = QWebChannel()
        self.channel.registerObject('bridge', self.bridge)
        self.map_view.page().setWebChannel(self.channel)
        
        # 設置地圖 HTML
        inline_html = '''
            <!DOCTYPE html>
            <html>
            <head>
            <meta charset="utf-8" />
            <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
            <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
            <script src="https://unpkg.com/leaflet-rotatedmarker/leaflet.rotatedMarker.js"></script>
            <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
            <style>
                html, body, #map { height: 100%; margin: 0; }
                #map {
                    user-select: none;
                    -webkit-user-select: none;
                    -moz-user-select: none;
                    -ms-user-select: none;
                }
                .map-controls {
                    position: absolute;
                    top: 10px;
                    right: 10px;
                    z-index: 1000;
                    background-color: rgba(255, 255, 255, 0.95);
                    padding: 10px;
                    border-radius: 6px;
                    box-shadow: 0 2px 8px rgba(0,0,0,0.3);
                    display: flex;
                    flex-direction: column;
                    gap: 5px;
                    min-width: 150px;
                }
                .map-controls-bottom {
                    position: absolute;
                    bottom: 10px;
                    left: 10px;
                    z-index: 1000;
                }
                .control-button {
                    padding: 8px 12px;
                    background-color: #EF5350;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 13px;
                    font-weight: bold;
                    box-shadow: 0 2px 5px rgba(0,0,0,0.2);
                }
                .control-button:hover {
                    background-color: #E53935;
                }
                .mission-info-panel {
                    position: absolute;
                    bottom: 10px;
                    right: 10px;
                    z-index: 1000;
                    background-color: rgba(255, 255, 255, 0.95);
                    padding: 12px;
                    border-radius: 6px;
                    box-shadow: 0 2px 8px rgba(0,0,0,0.3);
                    min-width: 200px;
                }
                .mission-info-row {
                    margin-bottom: 8px;
                    font-size: 12px;
                    color: #333;
                }
                .mission-info-label {
                    font-weight: bold;
                    color: #555;
                }
                .mission-info-value {
                    color: #2196F3;
                    font-family: monospace;
                }
                .mission-start-button {
                    width: 100%;
                    padding: 10px;
                    background-color: #7FBA82;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 13px;
                    font-weight: bold;
                    margin-top: 8px;
                }
                .mission-start-button:hover {
                    background-color: #6FA872;
                }
                .mission-start-button:disabled {
                    background-color: #ccc;
                    cursor: not-allowed;
                }
                .selection-buttons {
                    display: flex;
                    flex-direction: column;
                    gap: 5px;
                    margin-bottom: 10px;
                    padding-bottom: 10px;
                    border-bottom: 1px solid #ddd;
                }                .selection-button-blue {
                    width: 100%;
                    padding: 8px;
                    background-color: #64B5F6;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 13px;
                    font-weight: bold;
                    transition: background-color 0.2s;
                }
                .selection-button-blue:hover {
                    background-color: #42A5F5;
                }
                .selection-button-blue.active {
                    background-color: #1976D2;
                }                .selection-button-blue {
                    width: 100%;
                    padding: 8px;
                    background-color: #64B5F6;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 13px;
                    font-weight: bold;
                    transition: background-color 0.2s;
                }
                .selection-button-blue:hover {
                    background-color: #42A5F5;
                }
                .selection-button-blue.active {
                    background-color: #1976D2;
                }
                .selection-button {
                    width: 100%;
                    padding: 8px;
                    background-color: #F06A61;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 13px;
                    font-weight: bold;
                    transition: background-color 0.2s;
                }
                .selection-button:hover {
                    background-color: #E53935;
                }
                .selection-button.active {
                    background-color: #D32F2F;
                }
            </style>
            </head>
            <body>
            <div id="map"></div>
            <div class="map-controls">
                <button class="selection-button" onclick="clearAllTrajectories()">清除軌跡</button>
                <button class="selection-button" id="select-rect-btn" onclick="toggleRectSelection()">框選方形區域</button>
                <button class="selection-button" id="select-polygon-btn" onclick="togglePolygonSelection()">多點選擇區域</button>
            </div>
            <div class="mission-info-panel">
                <div class="selection-buttons">
                    <button class="selection-button-blue" onclick="toggleSelectAllDrones()">全選無人機</button>
                    <button class="selection-button-blue" id="select-drones-btn" onclick="toggleDroneSelection()">框選無人機</button>
                </div>
                <div class="mission-info-row">
                    <span class="mission-info-label">中心點: </span>
                    <span class="mission-info-value" id="center-position">未設定</span>
                </div>
                <div class="mission-info-row">
                    <span class="mission-info-label">目標點: </span>
                    <span class="mission-info-value" id="target-position">未設定</span>
                </div>
                <button class="mission-start-button" id="start-mission-btn" onclick="startMission()" disabled>開始任務</button>
                <button class="mission-start-button" id="pause-mission-btn" onclick="pauseMission()">暫停任務</button>
            </div>

            <script>
                var bridge;
                new QWebChannel(qt.webChannelTransport, function(channel) {
                    bridge = channel.objects.bridge;
                });

                var map = L.map('map').setView([0, 0], 19); 
                
                // 創建不同的地圖圖層
                var streetLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                    maxZoom: 19,
                    attribution: '© OpenStreetMap contributors'
                });
                
                var satelliteLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
                    maxZoom: 19,
                    attribution: 'Tiles © Esri'
                });
                
                // 默認使用衛星圖
                var currentLayer = satelliteLayer;
                currentLayer.addTo(map);
                var isSatellite = true;


                // 地圖點擊事件
                map.on('click', function(e) {
                    if (selectionMode === 'polygon') {
                        // 多點選擇模式：添加點
                        addPolygonPoint(e.latlng.lat, e.latlng.lng);
                    } else if (!selectionMode) {
                        // 正常模式：發送GPS信號
                        if (bridge) {
                            bridge.emitGpsSignal(e.latlng.lat, e.latlng.lng);
                            console.log('點擊位置:', e.latlng.lat, e.latlng.lng);
                        }
                    }
                });
                
                // 地圖拖曳事件（用於矩形選擇）
                map.on('mousedown', function(e) {
                    mapDragStarted = false;
                    clickStartPos = {x: e.originalEvent.clientX, y: e.originalEvent.clientY};
                    
                    if (selectionMode === 'rect' || selectionMode === 'drones') {
                        isDrawing = true;
                        drawStartPoint = e.latlng;
                        L.DomEvent.preventDefault(e.originalEvent);
                        L.DomEvent.stopPropagation(e);
                    }
                });
                
                map.on('mousemove', function(e) {
                    // 檢測地圖拖移
                    if (clickStartPos && !selectionMode) {
                        var dx = Math.abs(e.originalEvent.clientX - clickStartPos.x);
                        var dy = Math.abs(e.originalEvent.clientY - clickStartPos.y);
                        if (dx > 5 || dy > 5) {
                            mapDragStarted = true;
                        }
                    }
                    
                    if (isDrawing && (selectionMode === 'rect' || selectionMode === 'drones') && drawStartPoint) {
                        // 更新臨時矩形
                        if (tempRectangle) {
                            selectionLayer.removeLayer(tempRectangle);
                        }
                        var bounds = L.latLngBounds(drawStartPoint, e.latlng);
                        tempRectangle = L.rectangle(bounds, {
                            color: selectionMode === 'drones' ? '#9C27B0' : '#FF6B6B',
                            weight: 2,
                            fillOpacity: selectionMode === 'drones' ? 0 : 0.2,
                            dashArray: selectionMode === 'drones' ? '5, 5' : null
                        }).addTo(selectionLayer);
                    }
                });
                
                map.on('mouseup', function(e) {
                    if (isDrawing && (selectionMode === 'rect' || selectionMode === 'drones') && drawStartPoint) {
                        isDrawing = false;
                        var bounds = L.latLngBounds(drawStartPoint, e.latlng);
                        finishRectSelection(bounds);
                        drawStartPoint = null;
                    }
                    
                    // 重置拖移狀態
                    clickStartPos = null;
                    setTimeout(function() {
                        mapDragStarted = false;
                    }, 100);
                });

                function createArrowIcon(color) {
                return L.divIcon({
                    className: 'drone-arrow',
                    html: `
                    <div style="
                        width: 30px; height: 30px;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                    ">
                        <svg width="30" height="30" viewBox="0 0 30 30">
                            <polygon points="15,0 30,30  15,25  0,30" fill="${color || '#FF0000'}" />
                        </svg>
                    </div>
                    `,
                    iconSize: [30, 30],
                    iconAnchor: [15, 15]   // ★ 箭頭往左上移，使 ID 顯示在右下
                });
                }

                function getColorBySocketId(id) {
                    if (id.startsWith("s0_")) return "#00BFFF";  // 天藍色
                    if (id.startsWith("s1_")) return "#FFD700";  // 金色
                    if (id.startsWith("s2_")) return "#FF6969";  // 淺紅色
                    if (id.startsWith("s3_")) return "#FF69B4";  // 熱粉紅
                    if (id.startsWith("s4_")) return "#00FA9A";  // 中春綠
                    if (id.startsWith("s5_")) return "#9370DB";  // 中紫色 (串口)
                    if (id.startsWith("s6_")) return "#FFA500";  // 橙色
                    if (id.startsWith("s7_")) return "#20B2AA";  // 淺海綠
                    if (id.startsWith("s8_")) return "#7CFC00";  // 草綠色
                    if (id.startsWith("s9_")) return "#FF8C00";  // 深橙色
                    return "#AAAAAA";  // 灰色 (預設)
                }

                function createIdIcon(id) {
                const sysid = id.split('_')[1];
                return L.divIcon({
                    className: 'drone-id',
                    html: `<div style="
                    background-color: transparent;
                    color: black;
                    width: 16px;
                    height: 16px;
                    border-radius: 50%;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    font-weight: bold;
                    font-size: 12px;
                    text-shadow: 1px 1px 2px rgba(255,255,255,0.8), -1px -1px 2px rgba(255,255,255,0.8);
                    ">${sysid}</div>`,
                    iconSize: [16, 16],
                    iconAnchor: [8, 6]   // ★ icon 中心 = 經緯度點
                });
                }

                var markers = {};
                var idLabels = {};
                var trajectories = {};
                var trajectoryLines = {};
                var focusedId = null;
                var initialized = false;
                var trajectoryGroup = L.layerGroup().addTo(map);

                // ================================================================================
                // 【新增】任務規劃視覺化變數
                // ================================================================================
                var missionPlanGroup = L.layerGroup().addTo(map);  // 任務規劃圖層
                var centerMarker = null;     // 中心點標記
                var targetMarker = null;     // 目標點標記
                var missionLine = null;      // 中心點到目標點的虛線
                var centerPosition = null;   // 中心點經緯度
                var targetPosition = null;   // 目標點經緯度
                
                // 選擇工具變量
                var selectionMode = null;  // 'drones', 'rect', 'polygon', null
                var selectionLayer = L.layerGroup().addTo(map);
                var polygonPoints = [];  // 多點選擇的點
                var polygonMarkers = [];  // 多點選擇的標記
                var tempRectangle = null;  // 臨時矩形
                var isDrawing = false;  // 是否正在繪製
                var drawStartPoint = null;  // 繪製起點
                var mapDragStarted = false;  // 地圖是否正在拖移
                var clickStartPos = null;  // 記錄點擊開始位置
                // ================================================================================
                
                // 更新任務信息面板
                function updateMissionInfo() {
                    const centerElem = document.getElementById('center-position');
                    const targetElem = document.getElementById('target-position');
                    const startBtn = document.getElementById('start-mission-btn');
                    
                    if (centerPosition) {
                        centerElem.textContent = `${centerPosition.lat.toFixed(6)}°, ${centerPosition.lng.toFixed(6)}°`;
                    } else {
                        centerElem.textContent = '未設定';
                    }
                    
                    if (targetPosition) {
                        targetElem.textContent = `${targetPosition.lat.toFixed(6)}°, ${targetPosition.lng.toFixed(6)}°`;
                    } else {
                        targetElem.textContent = '未設定';
                    }
                    
                    // 只有當中心點和目標點都設定時才啟用按鈕
                    if (centerPosition && targetPosition) {
                        startBtn.disabled = false;
                    } else {
                        startBtn.disabled = true;
                    }
                }
                
                // ================================================================================
                // 選擇工具函數
                // ================================================================================
                function toggleSelectAllDrones() {
                    // 切換全選/取消全選無人機
                    if (bridge) {
                        bridge.toggleSelectAllDrones();
                        console.log('切換全選無人機');
                    }
                }
                
                function toggleDroneSelection() {
                    clearSelectionMode();
                    if (selectionMode === 'drones') {
                        selectionMode = null;
                        document.getElementById('select-drones-btn').classList.remove('active');
                        map.dragging.enable();
                    } else {
                        selectionMode = 'drones';
                        document.getElementById('select-drones-btn').classList.add('active');
                        map.dragging.disable();
                    }
                }
                
                function toggleRectSelection() {
                    clearSelectionMode();
                    if (selectionMode === 'rect') {
                        selectionMode = null;
                        document.getElementById('select-rect-btn').classList.remove('active');
                        map.dragging.enable();
                    } else {
                        selectionMode = 'rect';
                        document.getElementById('select-rect-btn').classList.add('active');
                        map.dragging.disable();
                    }
                }
                
                function togglePolygonSelection() {
                    if (selectionMode === 'polygon') {
                        // 第二次點擊：完成選擇
                        if (polygonPoints.length >= 3) {
                            finishPolygonSelection();
                        } else {
                            alert('至少需要3個點來形成區域');
                            // 清除並重置
                            clearSelectionMode();
                            clearPolygonPoints();
                            selectionMode = null;
                            document.getElementById('select-polygon-btn').classList.remove('active');
                        }
                    } else {
                        // 第一次點擊：清除上次的點位並啟動模式
                        clearSelectionMode();
                        clearPolygonPoints();
                        selectionMode = 'polygon';
                        document.getElementById('select-polygon-btn').classList.add('active');
                        map.dragging.disable();
                    }
                }
                
                function clearSelectionMode() {
                    // 清除所有按鈕的激活狀態
                    document.getElementById('select-drones-btn').classList.remove('active');
                    document.getElementById('select-rect-btn').classList.remove('active');
                    document.getElementById('select-polygon-btn').classList.remove('active');
                    
                    // 清除選擇圖層
                    selectionLayer.clearLayers();
                    tempRectangle = null;
                    
                    // 重新啟用地圖拖曳
                    map.dragging.enable();
                }
                
                function addPolygonPoint(lat, lng) {
                    polygonPoints.push([lat, lng]);
                    
                    // 添加邊界點標記
                    var marker = L.circleMarker([lat, lng], {
                        radius: 5,
                        color: '#FF6B6B',
                        fillColor: '#FF6B6B',
                        fillOpacity: 0.8
                    }).addTo(selectionLayer);
                    polygonMarkers.push(marker);
                    
                    // 如果有多個點，繪製連線
                    if (polygonPoints.length > 1) {
                        L.polyline(polygonPoints, {
                            color: '#FF6B6B',
                            weight: 2,
                            dashArray: '5, 5'
                        }).addTo(selectionLayer);
                    }
                    
                    console.log('添加邊界點:', lat, lng, '總共:', polygonPoints.length);
                }
                
                function clearPolygonPoints() {
                    polygonPoints = [];
                    polygonMarkers.forEach(m => selectionLayer.removeLayer(m));
                    polygonMarkers = [];
                    selectionLayer.clearLayers();
                }
                
                function finishPolygonSelection() {
                    if (polygonPoints.length < 3) {
                        alert('至少需要3個點來形成區域');
                        return;
                    }
                    
                    // 繪製最終多邊形
                    var polygon = L.polygon(polygonPoints, {
                        color: '#FF6B6B',
                        fillColor: '#FF6B6B',
                        fillOpacity: 0.2,
                        weight: 2
                    }).addTo(selectionLayer);
                    
                    // 發送多邊形數據到Python
                    if (bridge) {
                        var pointsStr = JSON.stringify(polygonPoints);
                        bridge.polygonSelected(pointsStr);
                        console.log('多邊形選擇完成:', polygonPoints);
                    }
                    
                    // 重置狀態
                    selectionMode = null;
                    document.getElementById('select-polygon-btn').classList.remove('active');
                    map.dragging.enable();
                }
                
                function finishRectSelection(bounds) {
                    var selectedDrones = [];
                    
                    // 清除臨時矩形
                    if (tempRectangle) {
                        selectionLayer.removeLayer(tempRectangle);
                        tempRectangle = null;
                    }
                    
                    if (selectionMode === 'drones') {
                        // 框選無人機模式：先清除全選
                        if (bridge) {
                            bridge.clearAllDroneSelection();
                        }
                        
                        Object.keys(markers).forEach(droneId => {
                            var pos = markers[droneId].getLatLng();
                            if (bounds.contains(pos)) {
                                selectedDrones.push(droneId);
                                // 觸發無人機點擊信號
                                if (bridge) {
                                    bridge.emitDroneClicked(droneId);
                                }
                            }
                        });
                        console.log('框選無人機:', selectedDrones);
                        // 不保留選擇框，直接完成
                        
                    } else if (selectionMode === 'rect') {
                        // 框選區域模式
                        var rectPoints = [
                            [bounds.getNorth(), bounds.getWest()],
                            [bounds.getNorth(), bounds.getEast()],
                            [bounds.getSouth(), bounds.getEast()],
                            [bounds.getSouth(), bounds.getWest()]
                        ];
                        
                        // 繪製最終矩形
                        L.rectangle(bounds, {
                            color: '#FF6B6B',
                            fillColor: '#FF6B6B',
                            fillOpacity: 0.2,
                            weight: 2
                        }).addTo(selectionLayer);
                        
                        // 添加四個角的標記
                        rectPoints.forEach(point => {
                            L.circleMarker(point, {
                                radius: 5,
                                color: '#FF6B6B',
                                fillColor: '#FF6B6B',
                                fillOpacity: 0.8
                            }).addTo(selectionLayer);
                        });
                        
                        // 發送矩形數據到Python
                        if (bridge) {
                            var pointsStr = JSON.stringify(rectPoints);
                            bridge.rectangleSelected(pointsStr);
                            console.log('矩形選擇完成:', rectPoints);
                        }
                    }
                    
                    // 重置狀態
                    selectionMode = null;
                    document.getElementById('select-drones-btn').classList.remove('active');
                    document.getElementById('select-rect-btn').classList.remove('active');
                    map.dragging.enable();
                }
                // ================================================================================
                
                // 開始任務
                function startMission() {
                    if (!centerPosition || !targetPosition) {
                        alert('請先設定中心點和目標點');
                        return;
                    }
                    
                    if (bridge) {
                        bridge.startMissionSignal(
                            centerPosition.lat, centerPosition.lng,
                            targetPosition.lat, targetPosition.lng
                        );
                        console.log('開始任務:', centerPosition, targetPosition);
                    }
                }
                
                // 暫停任務
                function pauseMission() {
                    if (bridge) {
                        bridge.pauseMissionSignal();
                        console.log('暫停任務');
                    }
                }
                // ================================================================================

                function initTrajectory(id) {
                    if (!trajectories[id]) {
                        trajectories[id] = [];
                        const color = getColorBySocketId(id);
                        trajectoryLines[id] = L.polyline([], {
                            color: color,
                            weight: 3,
                            opacity: 0.7,
                            smoothFactor: 1
                        }).addTo(trajectoryGroup);
                    }
                }

                function addTrajectoryPoint(id, lat, lon) {
                    initTrajectory(id);
                    const point = [lat, lon];
                    trajectories[id].push(point);
                    
                    if (trajectories[id].length > 1000) {
                        trajectories[id].shift();
                    }
                    
                    trajectoryLines[id].setLatLngs([...trajectories[id]]);
                }

                function focusOn(id) {
                    if (!markers[id]) return;
                    focusedId = id;
                    var latlng = markers[id].getLatLng();
                    map.flyTo(latlng, map.getZoom());
                }

                setInterval(() => {
                    if (focusedId && markers[focusedId]) {
                        var latlng = markers[focusedId].getLatLng();
                        map.panTo(latlng);
                    }
                }, 1000);

                function updateDrone(lat, lon, id, heading) {
                    if (markers[id]) {
                        const lastPos = markers[id].getLatLng();
                        const distance = lastPos.distanceTo([lat, lon]);
                        if (distance > 1) {
                            addTrajectoryPoint(id, lat, lon);
                        }
                        
                        markers[id]
                            .setLatLng([lat, lon])
                            .setRotationAngle(heading);
                        idLabels[id].setLatLng([lat, lon]);
                    } else {
                        initTrajectory(id);
                        addTrajectoryPoint(id, lat, lon);
                        
                        const color = getColorBySocketId(id);
                        markers[id] = L.marker([lat, lon], {
                            icon: createArrowIcon(color),
                            rotationAngle: heading,
                            rotationOrigin: 'center'
                        })
                        .on('click', function () {
                            if (mapDragStarted) {
                                return;  // 如果是拖移地圖，不處理點擊
                            }
                            if (bridge) {
                                bridge.emitDroneClicked(id);
                            }
                            focusOn(id);
                        })
                        .addTo(map);

                        idLabels[id] = L.marker([lat, lon], {
                            icon: createIdIcon(id),
                            zIndexOffset: 1000
                        })
                        .on('click', function() {
                            if (mapDragStarted) {
                                return;  // 如果是拖移地圖，不處理點擊
                            }
                            if (bridge) {
                                bridge.emitDroneClicked(id);
                            }
                            focusOn(id);
                        })
                        .addTo(map);

                        if (!initialized || id < focusedId) {
                            focusedId = id;
                            map.setView([lat, lon], 19);  // 第一台無人機：重置並放大到最大
                            initialized = true;
                        }
                    }
                }

                function clearAllTrajectories() {
                    trajectories = {};
                    Object.values(trajectoryLines).forEach(line => {
                        trajectoryGroup.removeLayer(line);
                    });
                    trajectoryLines = {};
                    console.log('所有軌跡已清除');
                }

                // ================================================================================
                // 【新增】任務規劃視覺化函式
                // ================================================================================
                function drawMissionPlan(centerLat, centerLon, targetLat, targetLon) {
                    // 清除舊的任務規劃標記
                    clearMissionPlan();
                    
                    // 保存中心點和目標點位置
                    centerPosition = {lat: centerLat, lng: centerLon};
                    targetPosition = {lat: targetLat, lng: targetLon};
                    updateMissionInfo();
                    
                    // 繪製中心點標記 "C"（縮小到 20px）
                    var centerIcon = L.divIcon({
                        className: 'mission-center',
                        html: `<div style="
                            background-color: #FF4444;
                            color: white;
                            width: 20px;
                            height: 20px;
                            border-radius: 50%;
                            display: flex;
                            align-items: center;
                            justify-content: center;
                            font-weight: bold;
                            font-size: 12px;
                            border: 2px solid white;
                            box-shadow: 0 2px 5px rgba(0,0,0,0.3);
                            ">C</div>`,
                        iconSize: [20, 20],
                        iconAnchor: [10, 10]
                    });
                    
                    centerMarker = L.marker([centerLat, centerLon], {
                        icon: centerIcon,
                        zIndexOffset: 2000
                    }).addTo(missionPlanGroup);
                    
                    // 繪製目標點標記 "★"（星星符號）
                    var targetIcon = L.divIcon({
                        className: 'mission-target',
                        html: `<div style="
                            background-color: #FFD700;
                            color: #FF4444;
                            width: 20px;
                            height: 20px;
                            border-radius: 50%;
                            display: flex;
                            align-items: center;
                            justify-content: center;
                            font-weight: bold;
                            font-size: 14px;
                            border: 2px solid white;
                            box-shadow: 0 2px 5px rgba(0,0,0,0.3);
                            ">★</div>`,
                        iconSize: [20, 20],
                        iconAnchor: [10, 10]
                    });
                    
                    targetMarker = L.marker([targetLat, targetLon], {
                        icon: targetIcon,
                        zIndexOffset: 2000
                    }).addTo(missionPlanGroup);
                    
                    console.log('任務規劃已繪製: C(' + centerLat + ', ' + centerLon + ') -> T(' + targetLat + ', ' + targetLon + ')');
                }
                
                function clearMissionPlan() {
                    // 清除中心點標記
                    if (centerMarker) {
                        missionPlanGroup.removeLayer(centerMarker);
                        centerMarker = null;
                    }
                    
                    // 清除目標點標記
                    if (targetMarker) {
                        missionPlanGroup.removeLayer(targetMarker);
                        targetMarker = null;
                    }
                    
                    // 清除位置資訊
                    centerPosition = null;
                    targetPosition = null;
                    updateMissionInfo();
                    
                    console.log('任務規劃已清除');
                }
                // ================================================================================
            </script>
            </body>
            </html>
        '''
        
        self.map_view.setHtml(inline_html)
        self.map_view.loadFinished.connect(self._on_map_loaded)
        
        # 設置地圖更新計時器
        self.map_update_timer = QTimer()
        self.map_update_timer.timeout.connect(self.update_map_positions)
        self.map_update_timer.start(200)  # 每 200ms 更新一次
    
    def _on_map_loaded(self, ok: bool):
        """地圖加載完成回調"""
        if ok:
            self.map_loaded = True
        else:
            print("⚠️ 地圖加載失敗")
    
    def update_drone_position(self, drone_id, lat, lon, heading):
        """更新無人機位置（加入待處理隊列）"""
        self.pending_map_updates[drone_id] = (lat, lon, heading)
    
    def update_map_positions(self):
        """批量更新地圖上的無人機位置"""
        if not self.map_loaded or not self.pending_map_updates:
            return
        
        # 批量執行所有待更新的位置
        js_commands = []
        for drone_id, (lat, lon, heading) in self.pending_map_updates.items():
            js_commands.append(f"updateDrone({lat:.6f}, {lon:.6f}, '{drone_id}', {heading:.1f});")
        
        if js_commands:
            combined_js = "\n".join(js_commands)
            self.map_view.page().runJavaScript(combined_js)
        
        # 清空待更新緩存
        self.pending_map_updates.clear()
    
    def clear_trajectories(self):
        """清除所有軌跡"""
        if self.map_loaded:
            self.map_view.page().runJavaScript("clearAllTrajectories();")
    
    def focus_on_drone(self, drone_id):
        """聚焦到指定無人機"""
        if self.map_loaded:
            self.map_view.page().runJavaScript(f"focusOn('{drone_id}');")
    
    # ================================================================================
    # 【新增】任務規劃視覺化方法
    # ================================================================================
    def draw_mission_plan(self, center_lat, center_lon, target_lat, target_lon):
        """
        在地圖上繪製任務規劃
        
        Args:
            center_lat: 中心點緯度
            center_lon: 中心點經度
            target_lat: 目標點緯度
            target_lon: 目標點經度
        """
        if self.map_loaded:
            js_code = f"drawMissionPlan({center_lat:.6f}, {center_lon:.6f}, {target_lat:.6f}, {target_lon:.6f});"
            self.map_view.page().runJavaScript(js_code)
            print(f"📍 地圖已繪製任務規劃: C({center_lat:.6f}, {center_lon:.6f}) -> T({target_lat:.6f}, {target_lon:.6f})")
    
    def clear_mission_plan(self):
        """清除地圖上的任務規劃標記"""
        if self.map_loaded:
            self.map_view.page().runJavaScript("clearMissionPlan();")
            print("🗑️ 地圖已清除任務規劃")
    # ================================================================================
    
    def get_widget(self):
        """獲取地圖 widget"""
        return self.map_view
    
    def get_gps_signal(self):
        """獲取 GPS 信號"""
        return self.bridge.gps_signal
    
    def get_drone_clicked_signal(self):
        """獲取無人機點擊信號"""
        return self.bridge.drone_clicked
    
    def get_clear_all_drone_selection_signal(self):
        """獲取清除所有無人機選擇信號"""
        return self.bridge.clear_all_drone_selection
    
    def get_toggle_select_all_drones_signal(self):
        """獲取切換全選所有無人機信號"""
        return self.bridge.select_all_drones
    
    def get_select_all_drones_signal(self):
        """獲取全選所有無人機信號"""
        return self.bridge.select_all_drones
    
    def get_start_mission_signal(self):
        """獲取開始任務信號"""
        return self.bridge.start_mission_signal
    
    def get_pause_mission_signal(self):
        """獲取暫停任務信號"""
        return self.bridge.pause_mission_signal
    
    def get_rectangle_selected_signal(self):
        """獲取矩形選擇信號"""
        return self.bridge.rectangle_selected
    
    def get_polygon_selected_signal(self):
        """獲取多邊形選擇信號"""
        return self.bridge.polygon_selected
    
class MapBridge(QObject):
    """JavaScript 和 Python 之間的橋接類"""
    gps_signal = pyqtSignal(float, float)  # lat, lon
    drone_clicked = pyqtSignal(str)  # drone_id
    clear_all_drone_selection = pyqtSignal()  # clear all drone selection
    select_all_drones = pyqtSignal()  # select all drones
    start_mission_signal = pyqtSignal(float, float, float, float)  # center_lat, center_lon, target_lat, target_lon
    pause_mission_signal = pyqtSignal()  # pause mission
    rectangle_selected = pyqtSignal(str)  # JSON string of rectangle points
    polygon_selected = pyqtSignal(str)  # JSON string of polygon points
    
    def __init__(self):
        super().__init__()
    
    @pyqtSlot(float, float)
    def emitGpsSignal(self, lat, lon):
        """供 JavaScript 調用的方法"""
        self.gps_signal.emit(lat, lon)
    
    @pyqtSlot(str)
    def emitDroneClicked(self, drone_id):
        """供 JavaScript 調用的方法 - 當無人機被點擊時"""
        self.drone_clicked.emit(drone_id)
    
    @pyqtSlot()
    def clearAllDroneSelection(self):
        """供 JavaScript 調用的方法 - 清除所有無人機選擇"""
        self.clear_all_drone_selection.emit()
        print("🗑️ 清除所有無人機選擇")
    
    @pyqtSlot()
    def toggleSelectAllDrones(self):
        """供 JavaScript 調用的方法 - 切換全選/取消全選所有無人機"""
        self.select_all_drones.emit()
        print("🔄 切換全選無人機")
    
    @pyqtSlot(float, float, float, float)
    def startMissionSignal(self, center_lat, center_lon, target_lat, target_lon):
        """供 JavaScript 調用的方法 - 開始任務"""
        self.start_mission_signal.emit(center_lat, center_lon, target_lat, target_lon)
        print(f"🚀 開始任務信號已發出: C({center_lat}, {center_lon}) -> T({target_lat}, {target_lon})")
    
    @pyqtSlot()
    def pauseMissionSignal(self):
        """供 JavaScript 調用的方法 - 暫停任務"""
        self.pause_mission_signal.emit()
        print("⏸️ 暫停任務信號已發出")
    
    @pyqtSlot(str)
    def rectangleSelected(self, points_json):
        """供 JavaScript 調用的方法 - 矩形選擇完成"""
        self.rectangle_selected.emit(points_json)
        print(f"📦 矩形區域已選擇: {points_json}")
    
    @pyqtSlot(str)
    def polygonSelected(self, points_json):
        """供 JavaScript 調用的方法 - 多邊形選擇完成"""
        self.polygon_selected.emit(points_json)
        print(f"🔷 多邊形區域已選擇: {points_json}")