<template>
    <div class="row">
        <div class="col-md-4">
            <label>Tỉnh/thành phố</label>
            <LadaSelect v-model="localCityId" :options="cities" :searchFn="onCitySearch"
                placeholder="Chọn tỉnh/thành phố" @update:modelValue="onCityChange" />
        </div>
        <div class="col-md-4">
            <label>Quận/huyện</label>
            <LadaSelect v-model="localDistrictId" :options="districts" :searchFn="onDistrictSearch"
                placeholder="Chọn quận/huyện" @update:modelValue="onDistrictChange" />
        </div>
        <div class="col-md-4">
            <label>Phường/xã</label>
            <LadaSelect v-model="localWardId" :options="wards" :searchFn="onWardSearch" placeholder="Chọn phường/xã"
                @update:modelValue="onWardChange" />
        </div>
    </div>
</template>
<script setup>
import { ref, watch, onMounted, defineExpose } from 'vue';
import locationService from '@/services/locationService';
import LadaSelect from '@/components/LadaSelect.vue';

const props = defineProps({
    cityId: Number,
    districtId: Number,
    wardId: Number,
});
const emit = defineEmits(['update:cityId', 'update:districtId', 'update:wardId']);

const localCityId = ref(props.cityId || null);
const localDistrictId = ref(props.districtId || null);
const localWardId = ref(props.wardId || null);

const cities = ref([]);
const districts = ref([]);
const wards = ref([]);

async function ensureOption(list, id) {
    if (id && !list.value.some(x => x.Id === id)) {
        const obj = await locationService.getById(id);
        if (obj && obj.Id) list.value.push({ Id: obj.Id, Name: obj.Name });
    }
}

async function loadDistricts(cid) {
    if (!cid) { districts.value = []; return; }
    districts.value = await locationService.loSug('', 1, cid) || [];
    await ensureOption(districts, localDistrictId.value);
}
async function loadWards(did) {
    if (!did) { wards.value = []; return; }
    wards.value = await locationService.loSug('', 2, did) || [];
    await ensureOption(wards, localWardId.value);
}

function onCityChange(val) {
    localCityId.value = val;
    emit('update:cityId', val);
    localDistrictId.value = null;
    emit('update:districtId', null);
    localWardId.value = null;
    emit('update:wardId', null);
}
function onDistrictChange(val) {
    localDistrictId.value = val;
    emit('update:districtId', val);
    localWardId.value = null;
    emit('update:wardId', null);
}
function onWardChange(val) {
    localWardId.value = val;
    emit('update:wardId', val);
    // KHÔNG reset district/city, KHÔNG set lại gì khác!
}

async function onCitySearch(search, loading) {
    loading(true);
    const result = await locationService.loSug(search, 3, 0);
    cities.value = result || [];
    if (localCityId.value && !cities.value.some(c => c.Id === localCityId.value)) {
        const obj = await locationService.getById(localCityId.value);
        if (obj && obj.Id) cities.value.push({ Id: obj.Id, Name: obj.CombinedName || obj.Name });
    }
    loading(false);
}
async function onDistrictSearch(search, loading) {
    loading(true);
    if (!localCityId.value) { districts.value = []; loading(false); return; }
    const result = await locationService.loSug(search, 1, localCityId.value);
    districts.value = result || [];
    if (localDistrictId.value && !districts.value.some(d => d.Id === localDistrictId.value)) {
        const obj = await locationService.getById(localDistrictId.value);
        if (obj && obj.Id) districts.value.push({ Id: obj.Id, Name: obj.CombinedName || obj.Name });
    }
    loading(false);
}
async function onWardSearch(search, loading) {
    loading(true);
    if (!localDistrictId.value) { wards.value = []; loading(false); return; }
    const result = await locationService.loSug(search, 2, localDistrictId.value);
    wards.value = result || [];
    if (localWardId.value && !wards.value.some(w => w.Id === localWardId.value)) {
        const obj = await locationService.getById(localWardId.value);
        if (obj && obj.Id) wards.value.push({ Id: obj.Id, Name: obj.CombinedName || obj.Name });
    }
    loading(false);
}

onMounted(async () => {
    await ensureOption(cities, localCityId.value);
    await loadDistricts(localCityId.value);
    await ensureOption(districts, localDistrictId.value);
    await loadWards(localDistrictId.value);
    await ensureOption(wards, localWardId.value);
});

// Đồng bộ props -> local khi props thay đổi, KHÔNG gọi API
watch(() => props.cityId, (val) => { localCityId.value = val; });
watch(() => props.districtId, (val) => { localDistrictId.value = val; });
watch(() => props.wardId, (val) => { localWardId.value = val; });

// Watcher localCityId: chỉ reset district/ward khi city thực sự đổi, load lại districts
watch(localCityId, async (val, oldVal) => {
    if (val !== oldVal) {
        emit('update:cityId', val);
        await ensureOption(cities, val);
        await loadDistricts(val);
        localDistrictId.value = null;
        emit('update:districtId', null);
        localWardId.value = null;
        emit('update:wardId', null);
    }
});
// Watcher localDistrictId: chỉ reset ward khi district thực sự đổi, load lại wards
watch(localDistrictId, async (val, oldVal) => {
    if (val !== oldVal) {
        emit('update:districtId', val);
        await ensureOption(districts, val);
        await loadWards(val);
        localWardId.value = null;
        emit('update:wardId', null);
    }
});
// Watcher localWardId: chỉ gọi ensureOption nếu wardId chưa có trong danh sách
watch(localWardId, async (val, oldVal) => {
    if (val !== oldVal) {
        emit('update:wardId', val);
        if (val && !wards.value.some(w => w.Id === val)) {
            await ensureOption(wards, val);
        }
    }
});

// expose hàm lấy giá trị hiện tại cho cha
const getCurrentSelection = () => ({
    cityId: localCityId.value,
    districtId: localDistrictId.value,
    wardId: localWardId.value,
    city: cities.value.find(c => c.Id === localCityId.value) || null,
    district: districts.value.find(d => d.Id === localDistrictId.value) || null,
    ward: wards.value.find(w => w.Id === localWardId.value) || null,
});
async function init(city, district, ward) {
    localCityId.value = city && city.Id ? city.Id : null;
    localDistrictId.value = district && district.Id ? district.Id : null;
    localWardId.value = ward && ward.Id ? ward.Id : null;

    // Emit events để đồng bộ với parent
    emit('update:cityId', localCityId.value);
    emit('update:districtId', localDistrictId.value);
    emit('update:wardId', localWardId.value);

    // Đảm bảo các option được load vào danh sách
    if (city && city.Id) {
        if (!cities.value.some(c => c.Id === city.Id)) {
            cities.value.push({ Id: city.Id, Name: city.Name });
        }
        await loadDistricts(city.Id);
    }

    if (district && district.Id) {
        if (!districts.value.some(d => d.Id === district.Id)) {
            districts.value.push({ Id: district.Id, Name: district.Name });
        }
        await loadWards(district.Id);
    }

    if (ward && ward.Id) {
        if (!wards.value.some(w => w.Id === ward.Id)) {
            wards.value.push({ Id: ward.Id, Name: ward.Name });
        }
    }
}
defineExpose({ getCurrentSelection, init });
</script>