<template>
  <div class="mark-area">
    <div class="lianxi-pigai van-hairline--surround">
      <van-overlay class-name="image-overlay" :show="state.resizing">
        <div class="overlay-loading">
          <van-loading type="spinner" />
        </div>
      </van-overlay>
      <div class="lianxi-pigai-panel" id="lianxi-pigai"></div>
    </div>
  </div>
</template>

<script type="module" lang="ts">
// @ts-nocheck
import {defineComponent, getCurrentInstance, onMounted, onBeforeUnmount, reactive, ref, computed} from 'vue'
import {Button, Dialog, Field, Form, Overlay, Loading, ActionSheet} from 'vant'
import {ResourceNote, Comment, CommentRefTypes} from "~/types";
import '@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css';
import * as L from 'leaflet'
import {LatLng, LeafletMouseEvent, Marker} from 'leaflet'
import '@geoman-io/leaflet-geoman-free';
import {ImageHelper} from "~/utils";
import AudioRecord from '~/components/audio-record.vue';
import CommentsSheet from '~/components/comments-sheet.vue';
import { UpyunAccess } from '~/utils/upyun';

export default defineComponent({
  name: "tester-map",
  components: {
    [Dialog.name]: Dialog,
    [Form.name]: Form,
    [Field.name]: Field,
    [AudioRecord.name]: AudioRecord,
    [Button.name]: Button,
    [Overlay.name]: Overlay,
    [Loading.name]: Loading,
    [ActionSheet.name]: ActionSheet,
    [CommentsSheet.name]: CommentsSheet,
  },
  setup() {
    const marks = [] as ResourceNote[];
    let map_data = ref<L.Map | null>(null)

    let state = reactive({
      pausing: '',
      resizing: false,
      comment: null as (Comment | null),
      replying: false,
      drawing: false
    });


    let letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')

    const markers: Marker[] = [];
    const instance = getCurrentInstance();




    const pause = (data: ResourceNote) => {
      instance?.emit('pause', data);
      state.pausing = data.serial_no;
      state.replying = true;
      if (data.comments?.length === 0) {
        state.comment = data.comment || {
          ref_type: CommentRefTypes.Piyue,
          content: {
            text: '',
            audio_id: '',
            audio_url: '',
            video_id: '',
            video_url: ''
          }
        }
      }
    }


    const BaseWidth = 360;

    const getBounds = async (map: L.Map, url: string) => {
      let {width, height} = await ImageHelper.load(url);
      let scale = Math.round((width / BaseWidth) * 10) / 10;

      let southWest = map.unproject([0, height / scale], 1);
      let northEast = map.unproject([BaseWidth, 0], 1)
      return L.latLngBounds(southWest, northEast)
    }

    const icon = (letter: string) => {
      return L.divIcon({
        className: "serial-marker",
        html: `<span style="font-size: ${13 * (window.innerWidth / BaseWidth)}px">${letter}</span>`,
        iconSize: [18, 18]
      });
    }


    const draw = (map: L.Map, marks: ResourceNote[]) => {
      marks.forEach((data: ResourceNote) => {
        let {serial_no, lat_pos, resource_pos} = data;
        if (!lat_pos && resource_pos)  {
          lat_pos = resource_pos.vals.find(x => !!x.lat_pos)?.lat_pos;
        }
        let marker = L.marker(lat_pos as LatLng, {icon: icon(serial_no)}).addTo(map)
            .on('click', () => pause(data))
        markers.push(marker);
      })
    }

    onMounted(async () => {
      let signedUrl = await UpyunAccess.getSign("https://upyun.alchemy-studio.cn/music-room/006c5fd0-430d-41cf-b529-8295d6264932.jpeg");
      let zoom = window.innerWidth / BaseWidth;
      let map = L.map('lianxi-pigai', {
        center: [0, 0], zoom, zoomControl: false, zoomDelta: 0.1
      })
      map_data.value = map;
      let bounds = await getBounds(map, signedUrl as string);
      L.imageOverlay(signedUrl as string, bounds).addTo(map);
      map.invalidateSize(true);
      map.setMaxBounds(bounds)
      draw(map, marks)

      map.on("click", (e: LeafletMouseEvent) => {
        if (state.drawing) {
          return;
        }
        let lastLetterIndex = marks.reduce((a: number, c: ResourceNote) => Math.max(a, letters.indexOf(c.serial_no)), -1);
        let letter = letters[lastLetterIndex + 1];
        let data: ResourceNote = {
          serial_no: letter, comments: [] as Comment[], lat_pos: e.latlng
        };
        let marker = L.marker(e.latlng, {icon: icon(letter)}).addTo(map)
            .on("click", () => pause(data));
        markers.push(marker);
        marks.push(data)
        pause(data)
      })

      window.addEventListener('resize', async () => {
        state.resizing = true;
        map.setZoom(window.innerWidth / BaseWidth)
        map.invalidateSize(true);
        map.fitBounds(bounds)
        markers.forEach(m => m.remove())
        markers.splice(0, markers.length)
        draw(map, marks)
        setTimeout(() => {
          state.resizing = false;
        }, 100)

      })

      map.pm.addControls({
        position: "topleft",

      })

      map.pm.setLang('zh')

      map.on("pm:drawstart", e => {
        state.drawing = true;
      })

      map.on("pm:drawend", e => {
        state.drawing = false;
      })
      map.on("pm:create", e => {
        console.log('create...', e)
      })
    });

    onBeforeUnmount(() => {
      if (map_data.value) {
        (map_data.value as L.Map).remove();
      }
    })

    return {state}
  },
});
</script>

<style scoped lang="less">

.leaflet-container {
 font-size: 0.24rem!important;
}
.mark-area {
  width: 94%;
  margin: auto;
  height: 49%;

  .lianxi-pigai {
    width: 100%;
    height: 100%;
    position: relative;

    .image-overlay {
      width: 100%;
      height: 100%;
      position: absolute;

      .overlay-loading {
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }

    .lianxi-pigai-panel {
      width: 100%;
      height: 100%;
      background: #FFFFFF;

      :deep(.serial-marker) {
        color: red;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        background: transparent;
        border: none;
      }
    }
  }
}

</style>
