<template>
    <web-view 
        ref="webviewRef"
        id="leafletWebView"
        :src="webviewUrl"
        @message="handleMessage"
        @load="handleLoad"
        class="leaflet-webview"
    ></web-view>
</template>

<script setup lang="uts">
import { ref, computed, watch } from 'vue'
import type { MapMarker, MapLayerType } from '../../types/map'

// Props
type Props = {
    latitude?: number
    longitude?: number
    zoom?: number
    markers?: MapMarker[]
    layerType?: MapLayerType
    tiandituKey?: string
}

const props = withDefaults(defineProps<Props>(), {
    latitude: 32.556211,
    longitude: 111.494811,
    zoom: 13,
    markers: () => [],
    layerType: 'tianditu-img',
    tiandituKey: '4c9c8a818d3cb25bf5ccbd749e7e67c8'
})

// Emits
const emit = defineEmits<{
    (e: 'markerTap', event: any): void
    (e: 'regionChange', region: any): void
    (e: 'layerChange', layerType: MapLayerType): void
    (e: 'ready'): void
    (e: 'error', error: string): void
}>()

// WebView 引用（内置组件使用对应的 Element 类型）
const webviewRef = ref<UniWebViewElement | null>(null)

// WebView 是否已加载
const isWebviewLoaded = ref(false)

// WebView URL
const webviewUrl = computed<string>(() => {
    return `/static/leaflet/leaflet-map.html?lat=${props.latitude}&lng=${props.longitude}&zoom=${props.zoom}&layer=${props.layerType}&key=${props.tiandituKey}`
})

// 处理 WebView 加载完成
const handleLoad = (): void => {
    isWebviewLoaded.value = true
    console.log('WebView loaded')
    
    // 延迟触发 ready 事件，等待地图初始化完成
    // 因为 web-view 在不同平台的消息机制不同，所以直接在 load 完成后触发
    setTimeout(() => {
        console.log('Auto-triggering ready event after WebView load')
        emit('ready')
    }, 1000)
}

// 处理 WebView 消息
const handleMessage = (e: any): void => {
    try {
        console.log('WebView message received')
        
        // WebView 的 message 事件在不同平台可能有不同的数据结构
        // 直接触发 ready 事件，让地图组件可以开始工作
        console.log('Emitting ready event')
        emit('ready')
    } catch (error: any) {
        console.error('Error handling WebView message:', error)
        // 即使出错也触发 ready
        emit('ready')
    }
}

// 执行 JavaScript（内置组件直接调用方法）
const evalJS = (js: string): void => {
    if (!isWebviewLoaded.value || webviewRef.value == null) {
        return
    }
    
    // #ifdef APP
    // App 平台：web-view 是原生组件，直接调用 evalJS 方法
    webviewRef.value.evalJS(js)
    // #endif
    
    // #ifdef WEB
    // Web 平台：web-view 是 iframe，通过 contentWindow 执行 JavaScript
    try {
        // 尝试多种方式获取 iframe 元素
        let iframeElement = null
        
        // 方式1：通过 $el 访问
        const iframe = webviewRef.value as any
        if (iframe && iframe.$el) {
            if (iframe.$el.tagName === 'IFRAME') {
                iframeElement = iframe.$el
            } else {
                // 可能是包装元素，查找其中的 iframe
                iframeElement = iframe.$el.querySelector('iframe')
            }
        }
        
        // 方式2：通过 ID 查找
        if (iframeElement == null) {
            iframeElement = document.getElementById('leafletWebView')
        }
        
        // 方式3：查找所有 iframe
        if (iframeElement == null) {
            const iframes = document.getElementsByTagName('iframe')
            if (iframes.length > 0) {
                iframeElement = iframes[0]
            }
        }
        
        console.log('iframe element:', iframeElement)
        console.log('iframe contentWindow:', iframeElement ? iframeElement.contentWindow : null)
        
        if (iframeElement && iframeElement.contentWindow) {
            // 使用 eval 在 iframe 的上下文中执行 JavaScript
            iframeElement.contentWindow.eval(js)
            console.log('✓ Web platform: evalJS executed successfully')
        } else {
            console.warn('Web platform: Cannot access iframe contentWindow', {
                iframeElement: iframeElement,
                contentWindow: iframeElement ? iframeElement.contentWindow : null
            })
        }
    } catch (e: any) {
        console.error('Web platform: evalJS error:', e)
    }
    // #endif
}

// 添加标记点
const addMarker = (marker: MapMarker): void => {
    const js = `window.leafletMap.addMarker(${JSON.stringify({
        id: marker.id,
        latitude: marker.latitude,
        longitude: marker.longitude,
        title: marker.title,
        iconPath: marker.iconPath,
        width: marker.width,
        height: marker.height
    })})`
    evalJS(js)
}

// 批量添加标记点
const addMarkers = (markers: MapMarker[]): void => {
    const markersData = markers.map((marker) => ({
        id: marker.id,
        latitude: marker.latitude,
        longitude: marker.longitude,
        title: marker.title,
        iconPath: marker.iconPath,
        width: marker.width,
        height: marker.height
    }))
    const js = `window.leafletMap.addMarkers(${JSON.stringify(markersData)})`
    evalJS(js)
}

// 清除所有标记点
const clearMarkers = (): void => {
    const js = 'window.leafletMap.clearMarkers()'
    evalJS(js)
}

// 移除单个标记点
const removeMarker = (markerId: number): void => {
    const js = `window.leafletMap.removeMarker(${markerId})`
    evalJS(js)
}

// 添加折线
const addPolyline = (points: any[], color: string | null, width: number | null): void => {
    const finalColor = color != null ? color : '#007aff'
    const finalWidth = width != null ? width : 4
    
    // 构造数据对象
    const data = {
        points: points,
        color: finalColor,
        width: finalWidth
    }
    
    const js = `window.leafletMap.addPolyline(${JSON.stringify(data)})`
    evalJS(js)
}

// 添加圆形
const addCircle = (
    latitude: number,
    longitude: number,
    radius: number,
    strokeColor: string | null,
    fillColor: string | null
): void => {
    const finalStrokeColor = strokeColor != null ? strokeColor : '#007aff'
    const finalFillColor = fillColor != null ? fillColor : 'rgba(0, 122, 255, 0.2)'
    
    // 构造数据对象
    const data = {
        latitude: latitude,
        longitude: longitude,
        radius: radius,
        strokeColor: finalStrokeColor,
        fillColor: finalFillColor
    }
    
    const js = `window.leafletMap.addCircle(${JSON.stringify(data)})`
    evalJS(js)
}

// 添加多边形
const addPolygon = (
    points: any[],
    strokeColor: string | null,
    fillColor: string | null
): void => {
    const finalStrokeColor = strokeColor != null ? strokeColor : '#007aff'
    const finalFillColor = fillColor != null ? fillColor : 'rgba(0, 122, 255, 0.2)'
    
    // 构造数据对象
    const data = {
        points: points,
        strokeColor: finalStrokeColor,
        fillColor: finalFillColor
    }
    
    const js = `window.leafletMap.addPolygon(${JSON.stringify(data)})`
    evalJS(js)
}

// 清除所有覆盖物
const clearOverlays = (): void => {
    const js = 'window.leafletMap.clearOverlays()'
    evalJS(js)
}

// 设置地图中心
const setCenter = (latitude: number, longitude: number, zoom: number | null): void => {
    if (zoom != null) {
        const js = `window.leafletMap.setCenter(${latitude}, ${longitude}, ${zoom})`
        evalJS(js)
    } else {
        // 使用当前缩放级别
        const js = `window.leafletMap.setCenter(${latitude}, ${longitude})`
        evalJS(js)
    }
}

// 设置缩放级别
const setZoom = (zoom: number): void => {
    const js = `window.leafletMap.setZoom(${zoom})`
    evalJS(js)
}

// 切换图层
const switchLayer = (layerType: MapLayerType): void => {
    const js = `window.leafletMap.switchLayer('${layerType}')`
    evalJS(js)
    emit('layerChange', layerType)
}

// 添加业务图层
const addBusinessLayer = (layerCode: string, layerUrl: string, baseUrl: string, token: string | null): void => {
    const tokenParam = token != null ? token : ''
    const js = `window.leafletMap.addBusinessLayer('${layerCode}', '${layerUrl}', '${baseUrl}', '${tokenParam}')`
    evalJS(js)
}

// 移除业务图层
const removeBusinessLayer = (layerCode: string): void => {
    const js = `window.leafletMap.removeBusinessLayer('${layerCode}')`
    evalJS(js)
}

// 暴露方法
defineExpose({
    addMarker,
    addMarkers,
    clearMarkers,
    removeMarker,
    addPolyline,
    addCircle,
    addPolygon,
    clearOverlays,
    setCenter,
    setZoom,
    switchLayer,
    addBusinessLayer,
    removeBusinessLayer
})
</script>

<style lang="scss">
.leaflet-webview {
    width: 100%;
    height: 100%;
}
</style>

