<template>
  <div 
    class="light-map"
    :class="{ 
      'full': full ,
      'small': small
    }" 
  >
    <slot />
    <map 
      id="prevMap"
      map-id="prevMap"
      class="light-map-map"
      :enable-poi="false"
      :show-location="true"
      :scale="12"
      :longitude="lonlat?.longitude"
      :latitude="lonlat?.latitude"
      @markertap="onMarkerTap" 
    />

    <FlexCol v-if="isEmptyRegion" 
      gap="gap.xl" 
      position="absolute" 
      inset="0" 
      padding="padding.md"
      center 
    > 
      <FlexCol center gap="gap.xl" padding="padding.md" backgroundColor="white" radius="radius.md">
        <Text fontConfig="importantTitle" textAlign="center">您选择的地区还未开通亮乡源数据，可联系客服开通</Text>
        <button open-type="contact" class="remove-button-style">
          <FlexCol padding="space.md" radius="radius.lg" center backgroundColor="button">
            <Text fontConfig="primaryTitle">联系客服</Text>
          </FlexCol>
        </button>
      </FlexCol>
    </FlexCol>
    <FlexCol v-if="mapLoader.error.value" 
      gap="gap.md" 
      position="absolute" 
      inset="0"
      center 
    > 
      <FlexCol center gap="gap.md" padding="padding.md" backgroundColor="white" radius="radius.md">
        <Icon name="warning" size="44" color="red" />
        <Text textAlign="center" :text="mapLoader.error.value" />
      </FlexCol>
    </FlexCol>
    <FlexCol v-else-if="mapLoader.status.value === 'loading'" 
      gap="gap.md" 
      position="absolute" 
      inset="0" 
      center
    > 
      <ActivityIndicator :size="64" />
    </FlexCol>

    <NButton 
      :innerStyle="{
        position: 'absolute',
        bottom: '20rpx',
        left: '20rpx',
        zIndex: 100,
        backgroundColor: '#ffffff',
      }"
      icon="search" 
      @click="showSearch" 
    />
    <SimpleDropDownPicker 
      v-if="!isEmptyRegion"
      class="light-map-region-picker" 
      :modelValue="selectedRegion" 
      @update:modelValue="onSelectedRegion"
      :columns="regionLoader.content.value" 
    />
    <NButton 
      :innerStyle="{
        position: 'absolute',
        bottom: '20rpx',
        right: '20rpx',
        zIndex: 100,
        backgroundColor: '#ffffff',
      }"
      text="定位"
      icon="navigation" 
      @click="emit('getCurrentLonlat')" 
    />
    <Dialog 
      v-model:show="searchDialogShow" 
      title="搜索村社"
      showCancel
      :maskClosable="false"
      :onConfirm="searchConfirm"
    >
      <template #content>
        <Field v-model="searchKeyword" placeholder="请输入村社名称进行搜索" />
      </template>
    </Dialog>
  </div>
</template>

<script setup lang="ts">
import { computed, getCurrentInstance, onMounted, ref, watch } from 'vue';
import { navTo } from '@/components/utils/PageAction';
import { waitTimeOut } from '@imengyu/imengyu-utils';
import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
import LightVillageApi, { VillageListItem } from '@/api/light/LightVillageApi';
import AppCofig, { isDev } from '@/common/config/AppCofig';
import SimpleDropDownPicker from '@/common/components/SimpleDropDownPicker.vue';
import NButton from '@/components/basic/Button.vue';
import FlexCol from '@/components/layout/FlexCol.vue';
import Text from '@/components/basic/Text.vue';
import CommonContent from '@/api/CommonContent';
import Icon from '@/components/basic/Icon.vue';
import ActivityIndicator from '@/components/basic/ActivityIndicator.vue';
import type { MapMarker } from '@/types/Map';
import MapApi from '@/api/map/MapApi';
import Dialog from '@/components/dialog/Dialog.vue';
import Field from '@/components/form/Field.vue';
import { toast } from '@/components/dialog/CommonRoot';

const instance = getCurrentInstance();
const mapCtx = uni.createMapContext('prevMap', instance);

const selectedRegion = ref<number>();
const nextNeedAutoFocus = ref(false);
const villageData = new Map<number, VillageListItem>();

const ready = ref(false);
const hasResItems = ref(false);

const searchDialogShow = ref(false);
const searchKeyword = ref('');

const emit = defineEmits([
  'getCurrentLonlat',
  'update:isLightMode', 
  'update:lonlat',
  'selectVillage',
  'regionChanged',
  'lightVillage',
]);

const props = defineProps<{
  lonlat?: { longitude: number, latitude: number } | undefined;
  city?: string;
  isLightMode?: boolean;
  small?: boolean;
  full?: boolean;
}>();

const regionLoader = useSimpleDataLoader(async () => {
  if (!props.city)
    return [];
  return (await CommonContent.searchRegion(props.city)).map(p => ({
    id: p.id,
    name: p.title,
  }));
}, false);
const mapLoader = useSimpleDataLoader<MapMarker[]>(async () => {
  mapCtx.removeMarkers({
    markerIds: Array.from(villageData.keys()),
  })
  villageData.clear();
  if (!selectedRegion.value)
    return [];
  await waitTimeOut(200);
  const res = (await LightVillageApi.getVillageList({
    region: selectedRegion.value,
    keyword: searchKeyword.value.trim() || undefined,
    page: 1,
    pageSize: 1000
  })).list;
  hasResItems.value = res.length > 0;
  const list = res.map((p, i) => {
    villageData.set(p.id, p);
    const maker : MapMarker = {
      id: p.id ?? i,
      title: p.name,
      longitude: Number(p.longitude),
      latitude: Number(p.latitude),
      width: 30,
      height: 30,
      iconPath: '',
      joinCluster: true,
      callout: {
        display: 'ALWAYS',
        content: p.name,
        color: '#000000',
        fontSize: 12,
        padding: 5,
        bgColor: '#ffffff',
        borderRadius: 5,
      },
    }

    if (p.isLight) {
      if (p.lightValue >= 1) {
        maker.iconPath = `https://mncdn.wenlvti.net/app_static/xiangyuan/images/map/Light3.png`;
      } else if (p.lightValue >= 0.5) {
        maker.iconPath = `https://mncdn.wenlvti.net/app_static/xiangyuan/images/map/Light2.png`;
      } else if (p.lightValue >= 0.25) {
        maker.iconPath = `https://mncdn.wenlvti.net/app_static/xiangyuan/images/map/Light1.png`;
      } else {
        maker.iconPath = `https://mncdn.wenlvti.net/app_static/xiangyuan/images/map/Light1.png`;
      }
      const size = Math.floor(35 +(p.lightValue) * 10);
      maker.width = size;
      maker.height = size;
      
    } else {
      maker.width = 35;
      maker.height = 35;
      maker.iconPath = `https://mncdn.wenlvti.net/app_static/xiangyuan/images/map/LightUnLight.png`;
    }

    return maker as MapMarker;
  }).filter(p => 
    p.longitude && p.latitude 
    && !isNaN(p.longitude) && !isNaN(p.latitude)
    && p.longitude > -180 && p.longitude < 180
    && p.latitude > -90 && p.latitude < 90
  );

  mapCtx.addMarkers({
    clear: true,
    markers: list, 
  })

  if (nextNeedAutoFocus.value) {
    
    if (res.length > 0) {
      setTimeout(() => {
        mapCtx.includePoints({
          points: list.map(p => {
            if (!p.longitude || !p.latitude) {
              p.longitude = AppCofig.defaultLonLat[0];
              p.latitude = AppCofig.defaultLonLat[1];
            }
            return {
              latitude: p.latitude,
              longitude: p.longitude,
            }
          }),
          padding: [20, 20, 20, 20],
        });
      }, 200);
    } else {
      try {
        const currentRegionName = regionLoader.content.value?.find(p => p.id == selectedRegion.value)?.name;
        if (currentRegionName) {
          const res = (await MapApi.simpleGetRegion(currentRegionName)).requireData();
          mapCtx.moveToLocation({
            latitude: Number(res.center.split(',')[1]),
            longitude: Number(res.center.split(',')[0]),
          });
        }
      } catch (error) {
        console.error(error);
      }
    }
  }

  ready.value = true;
  return list;
}, false, false);

const isEmptyRegion = computed(() => {
  return !hasResItems.value && ready.value;
});

function onMarkerTap(e: any) {
  if (props.isLightMode) {
    emit('update:isLightMode', false);
    const village = villageData.get(e.markerId);
    if (village) {
      emit('lightVillage', village);
      return;
    }
  }
  const village = villageData.get(e.markerId);
  if (village) {
    emit('selectVillage', village);
  }
}
function onSelectedRegion(regionId: number) {
  selectedRegion.value = regionId;
  nextNeedAutoFocus.value = true;
  mapLoader.reload();
  emit('regionChanged', regionId);
}
function setCurrentRegion(regionName: string) {
  const region = regionLoader.content.value?.find(p => p.name == regionName)?.id || 
  regionLoader.content.value?.[0]?.id || undefined;
  if (region === selectedRegion.value)
    return;
  selectedRegion.value = region;
  emit('regionChanged', selectedRegion.value);
  mapLoader.reload();
}

function showSearch() {
  searchDialogShow.value = true;
  searchKeyword.value = '';
}
async function searchConfirm() {
  searchDialogShow.value = false;
  if (searchKeyword.value.trim() === '') {
    toast('请输入搜索关键词');
    return;
  }
  await mapLoader.reload();
}

watch(() => props.city, async (newVal) => {
  await regionLoader.reload();
  setCurrentRegion(newVal || '');
}, { immediate: true });

onMounted(async () => {
  mapCtx.initMarkerCluster({
    enableDefaultStyle: false,
    zoomOnClick: true,
    gridSize: 40,
  });
  mapCtx.on('markerClusterCreate', (e: { clusters: any[] }) => {
    const customClusters = e.clusters.map((cluster) => {
      const { center, clusterId, markerIds } = cluster;
      return {
        ...center,
        width: 0,
        height: 0,
        clusterId,
        label: {
          content: markerIds.length.toString(), // 聚合点的数量
          fontSize: 16,
          color: '#fff',
          width: 30,
          height: 30,
          bgColor: '#8bb346', // 背景颜色
          borderRadius: 25,
          textAlign: 'center',
          anchorX: -10,
          anchorY: -35,
        },
      };
    });
    mapCtx.addMarkers({
      markers: customClusters,
      clear: false,
    });
  });
});
</script>

<style lang="scss">
.light-map {
  position: relative;
  width: 100%;
  height: 600rpx;
  border-radius: 30rpx;
  overflow: hidden;
  border: 1px solid #d45652;

  &.full {
    height: 100vh;
    border-radius: 0;

    .light-map-map {
      height: 100vh;
    }
  }
  &.small {
    height: 500rpx;
    border-radius: 20rpx;
    .light-map-map {
      height: 500rpx;
    }
  }

  .light-map-map {
    width: 100%;
    height: 600rpx;
  }

  .light-map-region-picker {
    position: absolute;
    bottom: 20rpx;
    left: 50%;
    transform: translateX(-50%);
    z-index: 100;
  }

  .light-map-address {
    position: absolute;
    bottom: 20rpx;
    right: 20rpx;
    z-index: 100;
  }
}
</style>