<template>
  <v-dialog v-model="props.isLatlngModal" persistent width="50rem">
    <div class="v-common-dialog-wrapper custom-dialog">
      <div class="modal-tit">
        <strong>지도로 검색</strong>
        <button class="btn-close" @click="$emit('closeModal')"></button>
      </div>
      <div class="v-common-dialog-content">
        <div class="map-area" id="map2"></div>
        <div class="map-address">
          <strong>주소 :</strong>
          <p class="color-blue2" v-if="!objSetLatlng.address">
            ※ 마우스로 위치를 지정하세요
          </p>
          <p style="" v-else>{{ objSetLatlng.address }}</p>
        </div>
      </div>
      <div class="btn-wrap">
        <v-btn class="custom-btn btn-white mini" @click="$emit('closeModal')">
          취소
        </v-btn>
        <v-btn class="custom-btn btn-blue mini" @click="fnSaveLatlng"> 저장 </v-btn>
      </div>
    </div>
  </v-dialog>
</template>

<script setup>
/***********************
 *     import
 ************************/
import { useI18n } from "vue-i18n";
import useUtil from "@/composables/useUtil";
import useValid from "@/composables/useValid";
import useEnumCode from "@/composables/useEnumCode";
/***********************
 *     plugins inject
 ************************/
const { $toast, $log, $dayjs, $eventBus } = useNuxtApp();

// props
const props = defineProps({
  isLatlngModal: Boolean,
  address: String,
  centerPosition: Object,
});
// 참조가능 데이터 설정
defineExpose({
  fnInit,
  fnReset,
});
// 발신 이벤트 선언
const emit = defineEmits(["closeModal", "setLatlng"]);
const i18n = useI18n();

/***********************
 *     data & created
 ************************/
const map = ref(null); // 카카오 맵 객체
const marker = ref(null); // 카카오맵 마커(핀) 객체
const geocoder = ref(null);
// 주소위치설정값
const objSetLatlng = ref({
  lat: "", // 위도
  lng: "", // 경도
  address: "", // 주소
  regionalCode: "", // 지역명 (코드로 변환필요)
});
const sidoCode = ref([]);
watchEffect(() => {
  fnGetEnumCode(useLangStore().getLang);
});
/**
 * ENUM 업데이트
 * @param lang
 */
function fnGetEnumCode(lang) {
  let objEnum = useEnumCode.getEnumCode(lang);
  // ...objEnum.sidoCode
  sidoCode.value = _cloneDeep(objEnum.sidoCode);
}
/***********************
 *     Methods
 ************************/
function fnInit() {
  if (!useUtil.isNull(props.address)) {
    objSetLatlng.value.address = _cloneDeep(props.address);
  }
  nextTick().then(() => {
    if (window.kakao && window.kakao.maps) {
      loadMap();
    } else {
      loadScript();
    }
  });
}
function fnReset() {
  objSetLatlng.value = {
    lat: "",
    lng: "",
    address: "",
  };
}
/**
 * kakao 스크립트 로드
 */
function loadScript() {
  const script = document.createElement("script");
  script.async = true;
  script.onload = () => {
    window.kakao.maps.load(loadMap);
  };
  script.src = `//dapi.kakao.com/v2/maps/sdk.js?autoload=false&libraries=services,clusterer,drawing&appkey=${
    import.meta.env.VITE_APP_KAKAO_APP_KEY
  }`;
  document.head.appendChild(script);
}
/**
 * kakao 지도 로드
 */
async function loadMap() {
  const mapContainer = document.getElementById("map2");
  let mapOption = {
    center: new kakao.maps.LatLng(props.centerPosition.lat, props.centerPosition.lng), // 지도의 중심좌표
    level: 3, // 지도의 확대 레벨
  };
  map.value = new kakao.maps.Map(mapContainer, mapOption);

  // 주소-좌표 변환 객체를 생성합니다
  geocoder.value = new kakao.maps.services.Geocoder();

  // 지도를 클릭한 위치에 표출할 마커입니다
  marker.value = new kakao.maps.Marker({
    // 지도 중심좌표에 마커를 생성합니다
    position: map.value.getCenter(),
  });
  // 지도에 마커를 표시합니다
  marker.value.setMap(map.value);

  let zoomControl = new kakao.maps.ZoomControl();
  // map.value.addControl(zoomControl, kakao.maps.ControlPosition.BOTTOMRIGHT)
  fnSetEventListener(); // 지도 이벤트 등록
}
/**
 * 지도 클릭 이벤트
 */
function fnSetEventListener() {
  kakao.maps.event.addListener(map.value, "click", function (mouseEvent) {
    // 클릭한 위도, 경도 정보
    let latlng = mouseEvent.latLng;
    marker.value.setPosition(latlng);
    // 위/경도값으로 주소 조회
    fnSearchAddrDetail(latlng);
    // 위치값 설정
    objSetLatlng.value.lat = latlng.getLat();
    objSetLatlng.value.lng = latlng.getLng();
  });
}
/**
 * 위/경도 값으로 주소 구하기
 */
function fnSearchAddrDetail(coords) {
  return new Promise((resolve, reject) => {
    fnSearchDetailAddrFromCoords(coords, function (result, status) {
      if (status === kakao.maps.services.Status.OK) {
        var detailAddr = !!result[0].road_address
          ? result[0].road_address.address_name
          : "";
        detailAddr += `(${result[0].address.address_name})`;

        objSetLatlng.value.address = detailAddr;
        objSetLatlng.value.regionalCode = fnGetRegionCode(
          result[0].address.region_1depth_name
        );
        resolve();
      } else {
        reject(status);
      }
    });
  });
}
function fnSearchDetailAddrFromCoords(coords, callback) {
  geocoder.value.coord2Address(coords.getLng(), coords.getLat(), callback);
}
// 지역코드 변환
function fnGetRegionCode(regionName) {
  let regionCode = "";
  sidoCode.value.forEach((item) => {
    if (item.title.includes(regionName)) {
      regionCode = item.value;
    }
  });

  return regionCode;
}
/**
 * 저장
 */
async function fnSaveLatlng() {
  if (useUtil.isNull(objSetLatlng.value.lat) || useUtil.isNull(objSetLatlng.value.lng)) {
    let latlng = new kakao.maps.LatLng(
      props.centerPosition.lat,
      props.centerPosition.lng
    );
    try {
      await fnSearchAddrDetail(latlng);
      objSetLatlng.value.lat = latlng.getLat();
      objSetLatlng.value.lng = latlng.getLng();
    } catch (error) {
      $log.debug("[주소위치설정 실패][error]", JSON.stringify(error));
    }
  }
  let params = {
    lat: objSetLatlng.value.lat.toFixed(8),
    lng: objSetLatlng.value.lng.toFixed(8),
    address: objSetLatlng.value.address,
    regionalCode: objSetLatlng.value.regionalCode,
  };

  emit("setLatlng", params);
}
</script>
