import L, { Layer } from "leaflet"
import { Ref, isRef, onMounted, reactive, ref, shallowRef, toRef, triggerRef, watch } from "vue"
import useCrs from "./useCrs"
import { MapType } from "../lib/mapType"
import useConfig, { Config } from "./useConfig"

/**
 * 地图接口 地图类型
 */
interface MapController {

}

type DefineProps = L.MapOptions & Partial<Config> & { use: MapType }

interface DefineExport {
    map: Ref<L.Map | undefined>
    tileLayers: Ref<L.TileLayer[]>
    gridLayers: Ref<L.GridLayer[]>
    geoJsons: Ref<L.GeoJSON[]>
    props: Ref<DefineProps>
    triggerProps: (options: Config) => void
}

function useMap(dom: Ref<string | HTMLElement>, props: DefineProps | Ref<DefineProps>): DefineExport {
    const _props = isRef(props) ? props : shallowRef(props)
    const _map = ref<L.Map>()
    const _tileLayers: Ref<L.TileLayer[]> = ref([])
    const _gridLayers: Ref<L.GridLayer[]> = ref([])
    const _geos: Ref<L.GeoJSON[]> = ref([])
    const _configGetter = useConfig()

    onMounted(() => {
        const _options = _props // FIXME 这里必须要强转嘛
        if (!_options) return
        const crs = useCrs(_options.value.use)
        const _config = _configGetter(_options.value.use)
        _map.value = L.map(dom.value, { ..._options.value, crs, center: _config.center })
        const layer = L.tileLayer(_config.urlTemplate, _config);
        layer.addTo(_map.value)
        _tileLayers.value.push(layer)
    })

    watch(_props, (options) => {
        if (!_map.value) return
        if (!options) return
        _map.value.options.crs = useCrs(options.use)
    })

    watch(_tileLayers, (layers) => {
        if (!_map.value) return
        if (layers.length < 1) return
        const { hasLayer: _has, addLayer: _add } = _map.value
        layers.forEach(l => !_has(l) && _add(l))
    })

    watch(_geos, (geos) => {
        const __map = _map.value
        if (!__map) return
        if (geos.length < 1) return
        geos.forEach(geo => {
            geo.addTo(__map)
        })
    })

    /**
     * 修改后激发props
     */
    function triggerProps(options: Config) {
        triggerRef(_props)
    }

    return { map: _map, props: _props, tileLayers: _tileLayers, gridLayers: _gridLayers, geoJsons: _geos, triggerProps }
}

export default useMap