<template>
	<div>
		<!-- Search + Filters -->
		<div v-if="hasSearch || hasFilters" class="flex flex-wrap gap-4 mb-8">
			<UInput
				v-if="hasSearch"
				v-model="search"
				placeholder="Search listings..."
				icon="i-lucide-search"
				class="w-full sm:w-72"
			/>
			<USelect
				v-if="hasFilters && categories.length"
				v-model="selectedCategory"
				:options="categoryOptions"
				placeholder="All Categories"
				class="w-48"
			/>
		</div>

		<!-- Grid / List -->
		<div :class="containerClasses">
			<XMarkDirectoryListingCard
				v-for="(listing, index) in paginatedListings"
				:key="listing.name + index"
				:listing="listing"
				:layout="layout === 'list' ? 'row' : 'card'"
				class="xFadeUp"
				:style="{ transitionDelay: `${index * 50}ms` }"
			/>
		</div>

		<!-- Empty State -->
		<div v-if="!paginatedListings.length" class="text-center py-20">
			<UIcon
				name="i-lucide-search-x"
				class="w-12 h-12 text-neutral-300 dark:text-neutral-700 mx-auto mb-4"
			/>
			<p
				class="text-lg font-medium text-neutral-700 dark:text-neutral-300 mb-1"
			>
				No listings found
			</p>
			<p class="text-sm text-neutral-500 dark:text-neutral-400">
				Try adjusting your search or filter criteria.
			</p>
			<UButton
				v-if="search || selectedCategory"
				label="Clear filters"
				variant="ghost"
				color="primary"
				size="sm"
				class="mt-4"
				@click="clearFilters"
			/>
		</div>

		<!-- Pagination -->
		<div
			v-if="hasPagination && totalPages > 1"
			class="mt-12 flex justify-center"
		>
			<UPagination
				v-model="currentPage"
				:total="filteredListings.length"
				:page-count="perPage"
			/>
		</div>
	</div>
</template>

<script setup>
// Initialize scroll reveal animations
useScrollReveal();

const props = defineProps({
	/** Array of listing objects */
	listings: {
		type: Array,
		default: () => [],
	},
	/** Available category strings for filter */
	categories: {
		type: Array,
		default: () => [],
	},
	/** Display mode */
	layout: {
		type: String,
		default: "grid",
		validator: (v) => ["grid", "list"].includes(v),
	},
	/** Number of columns in grid mode */
	columns: {
		type: Number,
		default: 3,
		validator: (v) => [2, 3, 4].includes(v),
	},
	/** Show search input */
	hasSearch: {
		type: Boolean,
		default: true,
	},
	/** Show category filter */
	hasFilters: {
		type: Boolean,
		default: true,
	},
	/** Show pagination */
	hasPagination: {
		type: Boolean,
		default: true,
	},
	/** Items per page */
	perPage: {
		type: Number,
		default: 12,
	},
	/** Optional button config passed through to each ListingCard */
	cardButton: {
		type: Object,
		default: null,
	},
});

const search = ref("");
const selectedCategory = ref("");
const currentPage = ref(1);

const categoryOptions = computed(() => {
	return [
		{ label: "All Categories", value: "" },
		...props.categories.map((cat) => ({
			label: cat,
			value: cat,
		})),
	];
});

const filteredListings = computed(() => {
	let result = props.listings;

	if (search.value) {
		const q = search.value.toLowerCase();
		result = result.filter(
			(item) =>
				item.name?.toLowerCase().includes(q) ||
				item.description?.toLowerCase().includes(q)
		);
	}

	if (selectedCategory.value) {
		result = result.filter((item) => item.category === selectedCategory.value);
	}

	return result;
});

const totalPages = computed(() => {
	return Math.ceil(filteredListings.value.length / props.perPage);
});

const paginatedListings = computed(() => {
	const start = (currentPage.value - 1) * props.perPage;
	const end = start + props.perPage;
	return filteredListings.value.slice(start, end);
});

const containerClasses = computed(() => {
	if (props.layout === "list") {
		return "flex flex-col gap-3";
	}
	const cols = {
		2: "grid sm:grid-cols-2 gap-6",
		3: "grid sm:grid-cols-2 lg:grid-cols-3 gap-6",
		4: "grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6",
	};
	return cols[props.columns] || cols[3];
});

const clearFilters = () => {
	search.value = "";
	selectedCategory.value = "";
};

// Reset pagination when filters change
watch([search, selectedCategory], () => {
	currentPage.value = 1;
});
</script>
