<template>
  <v-dialog v-model="showDialog" max-width="500" persistent>
    <v-card>
      <v-toolbar>
        <v-row no-gutters class="fill-height px-6" align="center">
          <span class="font-weight-bold text-h6">Search Location</span>
        </v-row>
      </v-toolbar>

      <v-card-text class="pa-6">
        <v-form ref="formRef" @submit.prevent="handleSearch">
          <v-row dense>
            <v-col cols="12" md="6">
              <InputLabel title="Country (Optional)" />
              <v-autocomplete
                v-model="formData.country"
                :items="countryList"
                :loading="loadingCountries"
                density="comfortable"
                placeholder="Select country"
                clearable
                hide-details="auto"
                @update:model-value="handleCountryChange"
              />
            </v-col>

            <v-col cols="12" md="6">
              <InputLabel title="Postal Code" required />
              <v-text-field
                v-model="formData.postalCode"
                clearable
                :loading="postalLoading"
                density="comfortable"
                placeholder="Enter postal code"
                :rules="postalCodeRules"
                hide-details="auto"
                @update:model-value="handlePostalCodeInput"
                @click:clear="handlePostalCodeClear"
              />
            </v-col>

            <v-col cols="12" md="6">
              <InputLabel title="City (Optional)" />
              <v-text-field
                v-model="formData.city"
                :loading="postalLoading"
                density="comfortable"
                placeholder="Enter city"
                hide-details="auto"
                @update:model-value="handleCityChange"
              />
            </v-col>

            <v-col cols="12" md="6">
              <InputLabel title="Address (Optional)" />
              <v-text-field
                v-model="formData.address"
                :loading="postalLoading"
                density="comfortable"
                placeholder="Enter address"
                hide-details="auto"
                @update:model-value="handleAddressChange"
              />
            </v-col>
          </v-row>
        </v-form>
      </v-card-text>

      <v-toolbar class="pa-0" density="compact">
        <v-row no-gutters>
          <v-col cols="6" class="pa-0">
            <v-btn
              block
              variant="text"
              class="text-none"
              size="large"
              height="56"
              :disabled="searching"
              @click="handleClose"
            >
              Cancel
            </v-btn>
          </v-col>
          <v-col cols="6" class="pa-0">
            <v-btn
              block
              variant="flat"
              color="black"
              class="text-none font-weight-bold rounded-0"
              height="56"
              size="large"
              :loading="searching"
              :disabled="!formData.postalCode"
              @click="handleSearch"
            >
              <v-icon class="mr-2">mdi-magnify</v-icon>
              Search
            </v-btn>
          </v-col>
        </v-row>
      </v-toolbar>
    </v-card>
  </v-dialog>

  <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
</template>
That is 

<script setup lang="ts">
const showDialog = defineModel({ type: Boolean, default: false });

const props = defineProps<{
  initialCountry?: string;
  initialPostalCode?: string;
  initialCity?: string;
  initialAddress?: string;
}>();

const emit = defineEmits<{
  locationSelected: [location: TLocationData];
}>();

const { getCountries, getAddressByPostalCode, searchLocationByAddress } =
  useLocation();

const formRef = ref<any>(null);
const searching = ref(false);
const loadingCountries = ref(false);
const postalLoading = ref(false);

const formData = ref<TLocationFormData>({
  country: props.initialCountry || "",
  postalCode: props.initialPostalCode || "",
  city: props.initialCity || "",
  address: props.initialAddress || "",
});

const manuallyEdited = ref<TLocationFieldState>({
  country: false,
  city: false,
  address: false,
});

const autoFilled = ref<TLocationFieldState>({
  country: !!props.initialCountry,
  city: !!props.initialCity,
  address: !!props.initialAddress,
});

const message = ref("");
const messageSnackbar = ref(false);
const messageColor = ref("");

const countryList = ref<string[]>([]);

let postalCodeTimeout: ReturnType<typeof setTimeout> | null = null;

const postalCodeRules = [(v: string) => !!v || "Postal code is required"];

onMounted(async () => {
  await loadCountriesList();
});

onUnmounted(() => {
  if (postalCodeTimeout) {
    clearTimeout(postalCodeTimeout);
  }
});

const loadCountriesList = async () => {
  try {
    loadingCountries.value = true;
    countryList.value = await getCountries();
  } catch (err) {
    console.error("Failed to load countries:", err);
    showMessage("Failed to load countries list", "error");
  } finally {
    loadingCountries.value = false;
  }
};

const handleCountryChange = () => {
  manuallyEdited.value.country = true;
  autoFilled.value.country = false;
};

const handleCityChange = () => {
  manuallyEdited.value.city = true;
  autoFilled.value.city = false;
};

const handleAddressChange = () => {
  manuallyEdited.value.address = true;
  autoFilled.value.address = false;
};

const handlePostalCodeInput = () => {
  postalLoading.value = true;

  if (postalCodeTimeout) {
    clearTimeout(postalCodeTimeout);
  }

  postalCodeTimeout = setTimeout(() => {
    fetchAddressFromPostal();
  }, 800);
};

const handlePostalCodeClear = () => {
  if (postalCodeTimeout) {
    clearTimeout(postalCodeTimeout);
    postalCodeTimeout = null;
  }

  postalLoading.value = false;
  formData.value.postalCode = "";

  if (autoFilled.value.country) {
    formData.value.country = "";
    autoFilled.value.country = false;
  }

  if (autoFilled.value.city) {
    formData.value.city = "";
    autoFilled.value.city = false;
  }

  if (autoFilled.value.address) {
    formData.value.address = "";
    autoFilled.value.address = false;
  }
};

const fetchAddressFromPostal = async () => {
  if (!formData.value.postalCode) {
    postalLoading.value = false;
    return;
  }

  try {
    postalLoading.value = true;

    const result = await getAddressByPostalCode(
      formData.value.postalCode,
      formData.value.country,
    );

    if (result) {
      const addressData = result.address || {};
      const displayParts =
        result.display_name?.split(",").map((s: string) => s.trim()) || [];

      const countryName = displayParts[displayParts.length - 1] || "";
      const derivedCity =
        addressData.city ||
        addressData.town ||
        addressData.village ||
        addressData.state ||
        displayParts[displayParts.length - 2] ||
        "";

      if (!manuallyEdited.value.country && countryName) {
        formData.value.country = countryName;
        autoFilled.value.country = true;
      }

      if (!manuallyEdited.value.city && derivedCity) {
        formData.value.city = derivedCity;
        autoFilled.value.city = true;
      }
      if (!manuallyEdited.value.address && result.display_name) {
        formData.value.address = result.display_name;
        autoFilled.value.address = true;
      }
    } else {
      if (autoFilled.value.country && !manuallyEdited.value.country) {
        formData.value.country = "";
        autoFilled.value.country = false;
      }

      if (autoFilled.value.city && !manuallyEdited.value.city) {
        formData.value.city = "";
        autoFilled.value.city = false;
      }

      if (autoFilled.value.address && !manuallyEdited.value.address) {
        formData.value.address = "";
        autoFilled.value.address = false;
      }
    }
  } catch (err) {
    console.error("Error fetching address from postal code:", err);
  } finally {
    postalLoading.value = false;
  }
};

const handleSearch = async () => {
  const { valid } = await formRef.value.validate();

  if (!valid) {
    return;
  }

  searching.value = true;

  try {
    const item = await searchLocationByAddress({
      postalCode: formData.value.postalCode,
      city: manuallyEdited.value.city ? formData.value.city : undefined,
      address: manuallyEdited.value.address
        ? formData.value.address
        : undefined,
      country: formData.value.country,
    });

    if (item) {
      const location: TLocationData = {
        latitude: parseFloat(item.lat),
        longitude: parseFloat(item.lon),
        address: formData.value.address || item.display_name || "",
        city:
          formData.value.city ||
          item.address?.city ||
          item.address?.town ||
          item.address?.village ||
          "",
        country: formData.value.country || item.address?.country || "",
        postalCode: formData.value.postalCode || "",
      };

      emit("locationSelected", location);
      showMessage("Location found successfully", "success");
      handleClose();
    } else {
      showMessage(
        "Location not found. Please try different search criteria.",
        "error",
      );
    }
  } catch (err) {
    console.error("Error searching location:", err);
    showMessage("Failed to search location. Please try again.", "error");
  } finally {
    searching.value = false;
  }
};

const handleClose = () => {
  resetForm();
  showDialog.value = false;
};

const resetForm = () => {
  formData.value = {
    country: props.initialCountry || "",
    postalCode: props.initialPostalCode || "",
    city: props.initialCity || "",
    address: props.initialAddress || "",
  };

  manuallyEdited.value = {
    country: false,
    city: false,
    address: false,
  };

  autoFilled.value = {
    country: !!props.initialCountry,
    city: !!props.initialCity,
    address: !!props.initialAddress,
  };

  if (postalCodeTimeout) {
    clearTimeout(postalCodeTimeout);
    postalCodeTimeout = null;
  }

  postalLoading.value = false;
};

const showMessage = (msg: string, color: string = "error") => {
  message.value = msg;
  messageColor.value = color;
  messageSnackbar.value = true;
};

watch(showDialog, (newVal) => {
  if (newVal) {
    resetForm();
  }
});
</script>
