<script lang="ts">
	import { UpdateRevenueStore, UpdateProjectStore } from '$houdini';
	import { fromGlobalId } from '$lib/utils/relay';
	import IconSpinner from '$lib/components/icons/IconSpinner.svelte';
	import type { WaveProduct } from './types';

	interface Props {
		open: boolean;
		entityType: 'revenue' | 'project';
		entityId: string;
		entityDescription: string;
		currentWaveServiceId: string | null;
		waveProducts: WaveProduct[];
		onSuccess: () => void;
		onCancel: () => void;
	}

	let {
		open,
		entityType,
		entityId,
		entityDescription,
		currentWaveServiceId,
		waveProducts,
		onSuccess,
		onCancel
	}: Props = $props();

	let submitting = $state(false);
	let error = $state('');
	let searchQuery = $state('');
	let selectedProductId = $state<string | null>(null);

	// Reset state when modal opens
	$effect(() => {
		if (open) {
			selectedProductId = currentWaveServiceId;
			searchQuery = '';
			error = '';
		}
	});

	// Decode Wave ID to match backend storage format
	function decodeWaveId(id: string): string {
		return fromGlobalId(id);
	}

	// Filter products by search query
	let filteredProducts = $derived.by(() => {
		const active = waveProducts.filter((p) => !p.isArchived);
		if (!searchQuery.trim()) return active;
		const query = searchQuery.toLowerCase();
		return active.filter((p) => {
			const name = p.name.toLowerCase();
			const description = p.description?.toLowerCase() ?? '';
			return name.includes(query) || description.includes(query);
		});
	});

	// Format currency
	function formatCurrency(value: number): string {
		return new Intl.NumberFormat('en-US', {
			style: 'currency',
			currency: 'USD'
		}).format(value);
	}

	const updateRevenueStore = new UpdateRevenueStore();
	const updateProjectStore = new UpdateProjectStore();

	async function handleSave() {
		submitting = true;
		error = '';

		try {
			if (entityType === 'revenue') {
				const res = await updateRevenueStore.mutate({
					input: {
						id: entityId,
						waveServiceId: selectedProductId ?? ''
					}
				});

				if (res.errors?.length) {
					error = res.errors.map((e) => e.message).join(', ');
					return;
				}
			} else {
				const res = await updateProjectStore.mutate({
					input: {
						id: entityId,
						waveServiceId: selectedProductId ?? ''
					}
				});

				if (res.errors?.length) {
					error = res.errors.map((e) => e.message).join(', ');
					return;
				}
			}

			onSuccess();
		} catch (err) {
			error = err instanceof Error ? err.message : 'Failed to save';
		} finally {
			submitting = false;
		}
	}

	function handleBackdropClick(e: MouseEvent) {
		if (e.target === e.currentTarget) {
			onCancel();
		}
	}
</script>

{#if open}
	<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
	<div
		class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4"
		role="dialog"
		aria-modal="true"
		tabindex="-1"
		onclick={handleBackdropClick}
		onkeydown={(e) => e.key === 'Escape' && onCancel()}
	>
		<div
			class="flex max-h-[80vh] w-full max-w-lg flex-col rounded-xl bg-theme shadow-xl"
			onclick={(e) => e.stopPropagation()}
			onkeydown={() => {}}
			role="document"
		>
			<!-- Header -->
			<div class="flex items-center justify-between border-b border-theme px-6 py-4">
				<div>
					<h2 class="text-lg font-semibold text-theme">Link Wave Product</h2>
					<p class="mt-0.5 text-sm text-theme-muted">{entityDescription}</p>
				</div>
				<button
					type="button"
					onclick={onCancel}
					class="rounded-lg p-2 text-theme-muted hover:bg-black/5 hover:text-theme dark:hover:bg-white/10"
					aria-label="Close"
				>
					<svg class="h-5 w-5" style="fill: none" stroke="currentColor" viewBox="0 0 24 24">
						<path
							stroke-linecap="round"
							stroke-linejoin="round"
							stroke-width="2"
							d="M6 18L18 6M6 6l12 12"
						/>
					</svg>
				</button>
			</div>

			<!-- Content -->
			<div class="flex min-h-0 flex-1 flex-col p-6">
				{#if error}
					<div class="mb-4 alert-error">
						{error}
					</div>
				{/if}

				<!-- Search -->
				<div class="mb-4">
					<div class="relative">
						<svg
							class="absolute top-1/2 left-3 h-5 w-5 -translate-y-1/2 text-theme-muted"
							style="fill: none"
							stroke="currentColor"
							viewBox="0 0 24 24"
						>
							<path
								stroke-linecap="round"
								stroke-linejoin="round"
								stroke-width="2"
								d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
							/>
						</svg>
						<input
							type="text"
							bind:value={searchQuery}
							placeholder="Search Wave products..."
							class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme py-2 pr-4 pl-10 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
						/>
					</div>
				</div>

				<!-- Product List -->
				<div class="min-h-0 flex-1 overflow-y-auto">
					{#if filteredProducts.length === 0 && !searchQuery}
						<div class="py-8 text-center text-theme-muted">No Wave products found.</div>
					{:else if filteredProducts.length === 0}
						<div class="py-8 text-center text-theme-muted">No products match your search.</div>
					{:else}
						<div class="space-y-2">
							<!-- Option to unlink -->
							<button
								type="button"
								onclick={() => (selectedProductId = null)}
								class="w-full rounded-lg border p-3 text-left transition-colors {selectedProductId ===
								null
									? 'border-primary-500 bg-primary-500/10'
									: 'border-theme bg-theme hover:bg-black/5 dark:hover:bg-white/10'}"
							>
								<span class="flex items-center gap-3">
									<span
										class="flex h-5 w-5 items-center justify-center rounded-full border-2 {selectedProductId ===
										null
											? 'border-primary-500'
											: 'border-theme-muted'}"
									>
										{#if selectedProductId === null}
											<div class="h-2.5 w-2.5 rounded-full bg-primary-500"></div>
										{/if}
									</span>
									<span class="text-theme-muted italic">No product (unlink)</span>
								</span>
							</button>

							{#each filteredProducts as product (product.id)}
								{@const decodedId = decodeWaveId(product.id)}
								<button
									type="button"
									onclick={() => (selectedProductId = decodedId)}
									class="w-full rounded-lg border p-3 text-left transition-colors {selectedProductId ===
									decodedId
										? 'border-primary-500 bg-primary-500/10'
										: 'border-theme bg-theme hover:bg-black/5 dark:hover:bg-white/10'}"
								>
									<span class="flex items-start gap-3">
										<span
											class="mt-0.5 flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full border-2 {selectedProductId ===
											decodedId
												? 'border-primary-500'
												: 'border-theme-muted'}"
										>
											{#if selectedProductId === decodedId}
												<div class="h-2.5 w-2.5 rounded-full bg-primary-500"></div>
											{/if}
										</span>
										<span class="min-w-0 flex-1">
											<span class="flex items-center justify-between gap-2">
												<span class="font-medium text-theme">{product.name}</span>
												<span
													class="text-sm font-semibold text-secondary-600 dark:text-secondary-400"
												>
													{formatCurrency(product.unitPrice)}
												</span>
											</span>
											{#if product.description}
												<p class="mt-0.5 truncate text-sm text-theme-muted">
													{product.description}
												</p>
											{/if}
										</span>
									</span>
								</button>
							{/each}
						</div>
					{/if}
				</div>
			</div>

			<!-- Footer -->
			<div class="flex items-center gap-3 border-t border-theme px-6 py-4">
				<button
					type="button"
					onclick={handleSave}
					disabled={submitting}
					class="flex-1 rounded-lg bg-primary-500 px-4 py-2 font-medium text-white transition-colors hover:bg-primary-600 disabled:cursor-not-allowed disabled:opacity-50"
				>
					{#if submitting}
						<span class="flex items-center justify-center gap-2">
							<IconSpinner class="h-4 w-4" />
							<span>Saving...</span>
						</span>
					{:else}
						Save
					{/if}
				</button>
				<button
					type="button"
					onclick={onCancel}
					disabled={submitting}
					class="rounded-lg border border-theme bg-theme px-4 py-2 font-medium text-theme transition-colors hover:bg-black/5 disabled:cursor-not-allowed disabled:opacity-50 dark:hover:bg-white/10"
				>
					Cancel
				</button>
			</div>
		</div>
	</div>
{/if}
