<template>
  <z-paging>
    <template #top>
      <navbar/>
      <view class="bg-white px-30rpx py-26rpx">
        <view class="flex items-center h-86rpx px-28rpx bg-#F6F7F9 rounded-20rpx">
          <wd-input v-model="mapSearchKeyword" :no-border="true" :placeholder="t('common.placeholder.pleaseEnter')"
                    custom-class="!w-full !bg-transparent" placeholder-class="text-#9B9CA0 text-28rpx">
            <template #prefix>
              <view class="w-12rpx h-12rpx rounded-50% bg-#F97C34"></view>
            </template>
          </wd-input>
        </view>

        <view class="" @click="handleUseLocation">
          <view class="text-32rpx text-#333 font-500 my-30rpx">{{ t('common.useMyCurrentLocation') }}</view>
          <view class="text-28rpx text-#333 font-500 flex items-center pb-20rpx pl-24rpx">
            <view class="i-carbon:location-current text-32rpx mr-14rpx mt-4rpx"></view>
            {{ t('common.useCurrentLocation') }}
          </view>
        </view>
      </view>
    </template>
    <view :change:prop="mapRenderjs.searchPlace" :prop="querySearch" class="bg-#f5f5f5">
      <view class="px-22rpx py-20rpx">
        <template v-if="placesLength === 0">
          <view class="center py-100rpx">
            <image class="w-250rpx h-250rpx" src="@img/chef/100.png"></image>
          </view>
        </template>

        <template v-else>
          <view class="rounded-36rpx bg-white">
            <template v-for="(item,index) in logicStore.placesList" :key="index">
              <view :class="[index === logicStore.placesList.length - 1 ? '' : 'border-bottom']"
                    class="px-22rpx pb-30rpx pt-34rpx"
                    @click="handleClickLocation(item)">
                    <!-- <view >{{ item }}</view> -->
                <view class="text-#000 text-26rpx font-bold">{{ item.displayName }}</view>
                <view class="text-#9B9CA0 text-24rpx flex-center-sb">
                  <view>{{ item.formattedAddress }}</view>
                </view>
              </view>
            </template>
          </view>
        </template>
      </view>
      <view id="map" :change:prop="mapRenderjs.initMap" :prop="mapDataComputed" :user-location="userLocation"
            class="absolute left-0 bottom-0 w-0 h-0"></view>
    </view>
  </z-paging>
</template>
<script lang="ts" setup>
import Config from "@/config";
import {EventEnum} from "@/constant/enums";
import {useLogicStore} from "@/pages-user/store/logic";
import {useUserStore} from "@/store";

const {t, locale} = useI18n();
const userStore = useUserStore()
const logicStore = useLogicStore()

// 生命周期：清空地址列表
onMounted(() => {
  logicStore.clearPlacesList()
})

const placesLength = computed(() => {
  return logicStore.placesList.length;
});

const userLocation = computed(() => ({
  longitude: userStore.location.longitude,
  latitude: userStore.location.latitude
}));

watch(
    () => logicStore.searchLoading,
    (newValue) => {
      if (newValue) {
        uni.showLoading({
          title: 'Loading...',
          mask: true,
        });
      } else {
        uni.hideLoading();
      }
    },
    {immediate: true}
);

// 地图搜索关键词
const mapSearchKeyword = ref<string>('');
const querySearch = computed(() => {
  return {
    keyword: mapSearchKeyword.value,
  }
})

function handleClickLocation(item: any) {
  console.log('item', item)
  uni.$emit(EventEnum.CHOOSE_ADDRESS, item)
  uni.navigateBack()
}

// 使用当前位置
function handleUseLocation() {
  // 检查是否获取到了当前定位
  if (!userStore.location.longitude || !userStore.location.latitude) {
    // 尝试再次获取定位
    uni.getLocation({
      isHighAccuracy: true,
      type: 'gcj02',
      geocode: true,
      success: async (res) => {
        getCityName(res.latitude, res.longitude)
      },
      fail: (err) => {
        const settings = uni.getAppAuthorizeSetting()
        console.log(settings)
        if (settings.locationAuthorized === 'denied') {
          uni.showToast({
            title: t('common.prompt.please-authorize-location-information'),
            icon: 'none'
          })
          setTimeout(()=> {
            uni.openAppAuthorizeSetting()
          })
        }
      },
    })
  } else {
    uni.$emit(EventEnum.CHOOSE_ADDRESS, {
      displayName: userStore.location.location,
      formattedAddress: userStore.location.formattedAddress || '',
      location: {
        lng: userStore.location.longitude,
        lat: userStore.location.latitude
      }
    })
    uni.navigateBack()
  }
}

function getCityName(latitude: number, longitude: number) {
  const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&key=${Config.googleMapKey}&language=${locale.value === 'zh-Hans' ? 'zh-CN' : locale.value}`;

  uni.request({
    url,
    method: 'GET',
    timeout: 10000,
    success: (res: any) => {
      const results = res.data?.results || [];
      console.log('geocode results:', results);

      if (!results.length) {
        return handleFail();
      }

      const addr = results[0]; // 最高匹配度
      const components = addr.address_components || [];

      // 提取城市名的工具函数
      const pickAddress = (types: string[]) => {
        return components.find((item) => item.types.some((t) => types.includes(t)));
      };

      // 寻找城市名（多层兜底）
      let cityObj =
          pickAddress(["locality"]) ||
          pickAddress(["administrative_area_level_2"]) ||
          pickAddress(["administrative_area_level_1"]) ||
          pickAddress(["political"]);

      const cityName = cityObj?.long_name || null;

      // 从 Google 获取完整地址
      const formattedAddress = addr.formatted_address || cityName || "";

      console.log("city:", cityObj);
      console.log("formattedAddress:", formattedAddress);

      if (!cityName) {
        return handleFail();
      }

      // 存入 store
      userStore.location = {
        location: cityName,
        formattedAddress,
        longitude,
        latitude
      };

      // 发事件
      uni.$emit(EventEnum.CHOOSE_ADDRESS, {
        displayName: cityName,
        formattedAddress,
        location: { lng: longitude, lat: latitude }
      });

      uni.navigateBack();
    },

    fail: () => handleFail()
  });

  function handleFail() {
    uni.showToast({
      title: t('common.prompt.getLocationFailed'),
      icon: 'none'
    });
  }
}

const mapDataComputed = computed(() => {
  return {
    language: locale.value,
    lng: userStore.location.longitude || 174.7633,
    lat: userStore.location.latitude || -36.8485,
  }
})

// 监听来自 renderjs 的事件
onMounted(() => {
  // 监听搜索结果
  uni.$on('MAP_SEARCH_RESULT', (places: any) => {
    console.log(places, '接收到的搜索结果')
    if (places && places.length > 0) {
      // 解析实际返回的数据结构
      const parsedPlaces = places.map((placeArray: any) => {
        const placeData = placeArray[0]?.[0];
        if (!placeData) return null;

        const placeId = placeData[1];
        const formattedAddress = placeData[8] || '';
        const locationArray = placeData[11];
        const displayNameArray = placeData[27];

        return {
          id: placeId,
          displayName: displayNameArray?.[0] || formattedAddress,
          formattedAddress: formattedAddress,
          location: locationArray ? {
            lat: locationArray[0],
            lng: locationArray[1]
          } : null
        };
      }).filter(Boolean);

      console.log('解析后的地址列表', parsedPlaces);
      logicStore.setPlacesList(parsedPlaces);
    } else {
      logicStore.setPlacesList([]);
    }
  })

  // 监听地图未加载提示
  uni.$on('MAP_NOT_LOADED', () => {
    uni.showToast({
      title: 'Map is not loaded yet, please wait',
      icon: 'none'
    });
  })

  // 监听搜索超时提示
  uni.$on('MAP_SEARCH_TIMEOUT', () => {
    uni.showToast({
      title: 'Search timeout, please try again',
      icon: 'none'
    });
  })

  // 监听搜索加载状态
  uni.$on('MAP_SEARCH_LOADING', (isLoading: boolean) => {
    // logicStore.searchLoading = isLoading;
  })
})

onUnmounted(() => {
  // 清理事件监听
  uni.$off('MAP_SEARCH_RESULT')
  uni.$off('MAP_NOT_LOADED')
  uni.$off('MAP_SEARCH_TIMEOUT')
  uni.$off('MAP_SEARCH_LOADING')
})
</script>
<script lang="renderjs" module="mapRenderjs">
import {Loader} from "@googlemaps/js-api-loader"
import * as R from 'ramda'
import Config from '@/config'
import {debounce} from "throttle-debounce";

let map = null
let mapLoaded = false; // 地图加载完成标志
// @ts-ignore
export default {
  data() {
    return {
      region: "US",
      lan: 'en',
      google: null,
      canvas: null,
      center: null,
      dotLottie: null,
      marker: null,
      markerViewList: [],
      AdvancedMarkerElement: null,
      lng: -77.0365,
      lat: 38.8977,
      userLocation: {
        longitude: 0,
        latitude: 0
      }
    }
  },
  props: {
    userLocation: Object
  },
  mounted() {
    console.log('mounted mapRenderjs')
    mapLoaded = false; // 重置地图加载完成标志
    // !map&&this.initMap()
    this.searchPlace = debounce(200, this.searchPlace)
  },
  methods: {
    initMap({lng, lat, language}) {
      console.log('initMap', lng, lat)
      console.log('当前系统语言', language)

      this.lan = language === 'zh-Hans' ? 'zh-CN' : 'en'
      this.region = language === 'zh-Hans' ? 'CN' : 'US'
      this.lng = language === 'zh-Hans' ? 116.4074 : -77.0365
      this.lat = language === 'zh-Hans' ? 39.9042 : 38.8977
      console.log('当前系统语言', this.lan)
      console.log('当前系统区域', this.region)

      this.$nextTick(() => {
        const loader = new Loader({
          apiKey: Config.googleMapKey,
          version: "weekly",
          region: this.region, // 设置为美国
          language: this.lan,
        });


        loader.load().then(async (google) => {
          const {Map} = await google.maps.importLibrary("maps")
          this.google = google
          console.log('google', google.maps)
          // 地图相关配置
          // 指定自定义地图样式的 ID。
          // center: 地图初始中心点的经纬度（lat, lng）。
          // zoom: 地图初始缩放级别。
          // fullscreenControl: 是否显示全屏按钮（false 表示不显示）。
          // cameraControl: 是否显示相机控制（false 表示不显示）。
          // disableDefaultUI: 是否禁用所有默认 UI 控件（true 表示全部禁用）。
          // gestureHandling: 设置手势操作方式（"greedy" 表示允许所有手势操作）
          const mapOptions = {
            mapId: 'ff2268c265ce7a40',
            center: {
              lat: this.lat,
              lng: this.lng,
            },
            zoom: 12,
            fullscreenControl: false,
            cameraControl: false,
            disableDefaultUI: true,
            gestureHandling: "greedy",
          };

          map = new Map(document.getElementById("map"), mapOptions);
          mapLoaded = true; // 地图加载完成
        });
      })
    },
    async searchPlace({keyword}) {
      console.log('搜索关键词', keyword);
      if (!keyword) {
        uni.$emit('MAP_SEARCH_RESULT', [])
        return;
      }
      if (!mapLoaded) {
        console.log('地图未加载完成，无法搜索');
        uni.$emit('MAP_NOT_LOADED');
        return;
      }
      if (!map || !this.google) {
        return
      }
      uni.$emit('MAP_SEARCH_LOADING', true);
      let timeoutId;
      try {
        // 设置搜索超时
        const timeoutPromise = new Promise((_, reject) => {
          timeoutId = setTimeout(() => {
            uni.$emit('MAP_SEARCH_LOADING', false);
            reject(new Error('Search timeout'));
          }, 10000); // 10 秒超时
        });

        const {Place, SearchByTextRankPreference} = await this.google.maps.importLibrary("places");
        const request = {
          textQuery: keyword,
          fields: ['id', 'displayName', 'location', 'formattedAddress', 'addressComponents'],
          locationBias: {lat: this.lat, lng: this.lng},
          language: this.lan,
          maxResultCount: 20,
          region: this.region,
          rankPreference: SearchByTextRankPreference.RELEVANCE
        };

        const searchPromise = Place.searchByText(request);
        const {places} = await Promise.race([searchPromise, timeoutPromise]);
        console.log('地图搜索结果原始数据', places);
        
        // 将 Google Places API 返回的对象转换为可序列化的数组格式
        const serializedPlaces = places.map(place => {
          // 提取需要的字段并转换为普通对象
          return [[{
            1: place.id,
            8: place.formattedAddress || '',
            9: place.addressComponents || [],
            11: place.location ? [place.location.lat(), place.location.lng()] : null,
            27: place.displayName ? [
              typeof place.displayName === 'string' ? place.displayName : place.displayName.text,
              place.displayName.languageCode || this.lan
            ] : null
          }]];
        });
        
        console.log('序列化后的搜索结果', serializedPlaces);
        uni.$emit('MAP_SEARCH_RESULT', serializedPlaces);
      } catch (e) {
        console.log('搜索错误原因', e);
        if (e.message === 'Search timeout') {
          uni.$emit('MAP_SEARCH_TIMEOUT');
        }
        uni.$emit('MAP_SEARCH_RESULT', []);
      } finally {
        clearTimeout(timeoutId);
        uni.$emit('MAP_SEARCH_LOADING', false);
      }
    }
  },
}
</script>
<style>
page {
  background-color: #f5f5f5;
}
</style>
<style lang="scss" scoped>

</style>