import L from "leaflet"
import { ref, Ref } from "vue";

function close(used: number[], close: number): number { // 接近数字下表
    const closeUsed = used.map((v, i) => ({ v: close - v, i }))
    const p = closeUsed.shift();
    if (!p) throw new Error('传入使用数组不能为空');
    const a = closeUsed.reduce((pre, cur) => {
        if (pre.v < 0 && cur.v < 0) { // 双方小数
            return pre.v < cur.v ? cur : pre   // 取大
        } else if (pre.v < 0 || cur.v < 0) { // 有一方是小数
            return pre.v < 0 ? pre : cur // 取小数
        } else { // 都不是
            
            return pre.v < cur.v ? pre : cur // 取小
        }
    }, p)

    return a.i
}

function limitZoom(min: number, max: number, zoom: number): number {
    return Math.max(min, Math.min(max, zoom))
}

function useZoom(mapContainer: Ref<HTMLElement>, map: Ref<L.Map | undefined>, used: number[]) {
    const _used = used.sort((a, b) => a - b)
    let _timer = 0;
    let _delta = 0;
    let _currentZoom = ref(0);

    const zoomControl = L.Handler.extend({
        addHooks: function () {
            console.log('add')
            L.DomEvent.on(mapContainer.value, 'wheel', this._onWheelScroll)
        },
        removeHooks: function () {
            console.log('remove')
            L.DomEvent.off(mapContainer.value, 'wheel', this._onWheelScroll)
        },
        _onWheelScroll: function (e: WheelEvent) {
            const _map = map.value;
            if (!_map) return;
            let _lastMousePos = _map.mouseEventToContainerPoint(e);
            let _debounce = _map.options.wheelDebounceTime

            const delta = L.DomEvent.getWheelDelta(e);  // 处理高度
            _delta += delta

            clearTimeout(_timer)
            _timer = setTimeout(() => {

                let zoom = _map.getZoom(),
                    snap = _map.options.zoomSnap || 0,
                    d2 = _delta / ((_map.options.wheelPxPerZoomLevel || 60) * 4),
                    d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2,
                    d4 = snap ? Math.ceil(d3 / snap) * snap : d3,
                    min = _map.getMinZoom(),
                    max = _map.getMaxZoom(),
                    limit = limitZoom(min, max, zoom + (_delta > 0 ? d4 : -d4)),
                    delta = limit - zoom;

                if (!delta) return
                _currentZoom.value = close(_used, limit) + delta
                const _to = _used[_currentZoom.value];
                console.log(_used, '当前', zoom, '放大缩小', delta, '接近', close(_used, limit), '转到', _currentZoom.value, '实际', _to)
                debugger
                if (_map.options.scrollWheelZoom === 'center') {
                    _map.setZoom(_to);
                } else {
                    _map.setZoomAround(_lastMousePos, _to);
                }
                _delta = 0
            }, _debounce);


            L.DomEvent.stop(e);
        },
    })

    return zoomControl
}


export default useZoom