<template>
    <view class="map-view-container">
        <!-- Leaflet WebView 地图 -->
        <leaflet-map
            ref="leafletMapRef"
            :latitude="centerLatitude"
            :longitude="centerLongitude"
            :zoom="props.zoom"
            :markers="markers"
            :layer-type="currentLayerType"
            :tianditu-key="tiandituKey"
            @markerTap="handleMarkerTap"
            @regionChange="handleRegionChange"
            @layerChange="handleLayerChange"
            @ready="handleMapReady"
            @error="handleMapError"
        />

        <!-- 返回按钮 -->
        <view class="back-btn" @click="handleBack">
            <text class="back-icon">←</text>
        </view>

        <!-- 操作按钮 -->
        <view class="map-controls">
            <view class="control-btn" @click="showLayerPopup">
                <image class="control-icon" src="/static/images/map/1.png" mode="aspectFit"></image>
            </view>
            <view class="control-btn" @click="handleZoomIn">
                <image class="control-icon" src="/static/images/map/3.png" mode="aspectFit"></image>
            </view>
            <view class="control-btn" @click="handleZoomOut">
                <image class="control-icon" src="/static/images/map/4.png" mode="aspectFit"></image>
            </view>
            <view class="control-btn" @click="handleLocation">
                <image class="control-icon" src="/static/images/map/2.png" mode="aspectFit"></image>
            </view>
        </view>

        <!-- 图层切换弹窗 - 自定义实现 -->
        <!-- 遮罩层 -->
        <view v-if="layerPopupVisible" class="popup-mask" @click="closeLayerPopup"></view>

        <!-- 弹窗内容 -->
        <view class="layer-popup" :class="{ 'layer-popup-show': layerPopupVisible }">
            <view class="popup-header">
                <text class="popup-title">图层选择</text>
                <view class="popup-close" @click="closeLayerPopup">
                    <text class="close-icon">×</text>
                </view>
            </view>

            <scroll-view class="popup-scroll" :scroll-y="true" :show-scrollbar="true">
                <!-- 地图主题 -->
                <view class="layer-section">
                    <text class="section-title">{{ baseLayerConfig.name }}</text>
                    <view class="layer-list">
                        <view v-for="(item, index) in baseLayerConfig.list" :key="index" class="layer-item" :class="{ 'layer-item-active': item.active }" @click="handleBaseLayerChange(index)">
                            <image class="layer-image" :src="item.icon" mode="aspectFill"></image>
                            <text class="layer-name">{{ item.name }}</text>
                            <view v-if="item.active" class="layer-check">
                                <text class="check-icon">✓</text>
                            </view>
                        </view>
                    </view>
                </view>

                <!-- 基础数据 -->
                <view class="layer-section">
                    <text class="section-title">{{ businessLayerConfig.name }}</text>
                    <view class="layer-list">
                        <view v-for="(item, index) in businessLayerConfig.list" :key="index" class="layer-item" :class="{ 'layer-item-active': item.active }" @click="handleBusinessLayerChange(index)">
                            <image class="layer-image" :src="item.icon" mode="aspectFill"></image>
                            <text class="layer-name">{{ item.name }}</text>
                            <view v-if="item.active" class="layer-check">
                                <text class="check-icon">✓</text>
                            </view>
                        </view>
                    </view>
                </view>
            </scroll-view>
        </view>
    </view>
</template>

<script setup lang="uts">
    import { ref, reactive, type ComponentPublicInstance } from 'vue'
    import type { MapMarker, MapLayerType } from '../../types/map'
    import { ARCGIS_CONFIG } from '../../config/map.config'

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

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

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

    // Leaflet 地图引用
    const leafletMapRef = ref<ComponentPublicInstance | null>(null)

    // 地图中心点
    const centerLatitude = ref<number>(props.latitude)
    const centerLongitude = ref<number>(props.longitude)
    const scale = ref<number>(16)

    // 当前图层类型（使用 as string 转换，让 ref 自动推断类型）
    const currentLayerType = ref(props.layerType as string)

    // 地图是否已准备好
    const isMapReady = ref(false)

    // 图层弹窗显示状态
    const layerPopupVisible = ref(false)

    // 当前位置标记点 ID
    const locationMarkerId = ref<number>(999999)

    // 图层配置类型定义
    type LayerItem = {
        code: string
        name: string
        icon: string
        url?: string
        active: boolean
    }

    type LayerConfig = {
        name: string
        list: LayerItem[]
    }

    // 图层配置（使用 ref 包装）
    const baseLayerConfig = ref<LayerConfig>({
        name: '地图主题',
        list: [
            {
                code: 'tianditu-vec',
                name: '天地图-矢量',
                icon: '/static/images/map/map1.jpg',
                active: false
            },
            {
                code: 'tianditu-img',
                name: '天地图-影像',
                icon: '/static/images/map/map2.jpg',
                active: true
            },
            {
                code: 'tianditu-ter',
                name: '天地图-地形',
                icon: '/static/images/map/map3.jpg',
                active: false
            }
        ]
    })

    const businessLayerConfig = ref<LayerConfig>({
        name: '基础数据',
        list: [
            {
                code: 'boundary',
                name: '界桩',
                icon: '/static/images/map/map4.jpg',
                url: '/arcgis/rest/services/水利专题图层/界桩点/MapServer/tile/{z}/{y}/{x}',
                active: false
            },
            {
                code: 'landLine',
                name: '管理线',
                icon: '/static/images/map/map5.jpg',
                url: '/arcgis/rest/services/管理和保护范围/管理范围/MapServer/tile/{z}/{y}/{x}',
                active: true
            },
            {
                code: 'protectLine',
                name: '保护线',
                icon: '/static/images/map/map6.jpg',
                url: '/arcgis/rest/services/管理和保护范围/保护范围/MapServer/tile/{z}/{y}/{x}',
                active: false
            }
        ]
    })

    /**
     * 获取图层显示名称
     */
    const getLayerName = (layerType: MapLayerType): string => {
        if (layerType == 'tianditu-vec') {
            return '天地图矢量'
        } else if (layerType == 'tianditu-img') {
            return '天地图影像'
        } else if (layerType == 'tianditu-ter') {
            return '天地图地形'
        }
        return '未知图层'
    }

    /**
     * 初始化业务图层（加载默认激活的图层）
     * 必须在 handleMapReady 之前定义
     */
    const initBusinessLayers = (): void => {
        console.log('initBusinessLayers 开始执行')
        console.log('leafletMapRef.value:', leafletMapRef.value)
        
        // 获取 token
        const token = uni.getStorageSync('accessToken') as string | null
        // const token = "eyJhbGciOiJIUzI1NiJ9.eyJyZWFsTmFtZSI6IueOi-itpuS9jSIsInN1YiI6IndhbmdqaW5nd2VpIiwiZGVwdElkIjoiMTAwMDA3IiwiZXhwIjoxNzYyOTMwMTAwLCJ1c2VySWQiOjI2OCwiaWF0IjoxNzYyODQzNzAwLCJqdGkiOiI3YzhhNmVmYi0xMDQyLTQ0NjAtOWNlMi1iZGMwMTVjNmZlMDYiLCJ1c2VybmFtZSI6IndhbmdqaW5nd2VpIn0.BlEnejBXkemhZY1nXd5xSAo8t5XoFSTnQVD09CQlVcI"
        console.log('token:', token != null ? 'exists' : 'null')
        
        for (let i = 0; i < businessLayerConfig.value.list.length; i++) {
            const item = businessLayerConfig.value.list[i]
            console.log(`检查图层 ${i}:`, item.name, 'active:', item.active)
            
            if (item.active) {
                const layerUrl = item.url as string | null
                console.log('layerUrl:', layerUrl)
                
                if (layerUrl != null && leafletMapRef.value != null) {
                    leafletMapRef.value.$callMethod('addBusinessLayer', item.code, layerUrl, ARCGIS_CONFIG.baseUrl, token)
                    console.log('✓ 初始化业务图层:', item.name)
                } else {
                    console.log('✗ 未能添加图层，layerUrl:', layerUrl, 'leafletMapRef:', leafletMapRef.value)
                }
            }
        }
    }

    /**
     * 获取当前位置
     * 必须在 handleMapReady 之前定义
     * 
     * 注意：
     * 1. manifest.json 中已配置定位权限，首次调用时系统会自动请求权限
     * 2. 使用系统定位（system provider），只支持 wgs84 坐标系
     * 3. 如需使用 gcj02 坐标，需配置腾讯定位 provider: 'tencent'
     */
    const handleLocation = (): void => {
        uni.getLocation({
            type: 'wgs84',
            success: (res) => {
                const latitude = res.latitude as number
                const longitude = res.longitude as number
                const accuracy = res.accuracy as number

                centerLatitude.value = latitude
                centerLongitude.value = longitude

                // 等待地图完全准备好再设置中心和添加标记点
                if (isMapReady.value && leafletMapRef.value != null) {
                    leafletMapRef.value.$callMethod('setCenter', latitude, longitude, null)

                    // 先移除旧的位置标记点
                    leafletMapRef.value.$callMethod('removeMarker', locationMarkerId.value)

                    // 添加位置标记点
                    const locationMarker: MapMarker = {
                        id: locationMarkerId.value,
                        latitude: latitude,
                        longitude: longitude,
                        title: '我的位置',
                        iconPath: '/static/images/map/location.png',
                        width: 48,
                        height: 48
                    }
                    leafletMapRef.value.$callMethod('addMarker', locationMarker)
                }

                emit('locationUpdate', {
                    latitude: latitude,
                    longitude: longitude,
                    accuracy: accuracy
                })

            },
            fail: (err) => {
                console.log('定位失败', err)
                
                // #ifdef WEB
                // Web 平台降级方案：使用默认位置（props 中的初始位置）
                const latitude = props.latitude
                const longitude = props.longitude
                
                centerLatitude.value = latitude
                centerLongitude.value = longitude

                // 等待地图完全准备好再设置中心和添加标记点
                if (isMapReady.value && leafletMapRef.value != null) {
                    leafletMapRef.value.$callMethod('setCenter', latitude, longitude, null)

                    // 先移除旧的位置标记点
                    leafletMapRef.value.$callMethod('removeMarker', locationMarkerId.value)

                    // 添加位置标记点（使用默认位置）
                    const locationMarker: MapMarker = {
                        id: locationMarkerId.value,
                        latitude: latitude,
                        longitude: longitude,
                        title: '默认位置',
                        iconPath: '/static/images/map/location.png',
                        width: 48,
                        height: 48
                    }
                    leafletMapRef.value.$callMethod('addMarker', locationMarker)
                }

                emit('locationUpdate', {
                    latitude: latitude,
                    longitude: longitude,
                    accuracy: 0
                })
                
                console.log('Web平台定位失败，使用默认位置')
                // #endif
                
                // #ifndef WEB
                // App 平台直接提示定位失败
                uni.showToast({
                    title: '定位失败',
                    icon: 'none',
                    duration: 2000
                })
                // #endif
            }
        })
    }

    // 地图准备完成
    const handleMapReady = (): void => {
        isMapReady.value = true
        console.log('地图准备完成')

        // 延迟初始化业务图层，确保 JavaScript 完全准备好
        setTimeout(() => {
            console.log('准备初始化业务图层...')
            initBusinessLayers()
        }, 500)

        // 自动定位当前位置
        if (props.showLocation) {
            setTimeout(() => {
                console.log('开始自动定位...')
                handleLocation()
            }, 800)
        }
    }

    // 地图错误
    const handleMapError = (error: string): void => {
        console.error('地图错误:', error)
    }

    // 返回上一页
    const handleBack = (): void => {
        uni.navigateBack()
    }

    // 放大地图
    const handleZoomIn = (): void => {
        if (scale.value < 20) {
            scale.value++
            if (leafletMapRef.value != null) {
                leafletMapRef.value.$callMethod('setZoom', scale.value)
            }
        }
    }

    // 缩小地图
    const handleZoomOut = (): void => {
        if (scale.value > 5) {
            scale.value--
            if (leafletMapRef.value != null) {
                leafletMapRef.value.$callMethod('setZoom', scale.value)
            }
        }
    }

    // 标记点点击
    const handleMarkerTap = (e: any): void => {
        emit('markerTap', e)
    }

    // 地图区域变化
    const handleRegionChange = (e: any): void => {
        emit('regionChange', e)
    }

    // 图层变化
    const handleLayerChange = (layerType: MapLayerType): void => {
        currentLayerType.value = layerType as string
        emit('layerChange', layerType)
    }

    /**
     * 切换地图图层（核心方法，必须在 handleSwitchLayer 之前定义）
     */
    const switchLayer = (layerType: MapLayerType): void => {
        try {
            // 验证图层类型
            if (currentLayerType.value == (layerType as string)) {
                return
            }

            // 更新图层
            currentLayerType.value = layerType as string

            if (leafletMapRef.value != null) {
                leafletMapRef.value.$callMethod('switchLayer', layerType)
            }

        } catch (e: any) {
            const message = e.message as string | null
            const errorMsg: string = message != null ? message : '图层切换失败'
            emit('layerChangeError', errorMsg)
        }
    }

    /**
     * 显示图层选择弹窗
     */
    const showLayerPopup = (): void => {
        layerPopupVisible.value = true
    }

    /**
     * 关闭图层选择弹窗
     */
    const closeLayerPopup = (): void => {
        layerPopupVisible.value = false
    }

    /**
     * 切换基础图层（地图主题）
     */
    const handleBaseLayerChange = (index: number): void => {
        // 取消其他图层的选中状态
        for (let i = 0; i < baseLayerConfig.value.list.length; i++) {
            baseLayerConfig.value.list[i].active = (i == index)
        }

        // 获取选中的图层
        const selectedLayer = baseLayerConfig.value.list[index]
        const layerType = selectedLayer.code as MapLayerType

        // 切换图层
        switchLayer(layerType)
    }

    /**
     * 切换业务图层（基础数据）
     */
    const handleBusinessLayerChange = (index: number): void => {
        // 切换选中状态
        const item = businessLayerConfig.value.list[index]
        item.active = !item.active

        // 获取图层 URL
        const layerUrl = item.url as string | null
        if (layerUrl == null) {
            console.error('业务图层 URL 为空:', item.name)
            return
        }

        // 根据 active 状态添加或移除图层
        if (leafletMapRef.value != null) {
            if (item.active) {
                // 获取 token
                // const token = uni.getStorageSync('accessToken') as string | null
                const token = "eyJhbGciOiJIUzI1NiJ9.eyJyZWFsTmFtZSI6IueOi-itpuS9jSIsInN1YiI6IndhbmdqaW5nd2VpIiwiZGVwdElkIjoiMTAwMDA3IiwiZXhwIjoxNzYyOTMwMTAwLCJ1c2VySWQiOjI2OCwiaWF0IjoxNzYyODQzNzAwLCJqdGkiOiI3YzhhNmVmYi0xMDQyLTQ0NjAtOWNlMi1iZGMwMTVjNmZlMDYiLCJ1c2VybmFtZSI6IndhbmdqaW5nd2VpIn0.BlEnejBXkemhZY1nXd5xSAo8t5XoFSTnQVD09CQlVcI"
                
                // 添加图层
                leafletMapRef.value.$callMethod('addBusinessLayer', item.code, layerUrl, ARCGIS_CONFIG.baseUrl, token)
                console.log('添加业务图层:', item.name, ARCGIS_CONFIG.baseUrl, layerUrl )
            } else {
                // 移除图层
                leafletMapRef.value.$callMethod('removeBusinessLayer', item.code)
                console.log('移除业务图层:', item.name,  ARCGIS_CONFIG.baseUrl, layerUrl)
            }
        }
    }

    // 批量添加标记点
    const addMarkers = (markers: MapMarker[]): void => {
        if (leafletMapRef.value != null) {
            leafletMapRef.value.$callMethod('addMarkers', markers)
        }
    }

    // 清除所有标记点
    const clearMarkers = (): void => {
        if (leafletMapRef.value != null) {
            leafletMapRef.value.$callMethod('clearMarkers')
        }
    }

    // 添加路线
    const addPolyline = (points: any[], color: string | null, width: number | null): void => {
        if (leafletMapRef.value != null) {
            leafletMapRef.value.$callMethod('addPolyline', points, color, width)
        }
    }

    // 添加圆形
    const addCircle = (
        latitude: number,
        longitude: number,
        radius: number,
        strokeColor: string | null,
        fillColor: string | null
    ): void => {
        if (leafletMapRef.value != null) {
            leafletMapRef.value.$callMethod('addCircle', latitude, longitude, radius, strokeColor, fillColor)
        }
    }

    // 添加多边形
    const addPolygon = (
        points: any[],
        strokeColor: string | null,
        fillColor: string | null
    ): void => {
        if (leafletMapRef.value != null) {
            leafletMapRef.value.$callMethod('addPolygon', points, strokeColor, fillColor)
        }
    }

    // 清除所有覆盖物
    const clearOverlays = (): void => {
        if (leafletMapRef.value != null) {
            leafletMapRef.value.$callMethod('clearOverlays')
        }
    }

    /**
     * 获取当前图层类型
     */
    const getCurrentLayerType = (): string => {
        return currentLayerType.value
    }

    /**
     * 获取图层配置信息
     */
    const getLayerConfig = (): any => {
        return {
            currentLayerType: currentLayerType.value,
            layerName: getLayerName(currentLayerType.value as MapLayerType),
            isReady: isMapReady.value
        }
    }

    // 暴露方法给父组件
    defineExpose({
        addMarkers,
        clearMarkers,
        addPolyline,
        addCircle,
        addPolygon,
        clearOverlays,
        handleLocation,
        switchLayer,
        getCurrentLayerType,
        getLayerConfig
    })
</script>

<style lang="scss">
    .map-view-container {
        position: relative;
        width: 100%;
        height: 100%;
    }

    .back-btn {
        position: absolute;
        left: 20rpx;
        top: 80rpx;
        width: 80rpx;
        height: 80rpx;
        background-color: #ffffff;
        border-radius: 40rpx;
        box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15);
        justify-content: center;
        align-items: center;

        .back-icon {
            font-size: 36rpx;
            color: #333333;
            font-weight: bold;
            line-height: 80rpx;
        }
    }

    .map-controls {
        position: absolute;
        right: 20rpx;
        top: 80rpx;
        flex-direction: column;
    }

    .control-btn {
        width: 80rpx;
        height: 80rpx;
        margin-bottom: 15rpx;
        background-color: #ffffff;
        border-radius: 8rpx;
        box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15);
        justify-content: center;
        align-items: center;

        .control-icon {
            width: 48rpx;
            height: 48rpx;
        }
    }

    /* 自定义图层弹窗样式 */
    .popup-mask {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(0, 0, 0, 0.5);
        z-index: 998;
    }

    .layer-popup {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        width: 70%;
        background-color: #ffffff;
        flex-direction: column;
        z-index: 999;
        transform: translateX(100%);
        transition-property: transform;
        transition-duration: 300ms;
        transition-timing-function: ease;

        .popup-header {
            height: 180rpx;
            padding: 80rpx 30rpx 0 30rpx;
            border-bottom: 1rpx solid #f0f0f0;
            flex-direction: row;
            justify-content: space-between;
            align-items: center;

            .popup-title {
                font-size: 32rpx;
                font-weight: bold;
                color: #333333;
            }

            .popup-close {
                width: 60rpx;
                height: 60rpx;
                justify-content: center;
                align-items: center;

                .close-icon {
                    font-size: 48rpx;
                    color: #666666;
                    line-height: 60rpx;
                }
            }
        }

        .popup-scroll {
            flex: 1;
            padding: 30rpx;
        }
    }

    .layer-popup-show {
        transform: translateX(0) !important;
    }

    .layer-section {
        margin-bottom: 40rpx;

        .section-title {
            font-size: 28rpx;
            color: #666666;
            margin-bottom: 20rpx;
        }

        .layer-list {
            flex-direction: row;
            flex-wrap: wrap;
            justify-content: flex-start;

            .layer-item {
                position: relative;
                width: 200rpx;
                height: 200rpx;
                margin-bottom: 20rpx;
                margin-right: 20rpx;
                border-radius: 8rpx;
                overflow: hidden;
                border: 2rpx solid transparent;

                .layer-image {
                    width: 200rpx;
                    height: 200rpx;
                }

                .layer-name {
                    position: absolute;
                    bottom: 0;
                    left: 0;
                    right: 0;
                    padding: 10rpx;
                    background-color: rgba(0, 0, 0, 0.6);
                    font-size: 24rpx;
                    color: #ffffff;
                }

                .layer-check {
                    position: absolute;
                    top: 10rpx;
                    right: 10rpx;
                    width: 44rpx;
                    height: 44rpx;
                    background-color: #007aff;
                    border-radius: 22rpx;
                    justify-content: center;
                    align-items: center;

                    .check-icon {
                        font-size: 28rpx;
                        color: #ffffff;
                        font-weight: bold;
                    }
                }
            }

            .layer-item-active {
                border-color: #007aff;
            }
        }
    }
</style>
