<template>
  <div class="lofty-detail-map">
    <div class="lofty-detail-title">NEARBY SCHOOLS</div>
    <div class="lofty-school-map-container">
      <map-here v-if="renderMap"
                :style="{height: isMobile ? '380px' : '100%'}"
                :config="mapConfig"
                @init="initMap"
      >
        <div v-if="showMarker" class="marker-box icon">
          <marker-icon :data="location" :map="map">
            <img :src="LocationIcon" width="40" alt="location">
          </marker-icon>
          <marker-icon v-for="item in showSchoolMarkers" class="school" v-model:active="activeMarker"
                       :key="item.key" :map="map" :data="item" :events="events">
          </marker-icon>
        </div>
      </map-here>
      <school-panel v-model="activeSchool"  class="school-area"
                    @mouseenter="fitPolygon = true"
                    @changeSchoolType="schoolType = $event"
                    :showContent="showSchool"
                    :style="{width: showSchool ? (isMobile? '100%':'400px'): '0', height: showSchool ? (isMobile ? 'fit-content' : '460px'): '0'}"
                    :id="id"></school-panel>
      <div v-show="!isMobile && showSchool" @click="showSchool = false" class="hide-school-button">
        <span class="lofty_iconfont lofty-icon-arrow_01_right" :class="{reverse: showSchool}"></span>
        <span style="margin-left: -7px" class="lofty_iconfont lofty-icon-arrow_01_right" :class="{reverse: showSchool}"></span>
      </div>
      <div v-show="!isMobile && !showSchool" @click="showSchool = true" class="show-school-button">
        <span style="margin-right: 10px">SCHOOLS</span>
        <span class="lofty_iconfont lofty-icon-arrow_01_right"></span>
        <span style="margin-left: -7px" class="lofty_iconfont lofty-icon-arrow_01_right"></span>
      </div>
    </div>
    <div class="school-disclaimer">
      School data provided by
      <a class='disclaimer' target="_blank" href='https://www.greatschools.org' rel="noopener">GreatSchools</a>
      for your convenience. Please contact schools directly for enrollment eligibility.
    </div>
  </div>
</template>

<script setup>
import http from '@/api';
import MapHere from '@/components/map-here/index.vue';
import MarkerIcon from "@/components/map-here/markers/icon.vue";
import SchoolPanel from "./components/schoolPanel.vue"
import store from './store.js'
import { isMobile } from "@/util/index.js";
import LocationIcon from "@/static/location.svg";

const props = defineProps({ id: String })
const { info, location, onLoad, schoolMarkers } = store[props.id]
const showSchool = ref(true)
const schoolType = ref('')
const showSchoolMarkers = computed(()=>{
  if(schoolType.value) {
    return schoolMarkers.value.filter(item => item.group === schoolType.value)
  }
  return schoolMarkers.value
})
const map = ref(null)
const mapConfig = {
  zoom: 14,
  center: {
    lat: 0,
    lng: 0,
  }
}

const activeSchool = ref('')
const events = {
  mouseEnter: function (data) {
    activeSchool.value = data.id
    fitPolygon.value = false
  }
}
const activeMarker = ref('')
watch(activeSchool, (val)=>{
  const school = schoolMarkers.value.find(s => s.id === val)
  activeMarker.value = school.key
  setTimeout(()=>{
    getGeometry(school.hjId)
  }, 300)
})

const showMarker = ref(false)
function initMap(mapView) {
  map.value = mapView
  setTimeout(()=>{
    showMarker.value = true
  }, 3000)
}

let polygonList = []
function clearPolygon() {
  polygonList.forEach(polygon => {
    map.value.removeObject(polygon);
  })
  polygonList = []
}
// 绘制多边形区域
const geometryMap = {}
async function getGeometry(hjId) {
  clearPolygon();
  if (geometryMap[hjId]) {
    let data = geometryMap[hjId]
    drawPolygon(data)
  } else {
    const res = await http.get(`search/hj-data/v1/boundary?type=school&hjId=${hjId}`);
    geometryMap[hjId] = res.data || []
    drawPolygon(res.data || [])
  }
}
const fitPolygon = ref(false)
function drawPolygon(list) {
  list.forEach(boundaryData => {
    boundaryData.forEach(line => {
      const lineString = new window.H.geo.LineString();
      line.forEach(point => {
        lineString.pushPoint(point);
      })
      polygonList.push(new window.H.map.Polygon(new window.H.geo.Polygon(lineString), {
        style: {
          strokeColor: getComputedStyle(document.documentElement).getPropertyValue('--lofty-map-polygon-borderColor') || 'rgb(25, 25, 25)',
          fillColor: getComputedStyle(document.documentElement).getPropertyValue('--lofty-map-polygon-bgColor') || 'rgba(25, 25, 25, 0.2)',
          lineWidth: 2
        }
      }))
    })
  })
  polygonList.forEach(obj => {
    map.value.addObject(obj);
  })
  if(polygonList.length > 0 && fitPolygon.value) {
    let minLat = Infinity, minLng = Infinity, maxLat = -Infinity, maxLng = -Infinity;
    polygonList.forEach(polygon => {
      const boundingBox = polygon.getGeometry().getBoundingBox();
      minLat = Math.min(minLat, boundingBox.getBottom());
      maxLat = Math.max(maxLat, boundingBox.getTop());
      minLng = Math.min(minLng, boundingBox.getLeft());
      maxLng = Math.max(maxLng, boundingBox.getRight());
    });
    
    // 获取当前zoom，限制变化幅度
    const currentZoom = map.value.getZoom();
    const bounds = new window.H.geo.Rect(maxLat, minLng, minLat, maxLng);
    
    // 先不使用动画计算合适的zoom
    map.value.getViewModel().setLookAtData({ bounds }, false);
    const calculatedZoom = map.value.getZoom();
    
    // 限制zoom变化幅度，最大允许变化3级
    const maxZoomChange = 3;
    const minZoom = Math.max(currentZoom - maxZoomChange, 4);
    const maxZoom = Math.min(currentZoom + maxZoomChange, 20);
    const finalZoom = Math.max(minZoom, Math.min(calculatedZoom, maxZoom));
    
    map.value.getViewModel().setLookAtData({
      bounds,
      zoom: finalZoom
    }, true);
  }
}
const renderMap = ref(false)
onMounted(()=>{
  onLoad.then(()=> {
    mapConfig.center.lat = +info.value.latitude
    mapConfig.center.lng = +info.value.longitude
    renderMap.value = true
  })
})

</script>
<style lang="scss">
.lofty-detail-map {
  .lofty-school-map-container {
    width: 100%;
    height: 500px;
    position: relative;
    margin-top: 40px;
    @include media-600 {
      height: fit-content;
      margin-top: 20px;
    }
  }
  .school-area {
    position: absolute;
    left: 20px;
    top: 20px;
    overflow-y: auto;
    transition: all .3s;
    z-index: 11;
    @include media-600 {
      position: static;
      height: fit-content;
    }
  }
  .hide-school-button {
    position: absolute;
    width: 50px;
    height: 50px;
    left: 419px;
    top: 210px;
    background: #fff;
    z-index: 10;
    cursor: pointer;
    box-shadow: 2px 2px 10px 0 rgba(0, 10, 30, 0.1);
    border-radius: 0 5px 5px 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all .3s;
    .lofty_iconfont {
      font-size: 16px;
    }
    .reverse {
      transform: rotate(180deg);
    }
  }
  .show-school-button {
    position: absolute;
    width: 140px;
    height: 50px;
    left: 20px;
    top: 20px;
    background: #fff;
    font-size: 14px;
    color: rgb(80, 80, 80);
    z-index: 10;
    cursor: pointer;
    box-shadow: 2px 2px 10px 0 rgba(0, 10, 30, 0.1);
    border-radius: 5px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all .3s;
    &:hover::after {
      content: '';
      width: 100%;
      height: 100%;
      position: absolute;
      left: 0;
      top: 0;
      background-color: rgba(17, 17, 17, 0.05);
    }
  }
  .school-disclaimer {
    font-size: 12px;
    font-family: var(--lofty-font-regular);
    margin-top: 20px;
    color: rgba(168, 168, 168, 1);
    a.disclaimer {
      text-decoration: underline;
      color: rgba(76, 132, 255, 1);
    }
  }
}
</style>
<style lang="scss">
.lofty-detail-map {
  .map-type.map-tool {
    left: unset !important;
    bottom: unset!important;
    right: 20px;
    top: 20px;
    width: 40px;
    height: 40px;
    img {
      position: absolute;
      right: 0;
    }
    &:hover p {
      left: -40px;
    }
  }
}
.site-map.standard .marker-icon .marker-pop{
  color: rgba(25, 25, 25, 1);
  background-color: #fff;
}
.site-map.standard .marker-icon .marker-pop .pointer {
  border-top-color: #fff;
}
</style>