<template>
	<form @submit.prevent="submit">
		<!-- Hidden fields -->
		<div>
			<div class="pa-0 d-flex flex-column">
				<div class="d-flex flex-wrap align-center mb-5 search-form-background">
					<!-- Place -->
					<div class="flex-grow-1" style="min-width: 300px; height: 100%">
						<app-address-location
							v-model:boundary="search.params.search.boundary"
							v-model:city="search.params.search.city"
							v-model:country="search.params.search.country"
							v-model:formatted="search.params.search.full_address"
							v-model:ignore_bookings="search.params.search.ignore_bookings"
							v-model:state="search.params.search.state"
							v-model:suburb="search.params.search.suburb"
							:map="false"
						/>
					</div>

					<!-- Date range -->
					<v-defaults-provider
						:defaults="searchHelper.defaults"
						class="d-flex align-items-center flex-wrap container-actions"
					>
						<div>
							<v-menu v-model="menu.calendar">
								<template #activator="{ props }">
									<v-btn
										:class="
                        selectedDates
                          ? 'bg-primary'
                          : ''
                      "
										icon="mdi-calendar-range"
										v-bind="props"
									/>
								</template>

								<v-defaults-provider>
									<v-card width="328">
										<!-- <VDatePicker
										  v-model.range.string="datePicker"
										  :disabled-dates="[{ start: null, end: new Date() }]"
										  borderless
										  class="saswp-vcalendar"
										  color="saswp-vcalendar"
										  timezone="utc"
										  transparent
										  update-on-input
										  @update:modelValue="datePickerUpdateHandler($event)"
										/> -->
										<v-date-picker
											hide-header
											elevation="0"
											multiple="range"
											v-model="datePicker"
											:min="new Date().toISOString().substr(0, 10)"
											@update:modelValue="datePickerUpdateHandler($event)"
										></v-date-picker>
										<v-row class="w-100 ma-0 border-t" justify="space-between">
											<v-col cols="6">
												<v-btn
													block
													class="w-100"
													@click="datePickerClearHandler()"
												>
													Clear
												</v-btn>
											</v-col>

											<v-col cols="6">
												<v-btn
													block
													class="w-100"
													rounded="0"
													@click="menu.calendar = false"
												>
													Ok
												</v-btn>
											</v-col>
										</v-row>

										<!-- <pre>{{ datePicker }}</pre> -->
										<!-- <pre>{{ search.params.search }}</pre> -->
									</v-card>
								</v-defaults-provider>
							</v-menu>
						</div>

						<!-- Guests -->
						<div>
							<v-menu v-model="menu.guests">
								<template #activator="{ props }">
									<v-btn
										:class="
                        (parseInt(search.params.search.guests_adults) || 0) +
                        (parseInt(search.params.search.guests_children) || 0) +
                        (parseInt(search.params.search.guests_infant) || 0) +
                        (parseInt(search.params.search.guests_pets) || 0) > 1
                          ? 'bg-primary'
                          : ''
                      "
										icon="mdi-account"
										v-bind="props"
									/>
								</template>

								<v-defaults-provider :defaults="searchHelper.defaults">
									<v-card>
										<v-card-title class="bg-grey-lighten-4 py-3 mb-5">
											{{
												(parseInt(search.params.search.guests_adults) || 0) +
												(parseInt(search.params.search.guests_children) || 0) +
												(parseInt(search.params.search.guests_infant) || 0) +
												(parseInt(search.params.search.guests_pets) || 0) +
												" Guests"
											}}
										</v-card-title>
										<v-card-text>
											<v-text-field
												v-model="search.params.search.guests_adults"
												label="Adults"
												min="1"
												type="number"
												@keydown="
                          $event.key === '-' ? $event.preventDefault() : null
                        "
											/>

											<br/>
											<v-text-field
												v-model="search.params.search.guests_children"
												label="Children"
												min="0"
												type="number"
												@keydown="$event.key === '-' ? $event.preventDefault() : null"
											/>

											<br/>
											<v-text-field
												v-model="search.params.search.guests_infant"
												label="Infant"
												min="0"
												type="number"
												@keydown="$event.key === '-' ? $event.preventDefault() : null"
											/>
										</v-card-text>

										<v-divider/>
										<v-row class="w-100 ma-0 border-t" justify="space-between">
											<v-col cols="6">
												<v-btn
													block
													class="w-100"
													@click="clearGuests()"
												>
													Clear
												</v-btn>
											</v-col>

											<v-col cols="6">
												<v-btn
													block
													class="w-100"
													rounded="0"
													@click="menu.guests = false"
												>
													Ok
												</v-btn>
											</v-col>
										</v-row>
									</v-card>
								</v-defaults-provider>
							</v-menu>
						</div>

						<!-- property type -->
						<div>
							<v-menu v-model="menu.house">
								<template #activator="{ props }">
									<v-btn
										:class="
                        search.params.search.property_types?.length > 0 ||
                        search.params.search.holiday_types?.length > 0 ||
                        search.params.search.amenities?.length > 0
                          ? 'bg-primary'
                          : ''
                      "
										icon="mdi-home"
										v-bind="props"
									/>
								</template>

								<v-defaults-provider :defaults="searchHelper.defaults">
									<v-card width="420px">
										<v-card-title class="bg-grey-lighten-4 py-3 mb-5">
											House configuration
										</v-card-title>
										<v-card-text>
											<v-select
												v-model="search.params.search.property_types"
												:items="propertyTypes.response.data"
												item-title="name"
												item-value="id"
												label="Property types"
												multiple
											>
												<template v-slot:selection="{ item, index }">
													<span v-if="index < 2">{{ index > 0 ? ', ' : ' ' }} {{
															item.title
														}}</span>

													<span
														v-if="index === 2"
														class="text-grey text-caption align-self-center"
													>
                            (+{{ search.params.search.property_types.length - 2 }})
                        </span>
												</template>
											</v-select>

											<br/>
											<v-select
												v-model="search.params.search.holiday_types"
												:items="holidayTypes"
												item-title="name"
												item-value="id"
												label="Holiday types"
												multiple
											>
												<template v-slot:selection="{ item, index }">
													<span v-if="index < 2">{{ index > 0 ? ', ' : ' ' }} {{
															item.title
														}}</span>

													<span
														v-if="index === 2"
														class="text-grey text-caption align-self-center"
													>
                            (+{{ search.params.search.holiday_types.length - 2 }})
                        </span>
												</template>
											</v-select>

											<br/>
											<v-select
												v-model="search.params.search.amenities"
												:items="amenities"
												item-title="name"
												item-value="id"
												label="Amenities"
												multiple
											>
												<template v-slot:selection="{ item, index }">
													<span v-if="index < 2">{{ index > 0 ? ', ' : ' ' }} {{
															item.title
														}}</span>

													<span
														v-if="index === 2"
														class="text-grey text-caption align-self-center"
													>
                            (+{{ search.params.search.amenities.length - 2 }})
                        </span>
												</template>
											</v-select>
										</v-card-text>

										<v-divider/>
										<v-row class="w-100 ma-0 border-t" justify="space-between">
											<v-col cols="6">
												<v-btn
													block
													class="w-100"
													@click="clearHouse()"
												>
													Clear
												</v-btn>
											</v-col>

											<v-col cols="6">
												<v-btn
													block
													class="w-100"
													rounded="0"
													@click="menu.house = false"
												>
													Ok
												</v-btn>
											</v-col>
										</v-row>
									</v-card>
								</v-defaults-provider>
							</v-menu>
						</div>

						<!-- More -->
						<div>
							<v-menu v-model="menu.advancedSearch">
								<template #activator="{ props }">
									<v-btn
										:class="
											Number(search.params.search.min_price) !== Number(priceRange.response.data.min_price || 0) ||
											Number(search.params.search.max_price) !== Number(priceRange.response.data.max_price || 0) ||
											(search.params.search.bedrooms !== null && Number(search.params.search.bedrooms) > 0) ||
											(search.params.search.bathrooms !== null && Number(search.params.search.bathrooms) > 0) ||
											search.params.search.accessibility || 
											search.params.search.sustainability || 
											search.params.search.pets
												? 'bg-primary'
												: ''
										"
										icon="mdi-dots-horizontal"
										v-bind="props"

									/>
								</template>

								<v-defaults-provider :defaults="searchHelper.defaults">
									<v-card>
										<v-card-title class="bg-grey-lighten-4 py-3 mb-5">
											Advanced filters
										</v-card-title>
										<v-card-text>
											<v-list-subheader>Price Range</v-list-subheader>
											<v-range-slider
												:max="priceRange.response.data.max_price"
												:min="priceRange.response.data.min_price"
												:model-value="[
													parseFloat(search.params.search.min_price) || 0,
													parseFloat(search.params.search.max_price) || 5000,
												]"
												append-icon="mdi-close"
												@update:modelValue="
													(values) => {
														search.params.search.min_price = values[0];
														search.params.search.max_price = values[1];
													}
												"
												@click:append="
													($event) => {
														search.params.search.min_price = null;
														search.params.search.max_price = null;
													}
												"
											/>

											<div class="d-flex">
												<div>
													{{ toMoney(search.params.search.min_price) }}
												</div>
												<div class="flex-grow-1 text-center">~</div>
												<div>
													{{ toMoney(search.params.search.max_price) }}
												</div>
											</div>
											<br/>

											<v-text-field
												v-model="search.params.search.bedrooms"
												class="mb-3"
												label="Bedrooms"
												max="5"
												min="1"
												type="number"
												@keydown="$event.key === '-' ? $event.preventDefault() : null"
											/>
											<br/>

											<v-text-field
												v-model="search.params.search.bathrooms"
												class="mb-3"
												label="Bathrooms"
												max="5"
												min="1"
												type="number"
												@keydown="$event.key === '-' ? $event.preventDefault() : null"
											/>
											<br/>

											<div class="d-flex align-center justify-space-between">
												<div>Accessibility Options</div>
												<v-switch color="primary" v-model="search.params.search.accessibility"></v-switch>
											</div>

											<div class="d-flex align-center justify-space-between">
												<div>Sustainability Features</div>
												<v-switch color="primary" v-model="search.params.search.sustainability"></v-switch>
											</div>

											<div class="d-flex align-center justify-space-between">
												<div>Pet Friendly</div>
												<v-switch color="primary" v-model="search.params.search.pets"></v-switch>
											</div>
											<!-- <v-btn class="w-100" @click="searchMap.show=!searchMap.show">Map</v-btn> -->
										</v-card-text>

										<v-divider/>
										<v-row class="w-100 ma-0 border-t" justify="space-between">
											<v-col cols="6">
												<v-btn block class="w-100" @click="clearAdvancedFilters()">Clear</v-btn>
											</v-col>

											<v-col cols="6">
												<v-btn block class="w-100" rounded="0"@click="menu.advancedSearch = false">
													Ok
												</v-btn>
											</v-col>
										</v-row>
									</v-card>
								</v-defaults-provider>
							</v-menu>
						</div>

						<!-- Submit -->
						<div class="flex-grow-1 width-button">
							<v-btn
								:loading="loading"
								block
								class="w-100"
								color="primary"
								height="58px"
								type="submit"
							>
								Search
							</v-btn>
						</div>
					</v-defaults-provider>
				</div>
			</div>
		</div>
	</form>
</template>

<script setup>
const {computed, defineEmits, onBeforeMount, reactive, ref, watch} = Vue;

const AppAddressLocation = Vue.defineAsyncComponent(() =>
	loadModule(`${SAS_URL}/src/components/AppAddressLocation.vue`, options),
);

const props = defineProps({
	modelValue: {type: Object, default: () => ({})},
	property: {type: Object, default: () => ({})},
	priceRangeProps: {type: Object, default: () => ({})},
});

const loading = ref(false)
const menu = ref({
	calendar: false,
	guests: false,
	house: false,
	advancedSearch: false,
});

const emit = defineEmits(["update:modelValue"]);
const url = useUrl();
const amenities = ref([])
const holidayTypes = ref([])
const amenitiesAndHolidayTypes = ref([])
const datePicker = ref([]);
const priceRange = ref({response: {data: {entities: []}}})

const search = useSasPropertySearch(lodash.merge(props.modelValue, {params: url.params}));

onBeforeMount(async () => {
	if (props.modelValue.params.search) {
		if ((props.modelValue.params.search?.amenities?.length ?? 0) > 0 || (props.modelValue.params.search?.holiday_types?.length ?? 0) > 0) {
			amenitiesAndHolidayTypes.value = convertStringsToNumbers([
				...(props.modelValue.params.search?.holiday_types ?? []),
				...(props.modelValue.params.search?.amenities ?? [])
			]);
		}

		props.modelValue.params.search.amenities = []
		props.modelValue.params.search.holiday_types = []
		search.value.params = props.modelValue.params;

		if (search.value.params.search.initial_date && search.value.params.search.final_date) {
			datePicker.value = getDatesBetween(new Date(search.value.params.search.initial_date), new Date(search.value.params.search.final_date))
		}
	}

	await loadAmenities()
	await loadHolidayTypes()
	
	if (props.priceRangeProps.max_price && props.priceRangeProps.min_price) {
		search.value.params.search.min_price = props.priceRangeProps.min_price ?? 0
		search.value.params.search.max_price = props.priceRangeProps.max_price ?? 0
	} else {
		await loadPriceRange()
	}

	if (search.value.params.search.amenitiesCategory) {
		if (Array.isArray(search.value.params.search.amenitiesCategory)) {
			search.value.params.search.accessibility = search.value.params.search.amenitiesCategory.includes(2);
			search.value.params.search.sustainability = search.value.params.search.amenitiesCategory.includes(24);
		}
	}

	if (search.value.params.search.amenitiesPet) {
		if (Array.isArray(search.value.params.search.amenitiesPet)) {
			search.value.params.search.pets = search.value.params.search.amenitiesPet.includes(159) && search.value.params.search.amenitiesPet.includes(161);
		}
	}
})

const getDatesBetween = (startDate, endDate) => {
	let dates = [];
	let currentDate = new Date(startDate);

	while (currentDate <= endDate) {
		dates.push(new Date(currentDate));
		currentDate.setDate(currentDate.getDate() + 1);
	}

	return dates;
}

const toMoney = (value) => {
	return window.money(value, 'AUD');
};

const loadAmenities = async () => {
	try {
		const {data} = await axios.get('/public/amenities')
		amenities.value = data.data

		manipulateHolidayTypesOrAmenities(amenities.value, 'amenities')
	} catch (e) {
		console.log(e)
	}
}

const loadHolidayTypes = async () => {
	try {
		const {data} = await axios.get('/public/amenities_by_categories?amenity_categories[]=37,38,39&per_page=999')
		holidayTypes.value = data.data

		manipulateHolidayTypesOrAmenities(holidayTypes.value, 'holiday_types')
	} catch (e) {
		console.log(e)
	}
}

const manipulateHolidayTypesOrAmenities = (array, type) => {
	array.forEach(a => {
		if (amenitiesAndHolidayTypes.value?.includes(a.id) && type === 'amenities') {
			search.value.params.search.amenities.push(a?.id)
		} else if (amenitiesAndHolidayTypes.value?.includes(a.id) && type === 'holiday_types') {
			search.value.params.search.holiday_types.push(a?.id)
		}
	})
}

const convertStringsToNumbers = (array) => {
	array = array?.sort((a, b) => a - b)
	return array?.map(item => Number(item))
};


const selectedDates = computed(() => {
	return datePicker.value?.filter(value => value !== null).length > 1 || false
})

// const priceRange = useAxios({
// 	url: "/properties",
// 	method: "get",
// 	autoSubmit: true,
// 	params: search.value.params,
// 	onSuccess(response) {
// 		search.value.params.search.min_price = response.data.data.min_price;
// 		search.value.params.search.max_price = response.data.data.max_price;
// 	},
// 	response: {
// 		data: {
// 			entities: [],
// 		},
// 	},
// });

const loadPriceRange = async () => {
	try {
		const response = await axios.get("/properties", search.value.params);
		search.value.params.search.min_price = response.data.data.min_price ?? 0
		search.value.params.search.max_price = response.data.data.max_price ?? 0
		priceRange.value.response = response.data
	} catch(e){
		console.error(e)
	}
}

const submit = async () => {
	loading.value = true;

	let payload = buildPayload(fieldNames.value);
	if (payload[0] === "&") {
		payload = payload.replace("&", "");
	}
	emit("update:modelValue", search.value, payload);

	if (!window.location.pathname.includes(`/${window.env?.sas_route_vendor_property_main_featured}`)) {
		window.location.href = `./${window.env?.sas_route_vendor_property_main_featured}?${payload}`;
	} else {
		updateURLWithPayload(payload);
	}

	setTimeout(() => {
		loading.value = false;
	}, 3000)
};

const updateURLWithPayload = (payload) => {
	const locationHrefSplit = window.location.href.split("?");
	const newUrl = `${locationHrefSplit[0]}${payload ? `?${payload}` : ""}`;
	window.history.replaceState(null, null, newUrl);
};

const buildPayload = (pairs) => {
	let payload = "";
	
	// Remove pairs that should be handled separately (always remove these as they're handled below)
	for (let i = pairs.length - 1; i >= 0; i--) {
		if (
			pairs[i].name === "search[accessibility]" || 
			pairs[i].name === "search[sustainability]" || 
			pairs[i].name === "search[pets]"
		) {
			pairs.splice(i, 1);
		}
	}

	pairs.forEach((pair, index) => {
		if (pair.value === undefined || pair.value === "") return;

		if (
			(pair.name === "search[guests]" || pair.name === "search[guests_adults]") && pair.value === 1
		) {
			return;
		}

		if (
			(pair.name === "search[min_price]" &&
				Number(pair.value) === Number(priceRange.value.response.data.min_price)) ||
			(pair.name === "search[max_price]" &&
				Number(pair.value) === Number(priceRange.value.response.data.max_price))
		) {
			return;
		}

		if (index !== 0 && pair.value !== undefined) {
			payload += "&";
		}

		if (pair.name.startsWith("search[") && pair.name.endsWith("]")) {
			payload += `${encodeURIComponent(pair.name)}=${encodeURIComponent(pair.value)}`;
		} else {
			payload += `${pair.name}=${pair.value}`;
		}
	});

	if (search.value.params.search.accessibility) {
		if (payload !== "") payload += "&";
		payload += "search[amenitiesCategory][]=2";
	}

	if (search.value.params.search.sustainability) {
		if (payload !== "") payload += "&";
		payload += "search[amenitiesCategory][]=24";
	}

	if (search.value.params.search.pets) {
		if (payload !== "") payload += "&";
		payload += "search[amenitiesPet][]=159&search[amenitiesPet][]=161";
	}

	return payload;
};

const datePickerUpdateHandler = (ev) => {
	if (ev.length > 1) {
		search.value.params.search.initial_date = window.$moment(ev[0]).format("YYYY-MM-DD");
		search.value.params.search.final_date = window.$moment(ev[ev.length - 1]).format("YYYY-MM-DD");
	}
};

const datePickerClearHandler = () => {
	datePicker.value = undefined
	search.value.params.search.initial_date = null;
	search.value.params.search.final_date = null;

	menu.value.calendar = false
};

// TODO: set bounds on init: ne_lat, ne_lng, sw_lat, sw_lng
const searchMap = reactive({
	show: true,
	bind: {
		zoom: 6,
		center: [-35.282001, 149.128998],
		onZoomend(ev) {
			searchMap.getBounds(ev.sourceTarget);
		},
		onMoveend(ev) {
			searchMap.getBounds(ev.sourceTarget);
		},
		onReady(instance) {
			if (
				!search.params.search.ne_lat ||
				!search.params.search.ne_lng ||
				!search.params.search.sw_lat ||
				!search.params.search.sw_lng
			)
				return;

			instance.fitBounds([
				[search.params.search.ne_lat, search.params.search.ne_lng],
				[search.params.search.sw_lat, search.params.search.sw_lng],
			]);
		},
	},
	markers: computed(() => {
		return search.response.data.entities.map((entity) => {
			return {
				bind: {
					latLng: {
						lat: parseFloat(entity.property_locations.latitude),
						lng: parseFloat(entity.property_locations.longitude),
					},
				},
			};
		});
	}),
	getBounds(instance) {
		const bounds = instance.getBounds();
		search.params.search.ne_lat = bounds._northEast.lat;
		search.params.search.ne_lng = bounds._northEast.lng;
		search.params.search.sw_lat = bounds._southWest.lat;
		search.params.search.sw_lng = bounds._southWest.lng;
		search.submit();
	},
});

const searchHelper = {
	defaults: {
		global: {
			rounded: 1,
			hideDetails: true,
			elevation: 1,
		},
		VTextField: {
			variant: "solo",
		},
		VSelect: {
			variant: "solo"
		},
		VBtn: {
			stacked: true,
			height: "58px",
			variant: "elevated",
			elevation: 1,
			class: "rounded",
		},
		VMenu: {
			offset: 15,
			location: "bottom center",
			closeOnContentClick: false,
			zIndex: 999999999,
		},
		VCard: {
			width: 340,
		},
	},
	guestsTotal: computed(() => {
		return 55;
	}),
};

const propertyTypes = useAxios({
	url: "/public/property_types",
	method: "get",
	autoSubmit: true,
	onSuccess({data}) {
		return data.data;
	},
	response: {
		data: {
			entities: [],
		},
	},
});

const fieldNames = computed(() => {
	let names = [];
	Object.entries(search.value.params).forEach(([name, value]) => {
		if (typeof value == "object" && value !== null) {
			Object.entries(value).forEach(([name2, value2]) => {
				if (typeof value2 === "object" && value2 !== null) {
					Object.entries(value2).forEach(([name3, value3]) => {
						if (value3 !== null) {
							names.push({
								name: `${name}[${name2 === 'holiday_types' ? 'amenities' : name2}][]`,
								value: value3,
							});
						}
					});
					return;
				}
				if (value2 !== null) {
					names.push({
						name: `${name}[${name2}]`,
						value: value2,
					});
				}
			});
			return;
		}
		// if (value !== null) {
		// 	names.push({name, value});
		// }
	});
	return names;
});


watch([search], ([searchNew]) => {
	search.value.params.search.guests =
		(Number(searchNew.params.search.guests_adults) || 0) +
		(Number(searchNew.params.search.guests_children) || 0);

	// Pet friendly amenities
	// const petFriendlyAmenities = [42, 159];
	// if (search.params.search.guests_pets) {
	//   petFriendlyAmenities.map((amenityId) => {
	//     const find = search.params.search.amenities.filter(
	//         (id) => id === amenityId,
	//     );
	//     if (find.length === 0) {
	//       search.params.search.amenities.push(amenityId);
	//     }
	//   });
	// } else {
	// petFriendlyAmenities.map((amenityId) => {
	//   search.params.search.amenities.map((id, amenityIndex) => {
	//     if (id === amenityId) {
	//       search.params.search.amenities.splice(amenityIndex, 1);
	//     }
	//   });
	// });
	// }
});

const clearGuests = () => {
	search.value.params.search.guests = 1
	search.value.params.search.guests_adults = 1
	search.value.params.search.guests_children = null
	search.value.params.search.guests_infant = null
	search.value.params.search.guests_pets = null

	menu.value.guests = false
}

const clearHouse = () => {
	search.value.params.search.property_types = []
	search.value.params.search.holiday_types = []
	search.value.params.search.amenities = []

	menu.value.house = false
}

const clearAdvancedFilters = () => {
	search.value.params.search.min_price = Number(priceRange.value.response.data.min_price || 0)
	search.value.params.search.max_price = Number(priceRange.value.response.data.max_price || 0)
	search.value.params.search.bedrooms = null
	search.value.params.search.bathrooms = null
	search.value.params.search.accessibility = false
	search.value.params.search.sustainability = false
	search.value.params.search.pets = false

	menu.value.advancedSearch = false
}
</script>

<style scoped>
.width-button {
	max-width: 150px;
}

.container-actions {
	gap: 15px;
}

.search-form-background {
  gap: 15px; 
  background-color: white; 
  box-shadow: 0 15px 20px rgba(0, 0, 0, 0.2); 
  padding: 1.5rem; 
  border-radius: 12px;
}

@media screen and (max-width: 380px) {
  .search-form-background {
    padding: 1rem 0.2rem;
  }
}

.title-select {
	width: 100%;
	-webkit-line-clamp: 1;
	text-overflow: ellipsis;
	overflow: hidden;
	white-space: nowrap;
	font-size: 14px;
}

@media screen and (max-width: 992px) {
	.width-button {
		max-width: 100%;
	}
}

@media screen and (max-width: 600px) {
	.width-button {
		width: 100%;
	}

	.container-actions {
		margin: 10px 0;
		width: 100%;
		justify-content: center;
	}
}
</style>
