<template>
    <q-scroll-area :style="{height: '100vh'}"
                   :thumb-style="scrollArea.thumbStyle"
                   :bar-style="scrollArea.barStyle">
    <div class="flex justify-start flex-wrap items-center">
        <div class="flex" v-if="!view.loginStatus">
            <q-input v-model="authModel.account"  class="mx-1" label="账号" dense clearable clear-icon="close" filled />
            <q-input v-model="authModel.password" class="mx-1" label="密码" type="password" dense clearable clear-icon="close" filled />
            <q-btn @click="login">登录</q-btn>
        </div>
        <div class="flex" v-else>
            <q-btn @click="logout">切换账号</q-btn>
        </div>

        <div class="flex items-center">
            <DateTimeSelector v-model="date" range></DateTimeSelector>
            <q-btn @click="search">查询</q-btn>
        </div>
    </div>
    <div class="flex justify-end flex-wrap items-center p-1">
        <q-toggle
                label="显示所有路径点"
                v-model="options.showMarker"
                color="primary"
                @update:model-value="toggleShowMarker"
                keep-color
        />

        <q-toggle
                label="仅使用高精度定位"
                v-model="options.useHighAccuracyLocation"
                color="primary"
                @update:model-value="toggleUseHighAccuracyLocation"
                keep-color
        />

        <q-toggle
                label="自动缩放"
                v-model="options.autoScaling"
                color="primary"
                @update:model-value="toggleAutoView"
                keep-color
        />

        <q-toggle
            label="卫星地图"
            v-model="layers.satellite.show"
            color="primary"
            @update:model-value="toggleSatellite"
            keep-color
        />

        <q-toggle
            label="路网"
            v-model="layers.roadNet.show"
            color="primary"
            @update:model-value="toggleRoadNet"
            keep-color
        />

        <q-toggle
            label="实时交通"
            v-model="layers.traffic.show"
            color="primary"
            @update:model-value="toggleTraffic"
            keep-color
        />

        <q-toggle
            label="纠偏路线"
            v-model="feature.showFixed"
            color="primary"
            @update:model-value="fixedLocation"
            keep-color
        />
    </div>
    <div id="container">
        <div class="absolute bg-amber-50 rounded-br z-max text-center" style="width: 300px" v-if="view.filterData.length > 0">
            <div class="flex">
                <div class="w-1/4">最高速度</div>
                <div>{{view.speed.max}} km/h</div>
            </div>
            <div class="flex">
                <div class="w-1/4">平均速度</div>
                <div>{{view.speed.avg}} km/h</div>
            </div>
        </div>

        <div class="absolute bg-amber-50 rounded-tl z-max text-left absolute-bottom-right pl-1.5" style="width: 350px" v-if="view.lines.length > 0">
            <div class="flex justify-between">
                <div>
                    路径数量: {{view.lines.length}}
                </div>
                <div>
                    <q-btn dense @click="changeAnimateRate">动画速率: {{view.animateRate}}</q-btn>
                </div>
            </div>

            <q-scroll-area :style="{height: view.lines.length * 22 > 250 ?'250px':view.lines.length * 22 + 'px'}" class="overflow-auto"
                            :thumb-style="scrollArea.thumbStyle"
                            :bar-style="scrollArea.barStyle">
<!--                <div v-for="(item,i) in view.lines" :key="i" >-->
<!--                    {{item[0].locationTime}} ~ {{item[item.length-1].locationTime}}-->
<!--                </div>-->
                <q-option-group v-model="options.showLines" @update:model-value="changeShowLines" :options="options.lines" type="checkbox" dense>
                    <template v-slot:label="opt">
                        <div class="row items-center">
                            <span>{{ opt.label }}</span>
                            <q-icon v-if="view.animating === opt.value"
                                    @click.stop="stop"
                                    name="fas fa-stop" color="negative" size="0.625em" class="q-ml-sm"></q-icon>
                            <q-icon v-else @click.stop="play(opt)" name="fas fa-play" color="teal" size="0.625em" class="q-ml-sm" />
                        </div>
                    </template>
                </q-option-group>
            </q-scroll-area>
        </div>
    </div>
    </q-scroll-area>
</template>
<script setup>
import AMapLoader from '@amap/amap-jsapi-loader';
import {onMounted, onUnmounted, reactive, ref} from "vue";
import DateTimeSelector from "matrix-middle-service-web/src/components/DateTimeSelector.vue";
import {useQuasar} from "quasar";
import moment from "moment";
import {locationRecord} from "matrix-middle-service-web/src/api/location/record";
import {getAvgSpeed, getMaxSpeed} from "matrix-middle-service-web/src/views/record/logic/speed";
import {
    checkLoginStatus,
    loginRequest,
    logoutHandler
} from "matrix-middle-service-web/src/views/record/logic/login";
import {fixedLocationHandler} from "matrix-middle-service-web/src/views/record/logic/location";
import {drawMarkers} from "matrix-middle-service-web/src/views/record/logic/markers";
import {drawLines} from "matrix-middle-service-web/src/views/record/logic/lines";
import {pauseAnimation, playAnimation, stopAnimation} from "matrix-middle-service-web/src/views/record/logic/play";
const $q = useQuasar();
const scrollArea = reactive({
    thumbStyle: {
        right: '4px',
        borderRadius: '5px',
        backgroundColor: '#027be3',
        width: '5px',
        opacity: "0.75"
    },
    barStyle: {
        right: '2px',
        borderRadius: '9px',
        backgroundColor: '#027be3',
        width: '9px',
        opacity: "0.2"
    }
})

function login(){
    loginRequest(authModel).finally(()=>{
        view.loginStatus = checkLoginStatus()
    })
}
function logout(){
    logoutHandler()
    view.loginStatus = checkLoginStatus()
}
const date = ref({
    from: moment().startOf('d').format("YYYY-MM-DD HH:mm:ss"),
    to: moment().format("YYYY-MM-DD HH:mm:ss"),
})
const feature = reactive({
    showFixed: false
})
function changeAnimateRate(){
    const animateRate = [1,2,5,10,20,30,60,120]
    let curIndex = animateRate.findIndex(item=>item === view.animateRate)
    let nextIndex = curIndex + 1
    view.animateRate = nextIndex >= animateRate.length ? animateRate[0] : animateRate[nextIndex]

    if(view.animating !== -1){
        let index = view.animating
        pauseAnimation(data)
        setTimeout(()=>{
            play(options.lines[index])
        },100)
    }
}
function stop(){
    stopAnimation(map,data,view)
}
function play(item){
    if(view.animating !== item.value){
        stop()
    }
    console.log(item,view.lines,data.polylines)
    options.showLines = [item.value]
    changeShowLines()
    view.animating = item.value
    playAnimation(map,data,view.lines[item.value],view.animateRate,view,item.value)
}
// 地图实例 和 数据不要交给 vue 管理 否则性能大打折扣 且 会有各种奇葩问题
let map = {}
const data = {
    data: [],
    polylines: [],
    fixedPolyline: {},
    labelsLayer: null,
    markers: [],
    tmpMarker: null,
    infoWindow: null,
    animateMarker: null,
}
const view = reactive({
    filterData: [],
    speed: {
        max: 0,
        avg: 0
    },
    lines: [],
    loginStatus: false,
    animateRate: 1,
    animating: -1
})
onMounted(()=>{
    view.loginStatus = checkLoginStatus()
})
onUnmounted(()=>{
    clearMap()
    map.remove(data.labelsLayer || {})
    map.remove(data.tmpMarker || {})
    map.remove(data.animateMarker || {})
    map.remove(data.infoWindow || {})
})
const layers = reactive({
    satellite: {
        inst: {},
        show: true,
    },
    roadNet: {
        inst: {},
        show: false,
    },
    traffic: {
        inst: {},
        show: false,
    }
})
const options = reactive({
    useHighAccuracyLocation: true,
    showMarker: false,
    autoScaling: true,
    lines: [],
    showLines: [],
})

const authModel = reactive({
    account: "",
    password: "",
})

function toggleAutoView(v){
    if(v){
        map.setFitView()
    }
}

function toggleShowMarker(v){
    if(v){
        options.autoScaling = false
    }
    redrawMap()
}

function redrawMap(){
    clearMap()
    drawMap()
}

function toggleUseHighAccuracyLocation(){
    redrawMap()
}

function toggleSatellite(){
    if (layers.satellite.show) {
        layers.satellite.inst.show()
    } else {
        layers.satellite.inst.hide()
    }
}
function toggleRoadNet() {
    if (layers.roadNet.show) {
        layers.roadNet.inst.show()
    } else {
        layers.roadNet.inst.hide()
    }
}
function toggleTraffic() {
    if (layers.traffic.show) {
        layers.traffic.inst.show()
    } else {
        layers.traffic.inst.hide()
    }
}

function changeShowLines(){
    console.log("options.showLines",options.showLines)
    console.log("view.lines",view.lines)

    let showLines = view.lines.filter((_,index)=>options.showLines.includes(index))
    drawMarkers(map,data,options,showLines)
    drawLines(map,data,showLines)

    view.speed.max = (getMaxSpeed(showLines.flat()) * 3.6).toFixed(2);
    view.speed.avg = (getAvgSpeed(showLines.flat()) * 3.6).toFixed(2);
}

AMapLoader.load({
    "key": "e01d7df3a4c3a1b8f06fa4544ddbbe9c",              // 申请好的Web端开发者Key，首次调用 load 时必填
    "version": "2.0",   // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
    "plugins": [
        "AMap.Scale",
        "AMap.HawkEye",
        "AMap.ToolBar",
        "AMap.ControlBar",
        "AMap.MoveAnimation"
    ],// 需要使用的的插件列表，如比例尺'AMap.Scale'等
    "lang": "zh_cn"
}).then((AMap) => {
    let scale = new AMap.Scale({
        visible: true
    })
    let toolBar = new AMap.ToolBar({
        visible: true,
        position: {
            top: '110px',
            right: '40px'
        }
    })
    let controlBar = new AMap.ControlBar({
        visible: true,
        position: {
            top: '10px',
            right: '10px'
        }
    })

    map = new AMap.Map('container',{
        viewMode:'3D', // 地图模式
        zoom: 14,
    });
    console.log("地图对象", map)
    map.on("moveend",()=>{
        let bounds = map.getBounds()
        data.markers.forEach(marker=>{
            if(bounds.contains(marker.getPosition())) {
                marker.show()
            } else {
                marker.hide()
            }
        })
    })

    map.addControl(scale)
    map.addControl(toolBar)
    map.addControl(controlBar)

    // 卫星
    layers.satellite.inst = new AMap.TileLayer.Satellite({
        visible: layers.satellite.show,
    })
    // 路网
    layers.roadNet.inst = new AMap.TileLayer.RoadNet({
        visible: layers.roadNet.show,
        index: 10
    })
    // 实时交通
    layers.traffic.inst = new AMap.TileLayer.Traffic({
        zIndex: 11,
        visible: layers.traffic.show,
    });

    map.addLayer(layers.satellite.inst)
    map.addLayer(layers.roadNet.inst)
    map.addLayer(layers.traffic.inst)

}).catch(e => {
    $q.notify({
        position: "top",
        color: 'negative',
        message: "地图组件初始化失败",
        icon: 'report_problem'
    })
    console.log(e);
})

function clearMap(){
    view.lines = []
    map.remove(data.polylines)
    map.remove(data.markers)
}


function drawMap(autoSelect=false){
    if(options.useHighAccuracyLocation){
        console.log("[仅使用高精度定位数据]")
        data.data = data.data.filter(item=>item.locationType === 1)
    }

    data.data = data.data.map(item=>{
        return {
            time: moment(item.locationTime),
            ...item,
        }
    })
    data.data.sort((a,b)=>{
        return a.time.isBefore(b.time)?-1:1
    })

    view.filterData =  data.data;

    view.speed.max = (getMaxSpeed(view.filterData) * 3.6).toFixed(2);
    view.speed.avg = (getAvgSpeed(view.filterData) * 3.6).toFixed(2);

    console.log("data", data.data)

    view.lines = []
    let prev = moment(0)
    for (let i = 0; i < data.data.length; i++) {
        let datum = data.data[i]

        if (prev.year() === datum.time.year() && prev.month() === datum.time.month() && prev.date() === datum.time.date() && datum.time.diff(prev,'m') <= 5 ) {
            prev = datum.time
        } else {
            prev = datum.time
            view.lines.push([])
        }
        view.lines[view.lines.length -1].push(datum)
    }
    view.lines = view.lines.reverse()
    options.lines = view.lines.map((item,index)=>{
        if(autoSelect){
            // 默认选中
            options.showLines.push(index)
        }

        return {
            label: `${item[0].locationTime} ~ ${item[item.length-1].locationTime}`,
            value: index,
        }
    })
    console.log("lines", view.lines)

    drawMarkers(map,data,options,view.lines.filter((_,index)=>options.showLines.includes(index)))
    drawLines(map,data,view.lines.filter((_,index)=>options.showLines.includes(index)))

    setTimeout(()=>{
        if(!options.autoScaling){
            return
        }
        if (data.polylines.length > 0) {
            map.setFitView()
        }
    })
    fixedLocation()
}

function search() {
    console.log(date.value)
    view.animating = -1
    let params = {
        startTime: !date.value.from ? undefined : moment(date.value.from).format("YYYY-MM-DD HH:mm:ss"),
        endTime: !date.value.to ? undefined : moment(date.value.to).format("YYYY-MM-DD HH:mm:ss"),
    }

    clearMap();
    locationRecord.list(params).then(resp => {
        if(resp.status !== 200){
            console.log(resp)
            let res = resp.data || {}
            $q.notify({
                position: "top",
                color: 'negative',
                message: res.data || res.msg || "请求失败",
                icon: 'report_problem'
            })
            throw new Error("请求失败")
        }
        return resp.data;
    }).then(res => {
        data.data = res.data || []
        options.showLines = []
        drawMap(true)
    })
}

function fixedLocation() {
    map.remove(data.fixedPolyline)

    if (!feature.showFixed) {
        return
    }
    fixedLocationHandler(map,data)
}
</script>

<style scoped lang="scss">
#container {
    width: 100%;
    height: 80vh;
}
</style>
