<?php echo message_box('success'); ?>
<?php echo message_box('error'); ?>

<?php
$payload = !empty($available_modules_payload) && is_array($available_modules_payload) ? $available_modules_payload : array();
$initial_modules = !empty($payload['modules']) && is_array($payload['modules']) ? array_values(array_filter($payload['modules'], 'is_array')) : array();
$last_synced = !empty($payload['last_synced']) ? $payload['last_synced'] : null;
?>

<div class="space-y-6" data-available-modules>
	<div class="overflow-hidden rounded-3xl border border-border bg-card shadow-sm">
		<div class="border-b border-border bg-gradient-to-r from-slate-50 via-background to-slate-50 px-6 py-6 dark:from-slate-950 dark:via-slate-900/70 dark:to-slate-950">
			<div class="flex flex-col gap-5 xl:flex-row xl:items-start xl:justify-between">
				<div class="min-w-0 flex-1">
					<div class="inline-flex items-center gap-2 rounded-full border border-border bg-background px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-muted-foreground shadow-sm">
						<i data-lucide="store" class="h-3.5 w-3.5"></i>
						<?= lang('available_modules') ?>
					</div>
					<div class="mt-4 max-w-3xl">
						<h1 class="text-2xl font-semibold tracking-tight text-foreground md:text-3xl"><?= lang('available_modules') ?></h1>
						<p class="mt-3 text-sm leading-6 text-muted-foreground">Browse installable modules, review cached availability, and refresh the catalog when you need the latest entries.</p>
					</div>
				</div>

				<div class="flex w-full flex-col gap-3 xl:max-w-xl">
					<div class="flex flex-wrap gap-3 text-xs text-muted-foreground">
						<span class="inline-flex items-center gap-2 rounded-full border border-border bg-background px-3 py-1.5 shadow-sm">
							<span class="font-semibold text-foreground" data-modules-count><?= count($initial_modules) ?></span>
							cached
						</span>
						<span class="inline-flex items-center gap-2 rounded-full border border-border bg-background px-3 py-1.5 shadow-sm">
							<i data-lucide="clock-3" class="h-3.5 w-3.5"></i>
							<span data-sync-time><?= !empty($last_synced) ? html_escape(date('M d, Y h:i A', strtotime($last_synced))) : 'Not synced yet' ?></span>
						</span>
						<span class="inline-flex items-center gap-2 rounded-full border border-border bg-background px-3 py-1.5 shadow-sm" data-sync-status-wrap>
							<span class="inline-flex h-2.5 w-2.5 rounded-full bg-emerald-500" data-sync-indicator></span>
							<span data-sync-status><?= !empty($initial_modules) ? 'Ready from cache' : 'Waiting for first sync' ?></span>
						</span>
					</div>
					<div class="flex items-center gap-2">
						<a href="<?= base_url('admin/my_module') ?>" class="inline-flex items-center justify-center gap-2 rounded-xl border border-border bg-background px-4 py-2 text-sm font-semibold text-foreground transition hover:bg-muted">
							<i data-lucide="arrow-left" class="h-4 w-4"></i>
							<?= lang('my_modules') ?>
						</a>
						<button type="button" data-sync-refresh class="inline-flex items-center justify-center gap-2 rounded-xl bg-slate-900 px-4 py-2 text-sm font-semibold text-white shadow-sm transition hover:bg-slate-800 dark:bg-slate-100 dark:text-slate-900 dark:hover:bg-white">
							<i data-lucide="refresh-cw" class="h-4 w-4"></i>
							Refresh Catalog
						</button>
					</div>
				</div>
			</div>
		</div>

		<div class="border-b border-border px-6 py-4">
			<div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
				<div class="max-w-xl">
					<h2 class="text-lg font-semibold text-foreground">Catalog</h2>
					<p class="text-sm text-muted-foreground">Search available modules, inspect pricing, and open preview pages without blocking the initial admin page load.</p>
				</div>
				<div class="flex flex-col gap-3 sm:flex-row sm:items-center shrink-0">
					<div class="inline-flex items-center rounded-2xl border border-border bg-background p-1 shadow-sm">
						<button type="button" data-available-filter="all" class="available-filter-btn rounded-xl px-3 py-2 text-xs font-semibold text-foreground transition hover:bg-muted">All</button>
						<button type="button" data-available-filter="priced" class="available-filter-btn rounded-xl px-3 py-2 text-xs font-semibold text-muted-foreground transition hover:bg-muted">With Price</button>
						<button type="button" data-available-filter="free" class="available-filter-btn rounded-xl px-3 py-2 text-xs font-semibold text-muted-foreground transition hover:bg-muted">No Price</button>
					</div>
					<div class="relative">
						<i data-lucide="search" class="pointer-events-none absolute left-3 top-3.5 h-4 w-4 text-muted-foreground"></i>
						<input type="search" placeholder="<?= lang('search_available_modules') ?>" data-available-search class="w-full rounded-xl border border-border bg-background py-2.5 pl-10 pr-4 text-sm text-foreground outline-none transition focus:border-sky-300 focus:ring-2 focus:ring-sky-500/10 sm:w-80">
					</div>
				</div>
			</div>
		</div>

		<div class="p-6">
			<div class="hidden rounded-2xl border border-rose-200 bg-rose-50 px-5 py-4 text-sm text-rose-700 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-300" data-store-error></div>

			<div class="grid gap-4 xl:grid-cols-2 2xl:grid-cols-3" data-available-grid>
				<?php foreach ($initial_modules as $module) : ?>
					<?php
					$name = $module['module_name'] ?? $module['name'] ?? 'Untitled Module';
					$description = $module['description'] ?? 'No description available.';
					$description_html = $module['description_html'] ?? '';
					$price = $module['price'] ?? null;
					$imageUrl = $module['image_url'] ?? null;
					$previewUrl = $module['preview_url'] ?? $module['uri'] ?? '#';
					$priceText = $module['price_text'] ?? (($price !== null && $price !== '') ? (string) $price : 'Contact Sales');
					?>
					<div class="available-module-card rounded-[28px] border border-border bg-background p-5 shadow-sm transition hover:-translate-y-0.5 hover:border-sky-200 hover:shadow-lg" data-price-mode="<?= ($price !== null && $price !== '') ? 'priced' : 'free' ?>" data-module-name="<?= html_escape(strtolower($name . ' ' . $description)) ?>">
						<div class="flex h-full flex-col justify-between gap-5">
							<div class="space-y-4">
								<div class="flex items-start justify-between gap-4">
									<div class="flex items-center gap-3">
										<div class="flex h-12 w-12 items-center justify-center rounded-2xl bg-gradient-to-br from-sky-500 to-indigo-500 text-white shadow-sm">
											<i data-lucide="package" class="h-5 w-5"></i>
										</div>
										<div class="space-y-1">
											<span class="inline-flex items-center gap-2 rounded-full border border-sky-200 bg-sky-50 px-2.5 py-1 text-[11px] font-semibold uppercase tracking-[0.2em] text-sky-700 dark:border-sky-900/40 dark:bg-sky-950/30 dark:text-sky-300">
												<i data-lucide="shield-check" class="h-3.5 w-3.5"></i>
												Verified
											</span>
										</div>
									</div>
									<div class="rounded-2xl border border-border bg-card px-3 py-2 text-right shadow-sm">
										<p class="text-[10px] font-semibold uppercase tracking-[0.2em] text-muted-foreground">Price</p>
										<p class="mt-1 text-base font-semibold text-foreground"><?= html_escape($priceText) ?></p>
									</div>
								</div>
								<?php if (!empty($imageUrl)) : ?>
									<div class="overflow-hidden rounded-2xl border border-border bg-slate-100 dark:bg-slate-900">
										<img src="<?= html_escape($imageUrl) ?>" alt="<?= html_escape($name) ?>" class="h-48 w-full object-cover object-top transition duration-300 hover:scale-[1.02]">
									</div>
								<?php endif; ?>
								<div>
									<h3 class="text-lg font-semibold text-foreground"><?= html_escape($name) ?></h3>
									<div class="mt-3 text-sm leading-6 text-muted-foreground">
										<p class="module-excerpt"><?= nl2br(html_escape($description)) ?></p>
									</div>
								</div>
							</div>
							<div class="flex items-center justify-between gap-3 border-t border-border pt-4">
								<div class="text-xs text-muted-foreground">
									<?= !empty($price) ? 'One-time purchase' : 'Pricing on request' ?>
								</div>
								<a href="<?= html_escape($previewUrl) ?>" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-2 rounded-xl bg-sky-600 px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-sky-500">
									<i data-lucide="arrow-up-right" class="h-4 w-4"></i>
									Preview
								</a>
							</div>
						</div>
					</div>
				<?php endforeach; ?>
			</div>

			<div class="<?= !empty($initial_modules) ? 'hidden ' : '' ?>mt-2" data-available-empty>
				<div class="flex min-h-[220px] flex-col items-center justify-center rounded-3xl border border-dashed border-border bg-background px-6 py-10 text-center">
					<div class="flex h-14 w-14 items-center justify-center rounded-2xl bg-muted text-muted-foreground">
						<i data-lucide="package-search" class="h-7 w-7"></i>
					</div>
					<h3 class="mt-4 text-lg font-semibold text-foreground">No modules loaded yet</h3>
					<p class="mt-2 max-w-md text-sm text-muted-foreground">The catalog will appear here after the first successful store sync.</p>
				</div>
			</div>

			<div class="hidden grid gap-4 xl:grid-cols-2 2xl:grid-cols-3" data-available-skeleton>
				<?php for ($i = 0; $i < 6; $i++) : ?>
					<div class="rounded-[28px] border border-border bg-background p-5 shadow-sm">
						<div class="animate-pulse space-y-4">
							<div class="flex items-start justify-between">
								<div class="h-12 w-12 rounded-2xl bg-slate-200 dark:bg-slate-800"></div>
								<div class="h-12 w-24 rounded-2xl bg-slate-200 dark:bg-slate-800"></div>
							</div>
							<div class="space-y-2">
								<div class="h-5 w-2/3 rounded bg-slate-200 dark:bg-slate-800"></div>
								<div class="h-4 w-full rounded bg-slate-200 dark:bg-slate-800"></div>
								<div class="h-4 w-5/6 rounded bg-slate-200 dark:bg-slate-800"></div>
							</div>
							<div class="h-10 w-28 rounded-xl bg-slate-200 dark:bg-slate-800"></div>
						</div>
					</div>
				<?php endfor; ?>
			</div>
		</div>
	</div>
</div>

<script id="available_modules_initial" type="application/json"><?= json_encode($payload); ?></script>
<style>
.module-excerpt {
	display: -webkit-box;
	-webkit-line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
</style>
<script>
(() => {
	const initialPayload = JSON.parse(document.getElementById('available_modules_initial').textContent || '{}');
	const grid = document.querySelector('[data-available-grid]');
	const emptyState = document.querySelector('[data-available-empty]');
	const skeleton = document.querySelector('[data-available-skeleton]');
	const errorBox = document.querySelector('[data-store-error]');
	const searchInput = document.querySelector('[data-available-search]');
	const countEl = document.querySelector('[data-modules-count]');
	const syncTimeEl = document.querySelector('[data-sync-time]');
	const syncStatusEl = document.querySelector('[data-sync-status]');
	const syncIndicator = document.querySelector('[data-sync-indicator]');
	const refreshBtn = document.querySelector('[data-sync-refresh]');
	const filterButtons = Array.from(document.querySelectorAll('[data-available-filter]'));
	let activeFilter = 'all';

	const escapeHtml = (value) => {
		const div = document.createElement('div');
		div.textContent = value == null ? '' : String(value);
		return div.innerHTML;
	};

	const setSyncState = (text, tone = 'ready') => {
		if (syncStatusEl) {
			syncStatusEl.textContent = text;
		}
		if (!syncIndicator) {
			return;
		}
		syncIndicator.className = 'inline-flex h-2.5 w-2.5 rounded-full';
		if (tone === 'loading') {
			syncIndicator.classList.add('bg-sky-500', 'animate-pulse');
		} else if (tone === 'error') {
			syncIndicator.classList.add('bg-rose-500');
		} else if (tone === 'warning') {
			syncIndicator.classList.add('bg-amber-500');
		} else {
			syncIndicator.classList.add('bg-emerald-500');
		}
	};

	const formatDate = (value) => {
		if (!value) {
			return 'Not synced yet';
		}
		try {
			return new Intl.DateTimeFormat(undefined, {
				year: 'numeric',
				month: 'short',
				day: '2-digit',
				hour: '2-digit',
				minute: '2-digit',
			}).format(new Date(value));
		} catch (error) {
			return value;
		}
	};

	const renderCards = (modules) => {
		if (!grid) {
			return;
		}
		const safeModules = Array.isArray(modules) ? modules.filter((module) => module && typeof module === 'object' && !Array.isArray(module)) : [];
		grid.innerHTML = safeModules.map((module) => {
			const name = module.module_name || module.name || 'Untitled Module';
			const description = module.description || 'No description available.';
			const price = module.price_text || (module.price !== undefined && module.price !== null && module.price !== '' ? String(module.price) : 'Contact Sales');
			const previewUrl = module.preview_url || module.uri || '#';
			const imageUrl = module.image_url || '';
			const priceMode = module.price !== undefined && module.price !== null && module.price !== '' ? 'priced' : 'free';
			const searchName = (name + ' ' + description).toLowerCase();

			return `
				<div class="available-module-card rounded-[28px] border border-border bg-background p-5 shadow-sm transition hover:-translate-y-0.5 hover:border-sky-200 hover:shadow-lg" data-price-mode="${priceMode}" data-module-name="${escapeHtml(searchName)}">
					<div class="flex h-full flex-col justify-between gap-5">
						<div class="space-y-4">
							<div class="flex items-start justify-between gap-4">
								<div class="flex items-center gap-3">
									<div class="flex h-12 w-12 items-center justify-center rounded-2xl bg-gradient-to-br from-sky-500 to-indigo-500 text-white shadow-sm">
										<i data-lucide="package" class="h-5 w-5"></i>
									</div>
									<div class="space-y-1">
										<span class="inline-flex items-center gap-2 rounded-full border border-sky-200 bg-sky-50 px-2.5 py-1 text-[11px] font-semibold uppercase tracking-[0.2em] text-sky-700 dark:border-sky-900/40 dark:bg-sky-950/30 dark:text-sky-300">
											<i data-lucide="shield-check" class="h-3.5 w-3.5"></i>
											Verified
										</span>
									</div>
								</div>
								<div class="rounded-2xl border border-border bg-card px-3 py-2 text-right shadow-sm">
									<p class="text-[10px] font-semibold uppercase tracking-[0.2em] text-muted-foreground">Price</p>
									<p class="mt-1 text-base font-semibold text-foreground">${escapeHtml(price)}</p>
								</div>
							</div>
							${imageUrl ? `<div class="overflow-hidden rounded-2xl border border-border bg-slate-100 dark:bg-slate-900"><img src="${escapeHtml(imageUrl)}" alt="${escapeHtml(name)}" class="h-48 w-full object-cover object-top transition duration-300 hover:scale-[1.02]"></div>` : ''}
							<div>
								<h3 class="text-lg font-semibold text-foreground">${escapeHtml(name)}</h3>
								<div class="mt-3 text-sm leading-6 text-muted-foreground"><p class="module-excerpt">${escapeHtml(description).replace(/\n/g, '<br>')}</p></div>
							</div>
						</div>
						<div class="flex items-center justify-between gap-3 border-t border-border pt-4">
							<div class="text-xs text-muted-foreground">${priceMode === 'priced' ? 'One-time purchase' : 'Pricing on request'}</div>
							<a href="${escapeHtml(previewUrl)}" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-2 rounded-xl bg-sky-600 px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-sky-500">
								<i data-lucide="arrow-up-right" class="h-4 w-4"></i>
								Preview
							</a>
						</div>
					</div>
				</div>
			`;
		}).join('');

		if (window.lucide && typeof window.lucide.createIcons === 'function') {
			window.lucide.createIcons();
		}
	};

	const applyFilters = () => {
		const cards = Array.from(document.querySelectorAll('.available-module-card'));
		const keyword = (searchInput?.value || '').trim().toLowerCase();
		let visibleCount = 0;
		cards.forEach((card) => {
			const priceMode = card.getAttribute('data-price-mode') || 'free';
			const haystack = card.getAttribute('data-module-name') || '';
			const matchesSearch = keyword === '' || haystack.includes(keyword);
			const matchesFilter =
				activeFilter === 'all' ||
				(activeFilter === 'priced' && priceMode === 'priced') ||
				(activeFilter === 'free' && priceMode === 'free');
			const visible = matchesSearch && matchesFilter;
			card.classList.toggle('hidden', !visible);
			if (visible) {
				visibleCount++;
			}
		});
		if (emptyState) {
			emptyState.classList.toggle('hidden', visibleCount > 0 || cards.length === 0 ? cards.length > 0 : false);
		}
		if (countEl && cards.length > 0) {
			countEl.textContent = String(visibleCount);
		}
	};

	const setLoading = (loading) => {
		if (refreshBtn) {
			refreshBtn.disabled = loading;
			refreshBtn.classList.toggle('opacity-70', loading);
		}
		if (skeleton) {
			skeleton.classList.toggle('hidden', !loading);
		}
	};

	const showError = (message) => {
		if (!errorBox) {
			return;
		}
		if (message) {
			errorBox.textContent = message;
			errorBox.classList.remove('hidden');
		} else {
			errorBox.textContent = '';
			errorBox.classList.add('hidden');
		}
	};

	const syncModules = async (force = false) => {
		setLoading(true);
		showError(null);
		setSyncState(force ? 'Refreshing store catalog…' : 'Syncing catalog…', 'loading');

		try {
			const response = await fetch(`<?= base_url('admin/my_module/available_modules_feed') ?>${force ? '?refresh=1' : ''}`, {
				headers: { 'X-Requested-With': 'XMLHttpRequest' },
			});
			const payload = await response.json();
			if (!payload.success && (!payload.modules || !payload.modules.length)) {
				throw new Error(payload.message || 'Unable to load available modules.');
			}

			const modules = Array.isArray(payload.modules) ? payload.modules.filter((module) => module && typeof module === 'object' && !Array.isArray(module)) : [];
			renderCards(modules);
			if (countEl) {
				countEl.textContent = String(modules.length);
			}
			if (syncTimeEl) {
				syncTimeEl.textContent = formatDate(payload.last_synced);
			}
			if (emptyState) {
				emptyState.classList.toggle('hidden', modules.length > 0);
			}
			if (payload.stale) {
				setSyncState(payload.message || 'Showing cached results', 'warning');
			} else {
				setSyncState(payload.from_cache ? 'Loaded from cache' : 'Catalog synced', 'ready');
			}
			showError(payload.success ? null : payload.message);
			applyFilters();
		} catch (error) {
			setSyncState('Catalog sync failed', 'error');
			showError(error.message || 'Unable to load available modules.');
		} finally {
			setLoading(false);
		}
	};

	searchInput?.addEventListener('input', applyFilters);
	filterButtons.forEach((button) => {
		button.addEventListener('click', () => {
			activeFilter = button.getAttribute('data-available-filter') || 'all';
			filterButtons.forEach((item) => {
				const selected = item === button;
				item.classList.toggle('bg-sky-600', selected);
				item.classList.toggle('text-white', selected);
				item.classList.toggle('shadow-sm', selected);
				item.classList.toggle('text-foreground', !selected);
				item.classList.toggle('text-muted-foreground', !selected);
			});
			applyFilters();
		});
	});
	if (filterButtons.length) {
		filterButtons[0].click();
	}
	refreshBtn?.addEventListener('click', () => syncModules(true));

	if (!initialPayload.modules || !initialPayload.modules.length) {
		syncModules(false);
	} else {
		applyFilters();
		setSyncState(initialPayload.stale ? 'Showing cached results' : 'Ready from cache', initialPayload.stale ? 'warning' : 'ready');
		if (initialPayload.message) {
			showError(initialPayload.message);
		}
		setTimeout(() => syncModules(false), 300);
	}
})();
</script>
