<script lang="ts">
	import { goto, invalidateAll } from '$app/navigation';
	import { client } from '$lib/graphql/client';
	import type { PageData } from './$types';
	import { ContentContainer } from '$lib/components/layout';
	import { PageHeader, SectionHeader } from '$lib/components/admin';
	import FormDrawer from '$lib/components/drawers/FormDrawer.svelte';
	import type {
		InvoiceDetail,
		InvoiceStatus,
		EligibleRevenue,
		EligibleInvoiceProject
	} from '$lib/graphql/queries/invoices';
	import {
		UPDATE_INVOICE,
		DELETE_INVOICE,
		ADD_REVENUE_TO_INVOICE,
		ADD_PROJECT_TO_INVOICE,
		REMOVE_REVENUE_FROM_INVOICE,
		REMOVE_PROJECT_FROM_INVOICE,
		ADD_ALL_ELIGIBLE_REVENUES,
		ADD_ALL_ELIGIBLE_PROJECTS
	} from '$lib/graphql/mutations/invoices';
	import {
		WAVE_CUSTOMERS,
		WAVE_INVOICE,
		WAVE_PRODUCTS,
		type WaveInvoiceReadiness,
		type WaveCustomer,
		type WaveInvoice,
		type WaveProduct
	} from '$lib/graphql/queries/wave';
	import { CREATE_WAVE_INVOICE, LINK_CUSTOMER_TO_WAVE } from '$lib/graphql/mutations/wave';
	import WaveLinkForm from '$lib/components/forms/WaveLinkForm.svelte';

	let { data }: { data: PageData } = $props();

	let invoice = $derived(data.invoice as InvoiceDetail);
	let eligibleRevenues = $derived(data.eligibleRevenues as EligibleRevenue[]);
	let eligibleProjects = $derived(data.eligibleProjects as EligibleInvoiceProject[]);
	let waveReadiness = $derived(data.waveReadiness as WaveInvoiceReadiness | null);

	// State
	let isUpdating = $state(false);
	let isDeleting = $state(false);
	let showDeleteConfirm = $state(false);
	let showAddRevenuesModal = $state(false);
	let showAddProjectsModal = $state(false);
	let addingRevenueId = $state<string | null>(null);
	let addingProjectId = $state<string | null>(null);
	let removingId = $state<string | null>(null);

	// Wave state
	let waveCustomers = $state<WaveCustomer[]>([]);
	let waveInvoice = $state<WaveInvoice | null>(null);
	let isSyncingWave = $state(false);
	let waveError = $state<string | null>(null);
	let showLinkCustomerModal = $state(false);
	let selectedWaveCustomerId = $state<string>('');

	// Wave product linking state
	let waveProducts = $state<WaveProduct[]>([]);
	let showWaveLinkDrawer = $state(false);
	let waveLinkTarget = $state<{
		type: 'revenue' | 'project';
		id: string;
		currentWaveServiceId: string | null;
		itemName: string;
	} | null>(null);

	// Fetch Wave invoice details when synced
	$effect(() => {
		if (invoice?.waveInvoiceId) {
			client
				.query<{ waveInvoice: WaveInvoice }>({
					query: WAVE_INVOICE,
					variables: { invoiceId: invoice.waveInvoiceId }
				})
				.then((result) => {
					waveInvoice = result.data?.waveInvoice ?? null;
				})
				.catch((err) => {
					console.error('Failed to fetch Wave invoice:', err);
				});
		}
	});

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

	function formatDate(dateStr: string): string {
		const date = new Date(dateStr + 'T00:00:00');
		return date.toLocaleDateString('en-US', {
			weekday: 'short',
			month: 'short',
			day: 'numeric',
			year: 'numeric'
		});
	}

	function formatDateRange(startDate: string, endDate: string): string {
		return `${formatDate(startDate)} - ${formatDate(endDate)}`;
	}

	function getStatusBadgeClass(status: InvoiceStatus): string {
		switch (status) {
			case 'DRAFT':
				return 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300';
			case 'SENT':
				return 'bg-accent-100 text-accent-800 dark:bg-accent-900/30 dark:text-accent-400';
			case 'PAID':
				return 'bg-success-100 text-success-800 dark:bg-success-900/30 dark:text-success-400';
			case 'OVERDUE':
				return 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400';
			case 'CANCELLED':
				return 'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-500';
			default:
				return 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300';
		}
	}

	async function updateStatus(newStatus: InvoiceStatus) {
		isUpdating = true;
		try {
			await client.mutate({
				mutation: UPDATE_INVOICE,
				variables: { id: invoice.id, input: { status: newStatus } }
			});
			await invalidateAll();
		} catch (err) {
			console.error('Failed to update status:', err);
		} finally {
			isUpdating = false;
		}
	}

	async function handleDelete() {
		isDeleting = true;
		try {
			await client.mutate({
				mutation: DELETE_INVOICE,
				variables: { id: invoice.id }
			});
			await goto('/admin/invoices');
		} catch (err) {
			console.error('Failed to delete invoice:', err);
		} finally {
			isDeleting = false;
			showDeleteConfirm = false;
		}
	}

	async function addRevenue(revenueId: string) {
		addingRevenueId = revenueId;
		try {
			await client.mutate({
				mutation: ADD_REVENUE_TO_INVOICE,
				variables: { invoiceId: invoice.id, revenueId }
			});
			await invalidateAll();
		} catch (err) {
			console.error('Failed to add revenue:', err);
		} finally {
			addingRevenueId = null;
		}
	}

	async function addProject(projectId: string) {
		addingProjectId = projectId;
		try {
			await client.mutate({
				mutation: ADD_PROJECT_TO_INVOICE,
				variables: { invoiceId: invoice.id, projectId }
			});
			await invalidateAll();
		} catch (err) {
			console.error('Failed to add project:', err);
		} finally {
			addingProjectId = null;
		}
	}

	async function removeRevenue(id: string) {
		removingId = id;
		try {
			await client.mutate({
				mutation: REMOVE_REVENUE_FROM_INVOICE,
				variables: { id }
			});
			await invalidateAll();
		} catch (err) {
			console.error('Failed to remove revenue:', err);
		} finally {
			removingId = null;
		}
	}

	async function removeProject(id: string) {
		removingId = id;
		try {
			await client.mutate({
				mutation: REMOVE_PROJECT_FROM_INVOICE,
				variables: { id }
			});
			await invalidateAll();
		} catch (err) {
			console.error('Failed to remove project:', err);
		} finally {
			removingId = null;
		}
	}

	async function addAllRevenues() {
		isUpdating = true;
		try {
			await client.mutate({
				mutation: ADD_ALL_ELIGIBLE_REVENUES,
				variables: { invoiceId: invoice.id }
			});
			await invalidateAll();
			showAddRevenuesModal = false;
		} catch (err) {
			console.error('Failed to add all revenues:', err);
		} finally {
			isUpdating = false;
		}
	}

	async function addAllProjects() {
		isUpdating = true;
		try {
			await client.mutate({
				mutation: ADD_ALL_ELIGIBLE_PROJECTS,
				variables: { invoiceId: invoice.id }
			});
			await invalidateAll();
			showAddProjectsModal = false;
		} catch (err) {
			console.error('Failed to add all projects:', err);
		} finally {
			isUpdating = false;
		}
	}

	// Wave functions
	async function loadWaveCustomers() {
		try {
			const result = await client.query<{ waveCustomers: WaveCustomer[] }>({
				query: WAVE_CUSTOMERS,
				fetchPolicy: 'cache-first'
			});
			waveCustomers = result.data?.waveCustomers ?? [];
		} catch (err) {
			console.error('Failed to load Wave customers:', err);
		}
	}

	async function loadWaveProducts() {
		if (waveProducts.length > 0) return;
		try {
			const result = await client.query<{ waveProducts: WaveProduct[] }>({
				query: WAVE_PRODUCTS,
				fetchPolicy: 'cache-first'
			});
			waveProducts = result.data?.waveProducts ?? [];
		} catch (err) {
			console.error('Failed to load Wave products:', err);
		}
	}

	function handleWaveLinkClick(
		type: 'revenue' | 'project',
		id: string,
		currentWaveServiceId: string | null,
		itemName: string
	) {
		loadWaveProducts();
		waveLinkTarget = { type, id, currentWaveServiceId, itemName };
		showWaveLinkDrawer = true;
	}

	async function handleWaveLinkSuccess() {
		showWaveLinkDrawer = false;
		waveLinkTarget = null;
		await invalidateAll();
	}

	interface CreateWaveInvoiceResult {
		createWaveInvoice: {
			success: boolean;
			error?: string;
		};
	}

	async function syncToWave() {
		isSyncingWave = true;
		waveError = null;
		try {
			const result = await client.mutate<CreateWaveInvoiceResult>({
				mutation: CREATE_WAVE_INVOICE,
				variables: {
					input: {
						invoiceId: invoice.id
					}
				}
			});

			if (result.data?.createWaveInvoice.success) {
				await invalidateAll();
			} else {
				waveError = result.data?.createWaveInvoice.error || 'Failed to create Wave invoice';
			}
		} catch (err: unknown) {
			console.error('Failed to sync to Wave:', err);
			waveError = err instanceof Error ? err.message : 'Failed to sync to Wave';
		} finally {
			isSyncingWave = false;
		}
	}

	async function linkCustomerToWave() {
		if (!selectedWaveCustomerId) return;

		isUpdating = true;
		try {
			await client.mutate({
				mutation: LINK_CUSTOMER_TO_WAVE,
				variables: {
					customerId: invoice.customer?.id,
					waveCustomerId: selectedWaveCustomerId
				}
			});
			await invalidateAll();
			showLinkCustomerModal = false;
		} catch (err) {
			console.error('Failed to link customer:', err);
		} finally {
			isUpdating = false;
		}
	}

	function handleWaveCustomerSelect(e: Event) {
		const target = e.target as HTMLSelectElement;
		selectedWaveCustomerId = target.value;
	}
</script>

<svelte:head>
	<title>{invoice.customer?.name ?? 'Invoice'} - Invoices - Admin - Nexus</title>
</svelte:head>

<div class="py-8">
	<ContentContainer>
		<PageHeader
			title={invoice.customer?.name ?? 'Unknown'}
			subtitle={formatDateRange(invoice.startDate, invoice.endDate)}
			colorScheme="accent6"
			backHref="/admin/invoices"
		>
			<span
				class="rounded-full px-3 py-1 text-sm font-semibold {getStatusBadgeClass(invoice.status)}"
			>
				{invoice.status}
			</span>
		</PageHeader>

		<!-- Status Actions -->
		<div class="mb-6 flex flex-wrap gap-2">
			{#if invoice.status === 'DRAFT'}
				<button
					type="button"
					class="btn-accent"
					onclick={() => updateStatus('SENT')}
					disabled={isUpdating}
				>
					Mark as Sent
				</button>
				<button
					type="button"
					class="btn-ghost text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-900/20"
					onclick={() => (showDeleteConfirm = true)}
				>
					Delete
				</button>
			{:else if invoice.status === 'SENT'}
				<button
					type="button"
					class="btn-primary"
					onclick={() => updateStatus('PAID')}
					disabled={isUpdating}
				>
					Mark as Paid
				</button>
				<button
					type="button"
					class="btn-ghost text-yellow-600 hover:bg-yellow-50 dark:text-yellow-400 dark:hover:bg-yellow-900/20"
					onclick={() => updateStatus('OVERDUE')}
					disabled={isUpdating}
				>
					Mark as Overdue
				</button>
				<button
					type="button"
					class="btn-ghost"
					onclick={() => updateStatus('DRAFT')}
					disabled={isUpdating}
				>
					Revert to Draft
				</button>
			{:else if invoice.status === 'OVERDUE'}
				<button
					type="button"
					class="btn-primary"
					onclick={() => updateStatus('PAID')}
					disabled={isUpdating}
				>
					Mark as Paid
				</button>
				<button
					type="button"
					class="btn-ghost"
					onclick={() => updateStatus('SENT')}
					disabled={isUpdating}
				>
					Revert to Sent
				</button>
			{:else if invoice.status === 'PAID'}
				<button
					type="button"
					class="btn-ghost"
					onclick={() => updateStatus('SENT')}
					disabled={isUpdating}
				>
					Revert to Sent
				</button>
			{:else if invoice.status === 'CANCELLED'}
				<button
					type="button"
					class="btn-ghost"
					onclick={() => updateStatus('DRAFT')}
					disabled={isUpdating}
				>
					Revert to Draft
				</button>
				<button
					type="button"
					class="btn-ghost text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-900/20"
					onclick={() => (showDeleteConfirm = true)}
				>
					Delete
				</button>
			{/if}
			{#if invoice.status !== 'CANCELLED' && invoice.status !== 'PAID'}
				<button
					type="button"
					class="btn-ghost text-gray-500 hover:bg-gray-50 dark:text-gray-400 dark:hover:bg-gray-800"
					onclick={() => updateStatus('CANCELLED')}
					disabled={isUpdating}
				>
					Cancel
				</button>
			{/if}
		</div>

		<div class="space-y-6">
			<!-- Summary Section -->
			<section
				class="overflow-hidden rounded-xl border border-accent6-500/20 bg-theme-card shadow-theme-md"
			>
				<div class="section-header-accent6 px-5 py-3">
					<h2 class="text-lg font-semibold text-theme">Summary</h2>
				</div>
				<div class="grid grid-cols-2 gap-4 p-5 sm:grid-cols-4">
					<div>
						<p class="text-sm font-medium text-theme-muted">Revenues</p>
						<p class="mt-1 text-xl font-bold text-secondary-600 dark:text-secondary-400">
							{invoice.revenueCount}
						</p>
						<p class="text-sm text-theme-muted">{formatCurrency(invoice.revenuesTotal)}</p>
					</div>
					<div>
						<p class="text-sm font-medium text-theme-muted">Projects</p>
						<p class="mt-1 text-xl font-bold text-accent-600 dark:text-accent-400">
							{invoice.projectCount}
						</p>
						<p class="text-sm text-theme-muted">{formatCurrency(invoice.projectsTotal)}</p>
					</div>
					<div class="col-span-2">
						<p class="text-sm font-medium text-theme-muted">Total Amount</p>
						<p class="mt-1 text-2xl font-bold text-accent6-600 dark:text-accent6-400">
							{formatCurrency(invoice.totalAmount)}
						</p>
					</div>
				</div>
			</section>

			<!-- Revenues Section -->
			<section
				class="overflow-hidden rounded-xl border border-accent6-500/20 bg-theme-card shadow-theme-md"
			>
				<div class="section-header-accent6 px-5 py-3">
					{#if invoice.status === 'DRAFT' && eligibleRevenues.length > 0}
						<SectionHeader
							title="Revenues ({invoice.revenues.length})"
							buttonText="Add ({eligibleRevenues.length})"
							onButtonClick={() => (showAddRevenuesModal = true)}
						/>
					{:else}
						<h2 class="text-lg font-semibold text-theme">Revenues ({invoice.revenues.length})</h2>
					{/if}
				</div>
				<div class="px-5 py-5">
					{#if invoice.revenues.length > 0}
						<!-- Mobile: Card view -->
						<div class="space-y-3 sm:hidden">
							{#each invoice.revenues as entry (entry.id)}
								<div class="bg-theme-secondary/50 rounded-lg border border-theme p-4">
									<div class="flex items-start justify-between">
										<div class="flex-1">
											<p class="font-medium text-theme">
												{entry.account?.name ?? 'Unknown Account'}
											</p>
											<p class="mt-1 text-sm text-theme-secondary">
												{entry.revenue?.startDate ? formatDate(entry.revenue.startDate) : ''} - {entry
													.revenue?.endDate
													? formatDate(entry.revenue.endDate)
													: 'Ongoing'}
											</p>
											<div class="mt-2">
												{#if entry.revenue?.waveServiceId}
													<span class="badge-success">Wave Linked</span>
												{:else if invoice.status === 'DRAFT'}
													<button
														type="button"
														class="badge-warning cursor-pointer hover:opacity-80"
														onclick={() => handleWaveLinkClick('revenue', entry.revenueId, entry.revenue?.waveServiceId ?? null, entry.account?.name ?? 'Revenue')}
													>
														Link to Wave
													</button>
												{:else}
													<span class="badge-warning">Not Linked</span>
												{/if}
											</div>
										</div>
										<div class="flex items-center gap-3">
											<span class="font-medium text-accent6-600 dark:text-accent6-400">
												{formatCurrency(entry.amount)}
											</span>
											{#if invoice.status === 'DRAFT'}
												<button
													type="button"
													class="text-red-600 hover:text-red-800 disabled:opacity-50 dark:text-red-400"
													onclick={() => removeRevenue(entry.id)}
													disabled={removingId === entry.id}
													aria-label="Remove revenue"
												>
													<svg
														class="h-5 w-5"
														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>
											{/if}
										</div>
									</div>
								</div>
							{/each}
						</div>

						<!-- Desktop: Table view -->
						<div class="hidden overflow-x-auto rounded-lg border border-theme sm:block">
							<table class="w-full">
								<thead class="bg-theme-secondary">
									<tr
										class="text-left text-xs font-medium tracking-wider text-theme-muted uppercase"
									>
										<th class="px-4 py-2">Account</th>
										<th class="px-4 py-2">Period</th>
										<th class="px-4 py-2 text-right">Amount</th>
										<th class="px-4 py-2">Wave</th>
										{#if invoice.status === 'DRAFT'}
											<th class="w-10 px-4 py-2"></th>
										{/if}
									</tr>
								</thead>
								<tbody class="divide-theme divide-y">
									{#each invoice.revenues as entry (entry.id)}
										<tr>
											<td class="px-4 py-2 text-sm text-theme">
												{entry.account?.name ?? 'Unknown Account'}
											</td>
											<td class="px-4 py-2 text-sm whitespace-nowrap text-theme-secondary">
												{entry.revenue?.startDate ? formatDate(entry.revenue.startDate) : ''} - {entry
													.revenue?.endDate
													? formatDate(entry.revenue.endDate)
													: 'Ongoing'}
											</td>
											<td
												class="px-4 py-2 text-right text-sm font-medium whitespace-nowrap text-accent6-600 dark:text-accent6-400"
											>
												{formatCurrency(entry.amount)}
											</td>
											<td class="px-4 py-2">
												{#if entry.revenue?.waveServiceId}
													<span class="badge-success">Linked</span>
												{:else if invoice.status === 'DRAFT'}
													<button
														type="button"
														class="badge-warning cursor-pointer hover:opacity-80"
														onclick={() => handleWaveLinkClick('revenue', entry.revenueId, entry.revenue?.waveServiceId ?? null, entry.account?.name ?? 'Revenue')}
													>
														Link
													</button>
												{:else}
													<span class="badge-warning">Not Linked</span>
												{/if}
											</td>
											{#if invoice.status === 'DRAFT'}
												<td class="px-4 py-2 text-right">
													<button
														type="button"
														class="text-red-600 hover:text-red-800 disabled:opacity-50 dark:text-red-400"
														onclick={() => removeRevenue(entry.id)}
														disabled={removingId === entry.id}
														aria-label="Remove revenue"
													>
														<svg
															class="h-4 w-4"
															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>
												</td>
											{/if}
										</tr>
									{/each}
								</tbody>
							</table>
						</div>
					{:else}
						<div class="py-6 text-center text-theme-muted">
							{#if invoice.status === 'DRAFT'}
								{#if eligibleRevenues.length > 0}
									No revenues added yet.
									<button
										type="button"
										class="mx-auto mt-2 block text-secondary-600 hover:text-secondary-700 dark:text-secondary-400"
										onclick={() => (showAddRevenuesModal = true)}
									>
										Add revenues
									</button>
								{:else}
									<p>No eligible revenues for this customer and invoice period.</p>
									<a
										href="/admin/customers/{invoice.customerId}"
										class="mt-2 inline-block text-secondary-600 hover:text-secondary-700 dark:text-secondary-400"
									>
										Go to customer page to manage accounts
									</a>
								{/if}
							{:else}
								No revenues in this invoice.
							{/if}
						</div>
					{/if}
				</div>
			</section>

			<!-- Projects Section -->
			<section
				class="overflow-hidden rounded-xl border border-accent6-500/20 bg-theme-card shadow-theme-md"
			>
				<div class="section-header-accent6 px-5 py-3">
					{#if invoice.status === 'DRAFT' && eligibleProjects.length > 0}
						<SectionHeader
							title="Projects ({invoice.projects.length})"
							buttonText="Add ({eligibleProjects.length})"
							onButtonClick={() => (showAddProjectsModal = true)}
						/>
					{:else}
						<h2 class="text-lg font-semibold text-theme">Projects ({invoice.projects.length})</h2>
					{/if}
				</div>
				<div class="px-5 py-5">
					{#if invoice.projects.length > 0}
						<!-- Mobile: Card view -->
						<div class="space-y-3 sm:hidden">
							{#each invoice.projects as entry (entry.id)}
								<div class="bg-theme-secondary/50 rounded-lg border border-theme p-4">
									<div class="flex items-start justify-between">
										<div class="flex-1">
											<p class="font-medium text-theme">{entry.project?.name ?? 'Unknown'}</p>
											<p class="mt-1 text-sm text-theme-secondary">
												{formatDate(entry.project?.date ?? '')}
												{#if entry.account?.name}
													· {entry.account.name}
												{/if}
											</p>
											{#if entry.project?.formattedAddress}
												<p class="mt-1 text-sm text-theme-muted">
													{entry.project.formattedAddress}
												</p>
											{/if}
											<div class="mt-2">
												{#if entry.project?.waveServiceId}
													<span class="badge-success">Wave Linked</span>
												{:else if invoice.status === 'DRAFT'}
													<button
														type="button"
														class="badge-warning cursor-pointer hover:opacity-80"
														onclick={() => handleWaveLinkClick('project', entry.projectId, entry.project?.waveServiceId ?? null, entry.project?.name ?? 'Project')}
													>
														Link to Wave
													</button>
												{:else}
													<span class="badge-warning">Not Linked</span>
												{/if}
											</div>
										</div>
										<div class="flex items-center gap-3">
											<span class="font-medium text-accent6-600 dark:text-accent6-400">
												{formatCurrency(entry.amount)}
											</span>
											{#if invoice.status === 'DRAFT'}
												<button
													type="button"
													class="text-red-600 hover:text-red-800 disabled:opacity-50 dark:text-red-400"
													onclick={() => removeProject(entry.id)}
													disabled={removingId === entry.id}
													aria-label="Remove project"
												>
													<svg
														class="h-5 w-5"
														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>
											{/if}
										</div>
									</div>
								</div>
							{/each}
						</div>

						<!-- Desktop: Table view -->
						<div class="hidden overflow-x-auto rounded-lg border border-theme sm:block">
							<table class="w-full">
								<thead class="bg-theme-secondary">
									<tr
										class="text-left text-xs font-medium tracking-wider text-theme-muted uppercase"
									>
										<th class="px-4 py-2">Date</th>
										<th class="px-4 py-2">Project</th>
										<th class="px-4 py-2">Account</th>
										<th class="hidden px-4 py-2 md:table-cell">Location</th>
										<th class="px-4 py-2 text-right">Amount</th>
										<th class="px-4 py-2">Wave</th>
										{#if invoice.status === 'DRAFT'}
											<th class="w-10 px-4 py-2"></th>
										{/if}
									</tr>
								</thead>
								<tbody class="divide-theme divide-y">
									{#each invoice.projects as entry (entry.id)}
										<tr>
											<td class="px-4 py-2 text-sm whitespace-nowrap text-theme">
												{formatDate(entry.project?.date ?? '')}
											</td>
											<td class="px-4 py-2 text-sm text-theme">
												{entry.project?.name ?? 'Unknown'}
											</td>
											<td class="px-4 py-2 text-sm text-theme-secondary">
												{entry.account?.name ?? '-'}
											</td>
											<td class="hidden px-4 py-2 text-sm text-theme-secondary md:table-cell">
												{entry.project?.formattedAddress ?? ''}
											</td>
											<td
												class="px-4 py-2 text-right text-sm font-medium whitespace-nowrap text-accent6-600 dark:text-accent6-400"
											>
												{formatCurrency(entry.amount)}
											</td>
											<td class="px-4 py-2">
												{#if entry.project?.waveServiceId}
													<span class="badge-success">Linked</span>
												{:else if invoice.status === 'DRAFT'}
													<button
														type="button"
														class="badge-warning cursor-pointer hover:opacity-80"
														onclick={() => handleWaveLinkClick('project', entry.projectId, entry.project?.waveServiceId ?? null, entry.project?.name ?? 'Project')}
													>
														Link
													</button>
												{:else}
													<span class="badge-warning">Not Linked</span>
												{/if}
											</td>
											{#if invoice.status === 'DRAFT'}
												<td class="px-4 py-2 text-right">
													<button
														type="button"
														class="text-red-600 hover:text-red-800 disabled:opacity-50 dark:text-red-400"
														onclick={() => removeProject(entry.id)}
														disabled={removingId === entry.id}
														aria-label="Remove project"
													>
														<svg
															class="h-4 w-4"
															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>
												</td>
											{/if}
										</tr>
									{/each}
								</tbody>
							</table>
						</div>
					{:else}
						<div class="py-6 text-center text-theme-muted">
							{#if invoice.status === 'DRAFT'}
								{#if eligibleProjects.length > 0}
									No projects added yet.
									<button
										type="button"
										class="mx-auto mt-2 block text-accent-600 hover:text-accent-700 dark:text-accent-400"
										onclick={() => (showAddProjectsModal = true)}
									>
										Add projects
									</button>
								{:else}
									<p>No eligible projects for this customer and invoice period.</p>
									<a
										href="/admin/projects"
										class="mt-2 inline-block text-accent-600 hover:text-accent-700 dark:text-accent-400"
									>
										View all projects
									</a>
								{/if}
							{:else}
								No projects in this invoice.
							{/if}
						</div>
					{/if}
				</div>
			</section>

			<!-- Wave Integration Section -->
			<section
				class="overflow-hidden rounded-xl border border-accent6-500/20 bg-theme-card shadow-theme-md"
			>
				<div class="section-header-accent6 px-5 py-3">
					<div class="flex items-center gap-2">
						<h2 class="text-lg font-semibold text-theme">Wave Accounting</h2>
						<span
							class="rounded bg-accent6-100 px-2 py-0.5 text-xs font-medium text-accent6-700 dark:bg-accent6-900/30 dark:text-accent6-400"
						>
							Integration
						</span>
					</div>
				</div>
				<div class="px-5 py-5">
					{#if invoice.waveInvoiceId}
						<!-- Already synced to Wave -->
						<div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
							<div class="flex items-center gap-3">
								<div
									class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-success-100 dark:bg-success-900/30"
								>
									<svg
										class="h-5 w-5 text-success-600 dark:text-success-400"
										fill="none"
										stroke="currentColor"
										viewBox="0 0 24 24"
									>
										<path
											stroke-linecap="round"
											stroke-linejoin="round"
											stroke-width="2"
											d="M5 13l4 4L19 7"
										/>
									</svg>
								</div>
								<div>
									<p class="font-medium text-theme">Synced to Wave</p>
									<p class="text-sm text-theme-secondary">
										{#if waveInvoice?.invoiceNumber}
											Wave #{waveInvoice.invoiceNumber}
										{:else}
											Loading...
										{/if}
									</p>
								</div>
							</div>
							{#if waveInvoice?.pdfUrl}
								<a
									href={waveInvoice.pdfUrl}
									target="_blank"
									rel="noopener noreferrer"
									class="btn-secondary inline-flex items-center gap-2 self-start text-sm sm:self-auto"
								>
									<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
										<path
											stroke-linecap="round"
											stroke-linejoin="round"
											stroke-width="2"
											d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
										/>
									</svg>
									Download PDF
								</a>
							{/if}
						</div>
					{:else if invoice.status === 'CANCELLED'}
						<!-- Cancelled - cannot sync -->
						<div class="flex items-center gap-3">
							<div
								class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-gray-100 dark:bg-gray-800"
							>
								<svg
									class="h-5 w-5 text-gray-400"
									fill="none"
									stroke="currentColor"
									viewBox="0 0 24 24"
								>
									<path
										stroke-linecap="round"
										stroke-linejoin="round"
										stroke-width="2"
										d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"
									/>
								</svg>
							</div>
							<div>
								<p class="font-medium text-theme-muted">Not synced</p>
								<p class="text-sm text-theme-muted">Cancelled invoices cannot be synced to Wave</p>
							</div>
						</div>
					{:else if invoice.status !== 'DRAFT'}
						<!-- Sent/Paid/Overdue without sync - missed opportunity -->
						<div class="flex items-center gap-3">
							<div
								class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-gray-100 dark:bg-gray-800"
							>
								<svg
									class="h-5 w-5 text-gray-400"
									fill="none"
									stroke="currentColor"
									viewBox="0 0 24 24"
								>
									<path
										stroke-linecap="round"
										stroke-linejoin="round"
										stroke-width="2"
										d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
									/>
								</svg>
							</div>
							<div>
								<p class="font-medium text-theme-muted">Not synced</p>
								<p class="text-sm text-theme-muted">
									This invoice was not synced to Wave before being sent
								</p>
							</div>
						</div>
					{:else if waveError}
						<!-- Sync error state -->
						<div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
							<div class="flex items-center gap-3">
								<div
									class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-red-100 dark:bg-red-900/30"
								>
									<svg
										class="h-5 w-5 text-red-600 dark:text-red-400"
										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>
								</div>
								<div>
									<p class="font-medium text-theme">Wave Sync Failed</p>
									<p class="text-sm text-red-600 dark:text-red-400">{waveError}</p>
								</div>
							</div>
							<button
								type="button"
								class="btn-ghost self-start text-sm sm:self-auto"
								onclick={() => {
									waveError = null;
								}}
							>
								Dismiss
							</button>
						</div>
					{:else if waveReadiness}
						<!-- Readiness check result -->
						{#if waveReadiness.ready}
							<!-- Ready to sync -->
							<div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
								<div class="flex items-center gap-3">
									<div
										class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-success-100 dark:bg-success-900/30"
									>
										<svg
											class="h-5 w-5 text-success-600 dark:text-success-400"
											fill="none"
											stroke="currentColor"
											viewBox="0 0 24 24"
										>
											<path
												stroke-linecap="round"
												stroke-linejoin="round"
												stroke-width="2"
												d="M5 13l4 4L19 7"
											/>
										</svg>
									</div>
									<div>
										<p class="font-medium text-theme">Ready to sync</p>
										<p class="text-sm text-theme-secondary">
											{waveReadiness.readyItemCount} items totaling {formatCurrency(
												parseFloat(waveReadiness.totalAmount)
											)}
										</p>
									</div>
								</div>
								<button
									type="button"
									class="btn-primary self-start sm:self-auto"
									onclick={syncToWave}
									disabled={isSyncingWave}
								>
									{isSyncingWave ? 'Syncing...' : 'Create Wave Invoice'}
								</button>
							</div>
						{:else}
							<!-- Not ready - show issues -->
							<div>
								<div class="mb-3 flex items-center gap-3">
									<div
										class="flex h-10 w-10 items-center justify-center rounded-full bg-yellow-100 dark:bg-yellow-900/30"
									>
										<svg
											class="h-5 w-5 text-yellow-600 dark:text-yellow-400"
											fill="none"
											stroke="currentColor"
											viewBox="0 0 24 24"
										>
											<path
												stroke-linecap="round"
												stroke-linejoin="round"
												stroke-width="2"
												d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
											/>
										</svg>
									</div>
									<div>
										<p class="font-medium text-theme">Not ready to sync</p>
										<p class="text-sm text-theme-secondary">Please resolve the following issues:</p>
									</div>
								</div>
								<ul class="ml-13 space-y-2 text-sm">
									{#each waveReadiness.issues as issue}
										<li class="flex flex-col gap-1">
											<span class="flex items-start gap-2">
												<span class="text-yellow-600 dark:text-yellow-400">•</span>
												<span class="text-theme-secondary">{issue}</span>
											</span>
											{#if issue.includes('Customer is not linked')}
												<button
													type="button"
													class="ml-4 text-left text-accent6-600 hover:text-accent6-700 dark:text-accent6-400"
													onclick={() => {
														loadWaveCustomers();
														showLinkCustomerModal = true;
													}}
												>
													Link now →
												</button>
											{/if}
										</li>
									{/each}
								</ul>
								{#if waveReadiness.readyItemCount > 0}
									<p class="mt-3 text-sm text-theme-muted">
										{waveReadiness.readyItemCount} of {waveReadiness.readyItemCount +
											waveReadiness.missingWaveLinkCount} items are linked to Wave products
									</p>
								{/if}
							</div>
						{/if}
					{/if}
				</div>
			</section>
		</div>
	</ContentContainer>
</div>

<!-- Add Revenues Drawer -->
<FormDrawer
	open={showAddRevenuesModal}
	title="Add Revenues"
	onClose={() => (showAddRevenuesModal = false)}
>
	{#if eligibleRevenues.length > 0}
		<div class="space-y-3">
			{#each eligibleRevenues as revenue (revenue.revenueId)}
				<div class="flex items-center justify-between rounded-lg border border-theme bg-theme p-4">
					<div>
						<p class="font-medium text-theme">
							{revenue.accountName}
						</p>
						<p class="text-sm text-theme-secondary">
							{formatCurrency(revenue.amount)}/month
						</p>
					</div>
					<button
						type="button"
						class="btn-secondary text-sm"
						onclick={() => addRevenue(revenue.revenueId)}
						disabled={addingRevenueId === revenue.revenueId}
					>
						{addingRevenueId === revenue.revenueId ? 'Adding...' : 'Add'}
					</button>
				</div>
			{/each}
		</div>
	{:else}
		<div class="py-8 text-center">
			<p class="mb-4 text-theme-muted">No eligible revenues available for this invoice period.</p>
			<a
				href="/admin/customers/{invoice.customerId}"
				class="btn-secondary inline-flex items-center gap-2 text-sm"
			>
				<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="2"
						d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
					/>
				</svg>
				Go to Customer Page
			</a>
		</div>
	{/if}

	{#snippet footer()}
		{#if eligibleRevenues.length > 0}
			<div class="flex gap-3">
				<button
					type="button"
					class="btn-ghost flex-1"
					onclick={() => (showAddRevenuesModal = false)}
				>
					Close
				</button>
				<button
					type="button"
					class="btn-primary flex-1"
					onclick={addAllRevenues}
					disabled={isUpdating}
				>
					{isUpdating ? 'Adding...' : `Add All (${eligibleRevenues.length})`}
				</button>
			</div>
		{:else}
			<button type="button" class="btn-ghost w-full" onclick={() => (showAddRevenuesModal = false)}>
				Close
			</button>
		{/if}
	{/snippet}
</FormDrawer>

<!-- Add Projects Drawer -->
<FormDrawer
	open={showAddProjectsModal}
	title="Add Projects"
	onClose={() => (showAddProjectsModal = false)}
>
	{#if eligibleProjects.length > 0}
		<div class="space-y-3">
			{#each eligibleProjects as project (project.projectId)}
				<div class="flex items-center justify-between rounded-lg border border-theme bg-theme p-4">
					<div>
						<p class="font-medium text-theme">
							{project.name}
						</p>
						<p class="text-sm text-theme-secondary">
							{formatDate(project.date)} - {formatCurrency(project.amount)}
						</p>
					</div>
					<button
						type="button"
						class="btn-secondary text-sm"
						onclick={() => addProject(project.projectId)}
						disabled={addingProjectId === project.projectId}
					>
						{addingProjectId === project.projectId ? 'Adding...' : 'Add'}
					</button>
				</div>
			{/each}
		</div>
	{:else}
		<div class="py-8 text-center">
			<p class="mb-4 text-theme-muted">No eligible projects available for this invoice period.</p>
			<a href="/admin/projects" class="btn-secondary inline-flex items-center gap-2 text-sm">
				<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="2"
						d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
					/>
				</svg>
				View Projects
			</a>
		</div>
	{/if}

	{#snippet footer()}
		{#if eligibleProjects.length > 0}
			<div class="flex gap-3">
				<button
					type="button"
					class="btn-ghost flex-1"
					onclick={() => (showAddProjectsModal = false)}
				>
					Close
				</button>
				<button
					type="button"
					class="btn-primary flex-1"
					onclick={addAllProjects}
					disabled={isUpdating}
				>
					{isUpdating ? 'Adding...' : `Add All (${eligibleProjects.length})`}
				</button>
			</div>
		{:else}
			<button type="button" class="btn-ghost w-full" onclick={() => (showAddProjectsModal = false)}>
				Close
			</button>
		{/if}
	{/snippet}
</FormDrawer>

<!-- Delete Confirmation Modal -->
{#if showDeleteConfirm}
	<div class="fixed inset-0 z-50 flex items-center justify-center p-4">
		<button
			type="button"
			class="absolute inset-0 bg-black/50"
			onclick={() => (showDeleteConfirm = false)}
			aria-label="Close modal"
		></button>
		<div
			class="relative w-full max-w-md rounded-xl border border-theme bg-theme-card p-6 shadow-xl"
		>
			<h2 class="mb-4 text-lg font-semibold text-theme">Delete Invoice?</h2>
			<p class="mb-6 text-theme-secondary">
				Are you sure you want to delete this invoice? This action cannot be undone.
			</p>
			<div class="flex justify-end gap-3">
				<button
					type="button"
					class="btn-ghost"
					onclick={() => (showDeleteConfirm = false)}
					disabled={isDeleting}
				>
					Cancel
				</button>
				<button
					type="button"
					class="btn-primary bg-red-600 hover:bg-red-700"
					onclick={handleDelete}
					disabled={isDeleting}
				>
					{isDeleting ? 'Deleting...' : 'Delete Invoice'}
				</button>
			</div>
		</div>
	</div>
{/if}

<!-- Link Customer to Wave Drawer -->
<FormDrawer
	open={showLinkCustomerModal}
	title="Link Customer to Wave"
	onClose={() => (showLinkCustomerModal = false)}
>
	<p class="mb-6 text-theme-secondary">
		Select the Wave customer that corresponds to <strong class="text-theme"
			>{invoice.customer?.name}</strong
		>:
	</p>
	<label class="block">
		<span class="form-label">Wave Customer</span>
		<select class="mt-1 select-base" onchange={handleWaveCustomerSelect}>
			<option value="">Select a customer...</option>
			{#each waveCustomers as customer}
				<option value={customer.id} selected={selectedWaveCustomerId === customer.id}>
					{customer.name}
					{customer.email ? `(${customer.email})` : ''}
				</option>
			{/each}
		</select>
	</label>

	{#snippet footer()}
		<div class="flex gap-3">
			<button
				type="button"
				class="btn-ghost flex-1"
				onclick={() => (showLinkCustomerModal = false)}
				disabled={isUpdating}
			>
				Cancel
			</button>
			<button
				type="button"
				class="btn-primary flex-1"
				onclick={linkCustomerToWave}
				disabled={isUpdating || !selectedWaveCustomerId}
			>
				{isUpdating ? 'Linking...' : 'Link Customer'}
			</button>
		</div>
	{/snippet}
</FormDrawer>

<!-- Link Item to Wave Product Drawer -->
<FormDrawer
	open={showWaveLinkDrawer}
	title="Link {waveLinkTarget?.type === 'revenue' ? 'Revenue' : 'Project'} to Wave"
	onClose={() => {
		showWaveLinkDrawer = false;
		waveLinkTarget = null;
	}}
>
	{#if waveLinkTarget}
		<p class="mb-4 text-theme-secondary">
			Select a Wave product to link <strong class="text-theme">{waveLinkTarget.itemName}</strong> for
			invoicing:
		</p>
		<WaveLinkForm
			type={waveLinkTarget.type}
			itemId={waveLinkTarget.id}
			currentWaveServiceId={waveLinkTarget.currentWaveServiceId}
			{waveProducts}
			onSuccess={handleWaveLinkSuccess}
			onCancel={() => {
				showWaveLinkDrawer = false;
				waveLinkTarget = null;
			}}
		/>
	{/if}
</FormDrawer>
