<script lang="ts">
	import { enhance } from '$app/forms';
	import IconSpinner from '$lib/components/icons/IconSpinner.svelte';
	import type { WaveInvoice, WaveInvoiceItem, WaveProduct } from './types';

	interface EditableLineItem {
		productId: string;
		productName: string;
		description: string;
		quantity: number;
		unitPrice: number;
	}

	interface Props {
		waveInvoice: WaveInvoice;
		waveProducts: WaveProduct[];
		onSuccess: () => void;
		onCancel: () => void;
	}

	let { waveInvoice, waveProducts, onSuccess, onCancel }: Props = $props();

	let submitting = $state(false);
	let error = $state('');

	// Form state - pre-populated from Wave invoice
	let invoiceDate = $state(waveInvoice.invoiceDate);
	let dueDate = $state(waveInvoice.dueDate);
	let memo = $state(waveInvoice.memo || '');
	let footer = $state(waveInvoice.footer || '');

	// Line items state - built from Wave invoice items
	let lineItems = $state<EditableLineItem[]>(buildLineItemsFromInvoice());

	// Add line item state
	let showAddLineItem = $state(false);
	let newProductId = $state('');
	let newDescription = $state('');
	let newQuantity = $state(1);
	let newUnitPrice = $state(0);

	// Discount state - initialize from existing Wave invoice discount
	let hasDiscount = $state(parseFloat(waveInvoice.discountTotal.value) > 0);
	let discountType = $state<'PERCENTAGE' | 'FIXED'>('PERCENTAGE');
	let discountName = $state('Discount');
	let discountValue = $state(0);

	// Active (non-archived) products for the dropdown
	let activeProducts = $derived(waveProducts.filter((p) => !p.isArchived));

	function buildLineItemsFromInvoice(): EditableLineItem[] {
		return waveInvoice.items.map((item: WaveInvoiceItem) => ({
			productId: item.product.id,
			productName: item.product.name,
			description: item.description || '',
			quantity: item.quantity,
			unitPrice: item.unitPrice
		}));
	}

	// Calculate totals
	let subtotal = $derived(lineItems.reduce((sum, item) => sum + item.quantity * item.unitPrice, 0));

	let discountAmount = $derived(() => {
		if (!hasDiscount || discountValue <= 0) return 0;
		if (discountType === 'PERCENTAGE') {
			return subtotal * (discountValue / 100);
		}
		return discountValue;
	});

	let total = $derived(subtotal - discountAmount());

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

	function updateLineItem(index: number, field: keyof EditableLineItem, value: string | number) {
		lineItems[index] = { ...lineItems[index], [field]: value };
	}

	function removeLineItem(index: number) {
		lineItems = lineItems.filter((_, i) => i !== index);
	}

	function handleProductSelect(productId: string) {
		const product = waveProducts.find((p) => p.id === productId);
		if (product) {
			newUnitPrice = product.unitPrice;
			newDescription = product.description || '';
		}
	}

	function addLineItem() {
		if (!newProductId) return;

		const product = waveProducts.find((p) => p.id === newProductId);
		if (!product) return;

		lineItems = [
			...lineItems,
			{
				productId: product.id,
				productName: product.name,
				description: newDescription,
				quantity: newQuantity,
				unitPrice: newUnitPrice
			}
		];

		// Reset add line item form
		showAddLineItem = false;
		newProductId = '';
		newDescription = '';
		newQuantity = 1;
		newUnitPrice = 0;
	}

	function cancelAddLineItem() {
		showAddLineItem = false;
		newProductId = '';
		newDescription = '';
		newQuantity = 1;
		newUnitPrice = 0;
	}

	// Build items JSON for form submission
	// Wave API expects the product's Global ID
	let itemsJson = $derived(
		JSON.stringify(
			lineItems.map((item) => ({
				productId: item.productId,
				description: item.description,
				quantity: item.quantity.toString(),
				unitPrice: item.unitPrice.toString()
			}))
		)
	);

	// Build discount JSON for form submission
	let discountJson = $derived(() => {
		if (!hasDiscount || discountValue <= 0) return null;
		return JSON.stringify({
			type: discountType,
			name: discountName,
			value: discountValue
		});
	});
</script>

<form
	method="POST"
	action="?/updateWaveInvoice"
	use:enhance={() => {
		submitting = true;
		error = '';
		return async ({ result }) => {
			submitting = false;
			if (result.type === 'failure') {
				const errorMsg = result.data?.error;
				error = typeof errorMsg === 'string' ? errorMsg : 'Failed to update invoice';
			} else if (result.type === 'success') {
				onSuccess();
			}
		};
	}}
	class="space-y-6"
>
	<!-- Hidden fields for form action -->
	<input type="hidden" name="invoiceId" value={waveInvoice.id} />
	<input type="hidden" name="items" value={itemsJson} />
	<input type="hidden" name="discount" value={discountJson() || ''} />

	<!-- Header -->
	<div class="card-padded">
		<div class="flex items-center justify-between">
			<div>
				<h3 class="text-lg font-semibold text-theme">
					Edit Invoice #{waveInvoice.invoiceNumber}
				</h3>
				<p class="mt-1 text-sm text-theme-muted">Modify invoice details and line items.</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="Cancel"
			>
				<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>
	</div>

	{#if error}
		<div class="mx-4 alert-error">
			{error}
		</div>
	{/if}

	<!-- Invoice Details -->
	<div class="card-padded">
		<h4 class="mb-4 text-sm font-medium text-theme-muted">Invoice Details</h4>
		<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
			<div>
				<label for="invoiceDate" class="mb-1 block text-sm font-medium text-theme">
					Invoice Date
				</label>
				<input
					type="date"
					id="invoiceDate"
					name="invoiceDate"
					bind:value={invoiceDate}
					class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
				/>
			</div>
			<div>
				<label for="dueDate" class="mb-1 block text-sm font-medium text-theme">Due Date</label>
				<input
					type="date"
					id="dueDate"
					name="dueDate"
					bind:value={dueDate}
					class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
				/>
			</div>
		</div>
	</div>

	<!-- Line Items -->
	<div class="card-padded">
		<div class="mb-4 flex items-center justify-between">
			<h4 class="text-sm font-medium text-theme-muted">
				Line Items ({lineItems.length})
			</h4>
			{#if !showAddLineItem}
				<button
					type="button"
					onclick={() => (showAddLineItem = true)}
					class="flex items-center gap-1.5 rounded-lg bg-accent6-500/10 px-3 py-1.5 text-sm font-medium text-accent6-600 transition-colors hover:bg-accent6-500/20 dark:text-accent6-400"
				>
					<svg class="h-4 w-4" style="fill: none" stroke="currentColor" viewBox="0 0 24 24">
						<path
							stroke-linecap="round"
							stroke-linejoin="round"
							stroke-width="2"
							d="M12 4v16m8-8H4"
						/>
					</svg>
					Add Item
				</button>
			{/if}
		</div>

		<div class="space-y-4">
			{#each lineItems as item, index (item.productId + '-' + index)}
				<div class="rounded-lg border border-theme bg-theme-secondary p-4">
					<div class="mb-3 flex items-start justify-between gap-2">
						<div>
							<span class="text-sm font-medium text-theme">{item.productName}</span>
						</div>
						<div class="flex items-center gap-2">
							<span class="text-sm font-semibold text-theme">
								{formatCurrency(item.quantity * item.unitPrice)}
							</span>
							<button
								type="button"
								onclick={() => removeLineItem(index)}
								class="rounded p-1 text-theme-muted transition-colors hover:bg-error-500/10 hover:text-error-600 dark:hover:text-error-400"
								title="Remove line item"
							>
								<svg class="h-4 w-4" 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>
					</div>

					<div class="grid grid-cols-1 gap-3 sm:grid-cols-3">
						<div class="sm:col-span-2">
							<label for="line-item-desc-{index}" class="mb-1 block text-xs text-theme-muted"
								>Description</label
							>
							<input
								type="text"
								id="line-item-desc-{index}"
								value={item.description}
								onchange={(e) => updateLineItem(index, 'description', e.currentTarget.value)}
								class="w-full rounded border border-theme bg-theme px-2 py-1.5 text-sm text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
							/>
						</div>
						<div class="grid grid-cols-2 gap-2">
							<div>
								<label for="line-item-qty-{index}" class="mb-1 block text-xs text-theme-muted"
									>Qty</label
								>
								<input
									type="number"
									id="line-item-qty-{index}"
									min="0"
									step="1"
									value={item.quantity}
									onchange={(e) =>
										updateLineItem(index, 'quantity', parseFloat(e.currentTarget.value) || 0)}
									class="w-full rounded border border-theme bg-theme px-2 py-1.5 text-sm text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
								/>
							</div>
							<div>
								<label for="line-item-price-{index}" class="mb-1 block text-xs text-theme-muted"
									>Price</label
								>
								<input
									type="number"
									id="line-item-price-{index}"
									min="0"
									step="0.01"
									value={item.unitPrice}
									onchange={(e) =>
										updateLineItem(index, 'unitPrice', parseFloat(e.currentTarget.value) || 0)}
									class="w-full rounded border border-theme bg-theme px-2 py-1.5 text-sm text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
								/>
							</div>
						</div>
					</div>
				</div>
			{/each}

			<!-- Add Line Item Form -->
			{#if showAddLineItem}
				<div class="rounded-lg border-2 border-dashed border-accent6-500/30 bg-accent6-500/5 p-4">
					<h5 class="mb-3 text-sm font-medium text-theme">Add New Line Item</h5>
					<div class="space-y-3">
						<div>
							<label for="new-product" class="mb-1 block text-xs text-theme-muted">Product</label>
							<select
								id="new-product"
								bind:value={newProductId}
								onchange={(e) => handleProductSelect(e.currentTarget.value)}
								class="w-full rounded border border-theme bg-theme px-2 py-1.5 text-sm text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
							>
								<option value="">Select a product...</option>
								{#each activeProducts as product (product.id)}
									<option value={product.id}>{product.name}</option>
								{/each}
							</select>
						</div>
						<div>
							<label for="new-description" class="mb-1 block text-xs text-theme-muted"
								>Description</label
							>
							<input
								type="text"
								id="new-description"
								bind:value={newDescription}
								placeholder="Optional description..."
								class="placeholder-theme-muted w-full rounded border border-theme bg-theme px-2 py-1.5 text-sm text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
							/>
						</div>
						<div class="grid grid-cols-2 gap-3">
							<div>
								<label for="new-quantity" class="mb-1 block text-xs text-theme-muted"
									>Quantity</label
								>
								<input
									type="number"
									id="new-quantity"
									min="1"
									step="1"
									bind:value={newQuantity}
									class="w-full rounded border border-theme bg-theme px-2 py-1.5 text-sm text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
								/>
							</div>
							<div>
								<label for="new-price" class="mb-1 block text-xs text-theme-muted">Unit Price</label
								>
								<input
									type="number"
									id="new-price"
									min="0"
									step="0.01"
									bind:value={newUnitPrice}
									class="w-full rounded border border-theme bg-theme px-2 py-1.5 text-sm text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
								/>
							</div>
						</div>
						<div class="flex items-center gap-2 pt-2">
							<button
								type="button"
								onclick={addLineItem}
								disabled={!newProductId}
								class="rounded-lg bg-accent6-500 px-3 py-1.5 text-sm font-medium text-white transition-colors hover:bg-accent6-600 disabled:cursor-not-allowed disabled:opacity-50"
							>
								Add Item
							</button>
							<button
								type="button"
								onclick={cancelAddLineItem}
								class="rounded-lg border border-theme interactive bg-theme px-3 py-1.5 text-sm font-medium text-theme"
							>
								Cancel
							</button>
						</div>
					</div>
				</div>
			{/if}
		</div>

		<!-- Subtotal -->
		<div class="mt-4 flex items-center justify-between border-t border-theme pt-4">
			<span class="font-medium text-theme">Subtotal</span>
			<span class="text-lg font-bold text-theme">
				{formatCurrency(subtotal)}
			</span>
		</div>

		<!-- Discount -->
		{#if hasDiscount && discountAmount() > 0}
			<div class="flex items-center justify-between py-2">
				<span class="text-theme-secondary">Discount ({discountName})</span>
				<span class="font-medium text-success-600 dark:text-success-400">
					-{formatCurrency(discountAmount())}
				</span>
			</div>
		{/if}

		<!-- Total -->
		<div class="flex items-center justify-between border-t border-theme pt-4">
			<span class="font-medium text-theme">Total</span>
			<span class="text-lg font-bold text-accent6-600 dark:text-accent6-400">
				{formatCurrency(total)}
			</span>
		</div>
	</div>

	<!-- Discount Section -->
	<div class="card-padded">
		<div class="mb-4 flex items-center justify-between">
			<h4 class="text-sm font-medium text-theme-muted">Discount</h4>
			<label class="inline-flex cursor-pointer items-center gap-2">
				<input type="checkbox" bind:checked={hasDiscount} class="peer sr-only" />
				<span
					class="relative h-5 w-9 rounded-full bg-gray-300 peer-checked:bg-accent6-500 after:absolute after:start-[2px] after:top-[2px] after:h-4 after:w-4 after:rounded-full after:bg-white after:transition-all after:content-[''] peer-checked:after:translate-x-full dark:bg-gray-600"
				></span>
				<span class="text-sm text-theme">{hasDiscount ? 'Enabled' : 'Disabled'}</span>
			</label>
		</div>

		{#if hasDiscount}
			<div class="space-y-4">
				<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
					<div>
						<label for="discountType" class="mb-1 block text-sm font-medium text-theme">Type</label>
						<select
							id="discountType"
							bind:value={discountType}
							class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
						>
							<option value="PERCENTAGE">Percentage</option>
							<option value="FIXED">Fixed Amount</option>
						</select>
					</div>
					<div>
						<label for="discountName" class="mb-1 block text-sm font-medium text-theme">Name</label>
						<input
							type="text"
							id="discountName"
							bind:value={discountName}
							placeholder="Discount"
							class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
						/>
					</div>
					<div>
						<label for="discountValue" class="mb-1 block text-sm font-medium text-theme">
							{discountType === 'PERCENTAGE' ? 'Percentage (%)' : 'Amount ($)'}
						</label>
						<input
							type="number"
							id="discountValue"
							min="0"
							step={discountType === 'PERCENTAGE' ? '1' : '0.01'}
							max={discountType === 'PERCENTAGE' ? '100' : undefined}
							bind:value={discountValue}
							placeholder={discountType === 'PERCENTAGE' ? '10' : '50.00'}
							class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
						/>
					</div>
				</div>
				{#if discountValue > 0}
					<p class="text-sm text-theme-muted">
						{#if discountType === 'PERCENTAGE'}
							{discountValue}% off = -{formatCurrency(discountAmount())}
						{:else}
							Fixed discount of {formatCurrency(discountValue)}
						{/if}
					</p>
				{/if}
			</div>
		{/if}
	</div>

	<!-- Notes -->
	<div class="card-padded">
		<h4 class="mb-4 text-sm font-medium text-theme-muted">Additional Notes</h4>
		<div class="space-y-4">
			<div>
				<label for="memo" class="mb-1 block text-sm font-medium text-theme">Memo (Notes)</label>
				<textarea
					id="memo"
					name="memo"
					bind:value={memo}
					rows="2"
					placeholder="Internal notes for the invoice..."
					class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
				></textarea>
			</div>
			<div>
				<label for="footer" class="mb-1 block text-sm font-medium text-theme">Footer</label>
				<textarea
					id="footer"
					name="footer"
					bind:value={footer}
					rows="2"
					placeholder="Footer text shown on the invoice..."
					class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500"
				></textarea>
			</div>
		</div>
	</div>

	<!-- Actions -->
	<div class="card-padded">
		<div class="flex items-center gap-3">
			<button
				type="submit"
				disabled={submitting || lineItems.length === 0}
				class="flex-1 rounded-lg bg-accent6-500 px-4 py-2.5 font-medium text-white transition-colors hover:bg-accent6-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 Changes...</span>
					</span>
				{:else}
					Save Changes
				{/if}
			</button>
			<button
				type="button"
				onclick={onCancel}
				disabled={submitting}
				class="rounded-lg border border-theme bg-theme px-4 py-2.5 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>
</form>
