import { yupResolver } from '@hookform/resolvers/yup';
import { useRouter } from 'next/router';
import { useEffect, useState, useMemo } from 'react';
import * as Yup from 'yup';
import cityApi from '../api/cityApi';
import { Controller, useForm } from 'react-hook-form';
import districtApi from '../api/districtApi';
import subDistrictApi from '../api/subDistrictApi';
import addressApi from '@/lib/address/api/addressApi';
import editAddressApi from '../api/editAddressApi';
import editPartnerApi from '../api/editPartnerApi';
import HookFormSelect from '@/core/components/elements/Select/HookFormSelect';
import { toast } from 'react-hot-toast';
import Menu from '@/lib/auth/components/Menu';
import useAuth from '@/core/hooks/useAuth';
import odooApi from '@/core/api/odooApi';
import stateApi from '../api/stateApi';
import { MapPinIcon } from 'lucide-react';
import { Button } from '@chakra-ui/react';
import { useMaps } from '../../maps/stores/useMaps';
import PinPointMap from '../../maps/components/PinPointMap';
import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
import { data } from 'autoprefixer';
const EditAddress = ({ id, defaultValues }) => {
const auth = useAuth();
const router = useRouter();
const {
register,
formState: { errors },
handleSubmit,
watch,
setValue,
getValues,
control,
} = useForm({
resolver: yupResolver(validationSchema),
defaultValues,
});
const [states, setStates] = useState([]);
const [cities, setCities] = useState([]);
const [districts, setDistricts] = useState([]);
const [subDistricts, setSubDistricts] = useState([]);
const [tempAddress, setTempAddress] = useState(getValues('addressMap'));
const resetPin = useMaps((state) => state.resetPin);
const setSelectedPosition = useMaps((state) => state.setSelectedPosition);
const setAddressMaps = useMaps((state) => state.setAddressMaps);
const setDetailAddress = useMaps((state) => state.setDetailAddress);
const [showValidationPopup, setShowValidationPopup] = useState(false);
const [popupMessage, setPopupMessage] = useState("");
const [selectedCityName, setSelectedCityName] = useState("");
const [normalizedDistrict, setNormalizedDistrict] = useState("");
const {
addressMaps,
selectedPosition,
detailAddress,
pinedMaps,
setPinedMaps,
getDefaultCenter, // penting untuk deteksi default center
} = useMaps();
const normalizeName = (name = "") => {
return name
.toLowerCase()
.replace(/\bkabupaten\b/gi, "")
.replace(/\bkota\b/gi, "")
.trim();
};
// Helper: cek apakah benar2 sudah PIN (bukan default center & ada addressMaps)
const isPinned = useMemo(() => {
if (!selectedPosition) return false;
// pastikan selalu cast ke number
const lat = Number(selectedPosition.lat);
const lng = Number(selectedPosition.lng);
// kalau hasil cast bukan angka valid
if (isNaN(lat) || isNaN(lng)) return false;
const dc =
typeof getDefaultCenter === "function"
? getDefaultCenter()
: { lat: -6.2, lng: 106.816666 };
const nearDefault =
Math.abs(lat - dc.lat) < 1e-4 &&
Math.abs(lng - dc.lng) < 1e-4;
return Boolean(addressMaps) && !nearDefault;
}, [selectedPosition, addressMaps, getDefaultCenter]);
// Hanya isi addressMap & lat/lng di form kalau SUDAH PIN
useEffect(() => {
// cek kalau form punya koordinat lama
const lat = getValues("latitude");
const lng = getValues("longtitude");
const oldAddress = getValues("addressMap");
if (lat && lng) {
setTempAddress(oldAddress);
setValue("addressMap", oldAddress);
// kalau store punya setter untuk koordinat/alamat:
if (typeof setSelectedPosition === "function") {
setSelectedPosition({ lat: Number(lat), lng: Number(lng) });
}
if (typeof setAddressMaps === "function") {
setAddressMaps(oldAddress);
}
}
}, [setSelectedPosition, setAddressMaps, getValues, setValue]);
useEffect(() => {
const addr = getValues("addressMap");
if (!addr || addr.trim() === "") {
resetPin();
} else {
setAddressMaps(addr);
const lat = getValues("latitude");
const lng = getValues("longtitude");
if (lat && lng) {
setSelectedPosition({ lat: Number(lat), lng: Number(lng) });
}
}
}, [getValues, resetPin, setAddressMaps, setSelectedPosition]);
useEffect(() => {
if (Object.keys(detailAddress).length > 0) {
setValue('zip', detailAddress.postalCode);
const selectedState = states.find(
(state) =>
detailAddress?.province.includes(state.label) ||
state.label.includes(detailAddress?.province)
);
setValue('state', selectedState?.value);
setValue('street', detailAddress?.street);
}
}, [detailAddress, setValue]);
useEffect(() => {
const loadProfile = async () => {
const dataProfile = await addressApi({ id: auth.partnerId });
setValue('industry', dataProfile.industryId);
setValue('companyType', dataProfile.companyTypeId);
setValue('taxName', dataProfile.taxName);
setValue('npwp', dataProfile.npwp);
setValue('alamat_wajib_pajak', dataProfile.alamatWajibPajak);
setValue('alamat_bisnis', dataProfile.alamatBisnis);
setValue('business_name', dataProfile.name);
};
if (auth) loadProfile();
}, [auth?.parentId, setValue]);
// Isi ZIP/Prov dari detailAddress (JANGAN isi street)
useEffect(() => {
const zip = getValues("zip");
const province = getValues("state");
const street = getValues("street");
// set zip dari DB kalau kosong
if (!zip && defaultValues?.zip) {
setValue("zip", defaultValues.zip);
}
// set state dari DB kalau kosong
if (!province && defaultValues?.state) {
const selectedState = states.find(
(state) =>
defaultValues.state.includes(state.label) ||
state.label.includes(defaultValues.state)
);
if (selectedState) {
setValue("state", selectedState.value);
}
}
// set street dari DB kalau kosong
if (!street && defaultValues?.street) {
setValue("street", defaultValues.street);
}
}, [states, setValue, getValues, defaultValues]);
useEffect(() => {
const loadStates = async () => {
let dataStates = await stateApi({ tempo: false });
dataStates = dataStates.map((state) => ({
value: state.id,
label: state.name,
}));
setStates(dataStates);
};
loadStates();
}, []);
const watchState = watch('state');
useEffect(() => {
setValue('city', '');
if (watchState) {
const loadCities = async () => {
let dataCities = await cityApi({ stateId: watchState });
dataCities = dataCities.map((city) => ({
value: city.id,
label: city.name,
}));
setCities(dataCities);
let oldCity = getValues('oldCity');
if (oldCity) {
setValue('city', oldCity);
setValue('oldCity', '');
}
};
loadCities();
}
}, [watchState, setValue, getValues]);
useEffect(() => {
if (!isPinned) return;
if (getValues("city")) return;
if (Object.keys(detailAddress || {}).length > 0) {
const selectedCities =
cities.find(
(city) =>
city.label.toLowerCase() === detailAddress?.district?.toLowerCase()
) ||
cities.find(
(city) =>
detailAddress?.district
?.toLowerCase()
.includes(city.label.toLowerCase()) ||
city.label
.toLowerCase()
.includes(detailAddress?.district?.toLowerCase())
);
if (selectedCities) {
setValue("city", selectedCities.value);
}
}
}, [cities, detailAddress, isPinned, getValues, setValue]);
const watchCity = watch('city');
useEffect(() => {
if (watchCity) {
const loadDistricts = async () => {
let dataDistricts = await districtApi({ cityId: watchCity });
dataDistricts = dataDistricts.map((district) => ({
value: district.id,
label: district.name,
}));
setDistricts(dataDistricts);
let oldDistrict = getValues('oldDistrict');
if (oldDistrict) {
setValue('oldDistrict', '');
}
};
loadDistricts();
}
}, [watchCity, setValue, getValues]);
useEffect(() => {
if (!isPinned) return; // skip kalau belum pin
if (getValues("district")) return;
if (Object.keys(detailAddress).length > 0) {
const selectedDistrict = districts.find(
(district) =>
detailAddress.subDistrict
.toLowerCase()
.includes(district.label.toLowerCase()) ||
district.label
.toLowerCase()
.includes(detailAddress.subDistrict.toLowerCase())
);
setValue('district', selectedDistrict?.value);
}
}, [districts, detailAddress, setValue]);
const watchDistrict = watch('district');
useEffect(() => {
if (watchDistrict) {
const loadSubDistricts = async () => {
let dataSubDistricts = await subDistrictApi({
districtId: watchDistrict,
});
dataSubDistricts = dataSubDistricts.map((district) => ({
value: district.id,
label: district.name,
}));
setSubDistricts(dataSubDistricts);
let oldSubDistrict = getValues('oldSubDistrict');
if (oldSubDistrict) {
setValue('subDistrict', oldSubDistrict);
setValue('oldSubDistrict', '');
}
};
loadSubDistricts();
}
}, [watchDistrict, setValue, getValues]);
useEffect(() => {
if (!isPinned) return; // skip kalau belum pin
if (getValues("subDistrict")) return;
if (Object.keys(detailAddress).length > 0) {
const selectedSubDistrict = subDistricts.find(
(district) =>
detailAddress.village
.toLowerCase()
.includes(district.label.toLowerCase()) ||
district.label
.toLowerCase()
.includes(detailAddress.village.toLowerCase())
);
setValue('subDistrict', selectedSubDistrict?.value);
}
}, [subDistricts, detailAddress, setValue]);
useEffect(() => {
if (id) {
setValue('id', id);
}
}, [id, setValue]);
const onSubmitHandler = async (values) => {
if (addressMaps) {
if (!detailAddress){
if (defaultValues?.oldCity !== values.city) {
setPopupMessage("Titik Koordinat tidak sesuai dengan Kota yang dipilih");
setShowValidationPopup(true);
// console.log(detailAddress)
return;
}
}
if (detailAddress) {
const cityName = normalizeName(
cities.find((c) => c.value === watch("city"))?.label || ""
);
const districtName = normalizeName(detailAddress?.district || "");
// console.log(cityName, '=', districtName);
if (cityName && cityName !== districtName) {
setPopupMessage("Titik Koordinat tidak sesuai dengan Kota yang dipilih");
setShowValidationPopup(true);
return;
}
}
}
// if(!addressMaps && detailAddress){
// if (selectedCityName && selectedCityName !== detailAddress?.district?.toLowerCase()) {
// setPopupMessage("Titik Koordinat tidak sesuai dengan Kota yang dipilih 3");
// setShowValidationPopup(true);
// return;
// }
// }
const data = {
...values,
phone: values.mobile,
state_id: parseInt(values.state, 10),
city_id: parseInt(values.city, 10),
district_id: parseInt(values.district, 10),
sub_district_id: parseInt(values.subDistrict, 10),
};
if (isPinned) {
data.longtitude = selectedPosition?.lng;
data.latitude = selectedPosition?.lat;
data.address_map = addressMaps || values.addressMap;
data.use_pin = true;
} else {
data.use_pin = false;
// pastikan tidak ada nilai default center yang ikut terkirim
delete data.longtitude;
delete data.latitude;
delete data.address_map;
}
if (!auth.company) {
data.alamat_lengkap_text = values.street;
}
try {
const address = await editAddressApi({ id, data });
console.log('Response address:', address);
let isUpdated = null;
const isCompanyEditingSelf = auth.company && auth.partnerId == id;
if (isCompanyEditingSelf) {
const dataProfile = await addressApi({ id: auth.partnerId });
const dataAlamat = {
id_user: auth.id,
company_type_id: dataProfile.companyTypeId,
industry_id: dataProfile.industryId,
tax_name: values.taxName,
npwp: values.npwp,
alamat_lengkap_text: values.alamat_wajib_pajak || values.street,
street: values.street,
email: values.email,
mobile: values.mobile,
};
const isUpdatedRes = await editPartnerApi({
id: auth.partnerId,
data: dataAlamat,
});
console.log('Response isUpdated:', isUpdatedRes);
}
const isSuccess = !!address?.id;
if (isSuccess) {
toast.success('Berhasil mengubah alamat');
router.back();
} else {
const errorMsg =
address?.message ||
isUpdated?.message ||
'Gagal memperbarui alamat, silakan coba lagi.';
toast.error(errorMsg);
}
} catch (error) {
console.error('Catch error:', error);
toast.error(error?.message || 'Terjadi kesalahan tidak terduga.');
}
const dataProfile = await addressApi({ id: auth.partnerId });
// console.log('ini adalah', dataProfile);
};
// console.log('ini adalah', detailAddress);
return (
<>