<script lang="ts">
	import { fade, fly } from 'svelte/transition';
	import { invalidateAll } from '$app/navigation';
	import { client } from '$lib/graphql/client';
	import { ContentContainer } from '$lib/components/layout';
	import { AdminDashboardHeader } from '$lib/components/admin';
	import type {
		WaveInvoiceConnection,
		WaveInvoiceListItem,
		WaveProduct,
		WaveCustomer
	} from '$lib/graphql/queries/wave';
	import {
		APPROVE_WAVE_INVOICE,
		SEND_WAVE_INVOICE,
		DELETE_WAVE_INVOICE,
		ARCHIVE_WAVE_PRODUCT,
		CREATE_WAVE_PRODUCT,
		UPDATE_WAVE_PRODUCT,
		UPDATE_WAVE_CUSTOMER,
		DELETE_WAVE_CUSTOMER
	} from '$lib/graphql/mutations/wave';

	interface PageData {
		invoices: WaveInvoiceConnection;
		products: WaveProduct[];
		customers: WaveCustomer[];
		currentPage: number;
	}

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

	// Tab state
	type Tab = 'invoices' | 'products' | 'customers';
	const tabs: { id: Tab; label: string }[] = [
		{ id: 'invoices', label: 'Invoices' },
		{ id: 'products', label: 'Products' },
		{ id: 'customers', label: 'Customers' }
	];
	let activeTabIndex = $state(0);
	let activeTab = $derived(tabs[activeTabIndex].id);

	// Loading states
	let actionLoading = $state<string | null>(null);
	let actionError = $state<string | null>(null);

	// Derived data
	let invoices = $derived(data.invoices);
	let products = $derived(data.products);
	let customers = $derived(data.customers);
	let activeProducts = $derived(products.filter((p) => !p.isArchived));
	let archivedProducts = $derived(products.filter((p) => p.isArchived));

	// Tab counts
	function getTabCount(tabId: Tab): number {
		switch (tabId) {
			case 'invoices':
				return invoices.pageInfo.totalCount;
			case 'products':
				return activeProducts.length;
			case 'customers':
				return customers.length;
		}
	}

	// Show archived products toggle
	let showArchivedProducts = $state(false);

	// Mobile tab navigation
	function prevTab() {
		activeTabIndex = (activeTabIndex - 1 + tabs.length) % tabs.length;
	}

	function nextTab() {
		activeTabIndex = (activeTabIndex + 1) % tabs.length;
	}

	// ============================================================================
	// Customer CRUD State
	// ============================================================================

	let showCustomerPanel = $state(false);
	let editingCustomer = $state<WaveCustomer | null>(null);
	let customerFormError = $state<string | null>(null);
	let customerFormLoading = $state(false);

	// Customer form fields
	let customerName = $state('');
	let customerEmail = $state('');
	let customerCurrency = $state('USD');
	let customerAddressLine1 = $state('');
	let customerAddressLine2 = $state('');
	let customerCity = $state('');
	let customerProvinceCode = $state('');
	let customerPostalCode = $state('');

	function openCustomerEdit(customer: WaveCustomer) {
		editingCustomer = customer;
		customerName = customer.name;
		customerEmail = customer.email || '';
		customerCurrency = customer.currencyCode || 'USD';
		customerAddressLine1 = customer.address?.addressLine1 || '';
		customerAddressLine2 = customer.address?.addressLine2 || '';
		customerCity = customer.address?.city || '';
		customerProvinceCode = customer.address?.provinceCode || '';
		customerPostalCode = customer.address?.postalCode || '';
		customerFormError = null;
		showCustomerPanel = true;
	}

	function closeCustomerPanel() {
		showCustomerPanel = false;
		editingCustomer = null;
		customerFormError = null;
	}

	async function saveCustomer() {
		if (!editingCustomer) return;
		if (!customerName.trim()) {
			customerFormError = 'Name is required';
			return;
		}

		customerFormLoading = true;
		customerFormError = null;

		try {
			const result = await client.mutate<{
				updateWaveCustomer: { success: boolean; error?: string };
			}>({
				mutation: UPDATE_WAVE_CUSTOMER,
				variables: {
					input: {
						id: editingCustomer.id,
						name: customerName.trim(),
						email: customerEmail.trim() || null,
						currency: customerCurrency,
						address: {
							addressLine1: customerAddressLine1.trim() || null,
							addressLine2: customerAddressLine2.trim() || null,
							city: customerCity.trim() || null,
							provinceCode: customerProvinceCode.trim() || null,
							postalCode: customerPostalCode.trim() || null,
							countryCode: 'US'
						}
					}
				}
			});

			if (result.data?.updateWaveCustomer.success) {
				await invalidateAll();
				closeCustomerPanel();
			} else {
				customerFormError = result.data?.updateWaveCustomer.error || 'Failed to update customer';
			}
		} catch (err) {
			customerFormError = err instanceof Error ? err.message : 'Failed to update customer';
		} finally {
			customerFormLoading = false;
		}
	}

	async function deleteCustomer(customer: WaveCustomer) {
		if (
			!confirm(
				`Are you sure you want to delete "${customer.name}" from Wave?\n\nThis will not delete the associated Nexus customer.`
			)
		) {
			return;
		}

		actionLoading = customer.id;
		actionError = null;

		try {
			const result = await client.mutate<{
				deleteWaveCustomer: { success: boolean; error?: string };
			}>({
				mutation: DELETE_WAVE_CUSTOMER,
				variables: { customerId: customer.id }
			});

			if (result.data?.deleteWaveCustomer.success) {
				await invalidateAll();
			} else {
				actionError = result.data?.deleteWaveCustomer.error || 'Failed to delete customer';
			}
		} catch (err) {
			actionError = err instanceof Error ? err.message : 'Failed to delete customer';
		} finally {
			actionLoading = null;
		}
	}

	// ============================================================================
	// Product CRUD State
	// ============================================================================

	let showProductPanel = $state(false);
	let editingProduct = $state<WaveProduct | null>(null);
	let productFormError = $state<string | null>(null);
	let productFormLoading = $state(false);

	// Product form fields
	let productName = $state('');
	let productDescription = $state('');
	let productUnitPrice = $state('0.00');
	let productIsSold = $state(true);

	function openProductCreate() {
		editingProduct = null;
		productName = '';
		productDescription = '';
		productUnitPrice = '0.00';
		productIsSold = true;
		productFormError = null;
		showProductPanel = true;
	}

	function openProductEdit(product: WaveProduct) {
		editingProduct = product;
		productName = product.name;
		productDescription = product.description || '';
		productUnitPrice = product.unitPrice.toFixed(2);
		productIsSold = product.isSold;
		productFormError = null;
		showProductPanel = true;
	}

	function closeProductPanel() {
		showProductPanel = false;
		editingProduct = null;
		productFormError = null;
	}

	async function saveProduct() {
		if (!productName.trim()) {
			productFormError = 'Name is required';
			return;
		}

		const unitPrice = parseFloat(productUnitPrice);
		if (isNaN(unitPrice) || unitPrice < 0) {
			productFormError = 'Invalid unit price';
			return;
		}

		productFormLoading = true;
		productFormError = null;

		try {
			if (editingProduct) {
				// Update existing product
				const result = await client.mutate<{
					updateWaveProduct: { success: boolean; error?: string };
				}>({
					mutation: UPDATE_WAVE_PRODUCT,
					variables: {
						input: {
							id: editingProduct.id,
							name: productName.trim(),
							description: productDescription.trim() || null,
							unitPrice
						}
					}
				});

				if (result.data?.updateWaveProduct.success) {
					await invalidateAll();
					closeProductPanel();
				} else {
					productFormError = result.data?.updateWaveProduct.error || 'Failed to update product';
				}
			} else {
				// Create new product
				const result = await client.mutate<{
					createWaveProduct: { success: boolean; error?: string };
				}>({
					mutation: CREATE_WAVE_PRODUCT,
					variables: {
						input: {
							name: productName.trim(),
							description: productDescription.trim() || null,
							unitPrice,
							isSold: productIsSold
						}
					}
				});

				if (result.data?.createWaveProduct.success) {
					await invalidateAll();
					closeProductPanel();
				} else {
					productFormError = result.data?.createWaveProduct.error || 'Failed to create product';
				}
			}
		} catch (err) {
			productFormError = err instanceof Error ? err.message : 'Failed to save product';
		} finally {
			productFormLoading = false;
		}
	}

	// ============================================================================
	// Invoice Actions
	// ============================================================================

	// Status badge colors
	function getStatusColor(status: string): string {
		switch (status) {
			case 'DRAFT':
				return 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300';
			case 'SAVED':
				return 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400';
			case 'SENT':
				return 'bg-indigo-100 text-indigo-800 dark:bg-indigo-900/30 dark:text-indigo-400';
			case 'VIEWED':
				return 'bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-400';
			case 'PAID':
				return 'bg-success-100 text-success-800 dark:bg-success-900/30 dark:text-success-400';
			case 'PARTIAL':
				return 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400';
			case 'OVERDUE':
				return 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400';
			default:
				return 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300';
		}
	}

	// Format currency (strip commas since Wave returns values like "1,600.00")
	function formatMoney(value: string, symbol: string): string {
		const num = parseFloat(value.replace(/,/g, ''));
		return `${symbol}${num.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
	}

	// Format date
	function formatDate(dateStr: string): string {
		return new Date(dateStr).toLocaleDateString('en-US', {
			year: 'numeric',
			month: 'short',
			day: 'numeric'
		});
	}

	async function approveInvoice(invoice: WaveInvoiceListItem) {
		if (
			!confirm(
				'Are you sure you want to approve this invoice?\n\nThis is a point of no return - the invoice cannot be edited after approval.'
			)
		) {
			return;
		}

		actionLoading = invoice.id;
		actionError = null;

		try {
			const result = await client.mutate<{
				approveWaveInvoice: { success: boolean; error?: string };
			}>({
				mutation: APPROVE_WAVE_INVOICE,
				variables: { invoiceId: invoice.id }
			});

			if (result.data?.approveWaveInvoice.success) {
				await invalidateAll();
			} else {
				actionError = result.data?.approveWaveInvoice.error || 'Failed to approve invoice';
			}
		} catch (err) {
			actionError = err instanceof Error ? err.message : 'Failed to approve invoice';
		} finally {
			actionLoading = null;
		}
	}

	async function sendInvoice(invoice: WaveInvoiceListItem) {
		if (
			!confirm(
				`Are you sure you want to send invoice #${invoice.invoiceNumber} to ${invoice.customer.name}?\n\nThis will email the invoice to the customer.`
			)
		) {
			return;
		}

		actionLoading = invoice.id;
		actionError = null;

		try {
			const result = await client.mutate<{ sendWaveInvoice: { success: boolean; error?: string } }>(
				{
					mutation: SEND_WAVE_INVOICE,
					variables: { invoiceId: invoice.id }
				}
			);

			if (result.data?.sendWaveInvoice.success) {
				await invalidateAll();
			} else {
				actionError = result.data?.sendWaveInvoice.error || 'Failed to send invoice';
			}
		} catch (err) {
			actionError = err instanceof Error ? err.message : 'Failed to send invoice';
		} finally {
			actionLoading = null;
		}
	}

	async function deleteInvoice(invoice: WaveInvoiceListItem) {
		if (!confirm(`Are you sure you want to delete draft invoice #${invoice.invoiceNumber}?`)) {
			return;
		}

		actionLoading = invoice.id;
		actionError = null;

		try {
			const result = await client.mutate<{
				deleteWaveInvoice: { success: boolean; error?: string };
			}>({
				mutation: DELETE_WAVE_INVOICE,
				variables: { invoiceId: invoice.id }
			});

			if (result.data?.deleteWaveInvoice.success) {
				await invalidateAll();
			} else {
				actionError = result.data?.deleteWaveInvoice.error || 'Failed to delete invoice';
			}
		} catch (err) {
			actionError = err instanceof Error ? err.message : 'Failed to delete invoice';
		} finally {
			actionLoading = null;
		}
	}

	async function archiveProduct(product: WaveProduct) {
		if (!confirm(`Are you sure you want to archive "${product.name}"?`)) {
			return;
		}

		actionLoading = product.id;
		actionError = null;

		try {
			const result = await client.mutate<{
				archiveWaveProduct: { success: boolean; error?: string };
			}>({
				mutation: ARCHIVE_WAVE_PRODUCT,
				variables: { productId: product.id }
			});

			if (result.data?.archiveWaveProduct.success) {
				await invalidateAll();
			} else {
				actionError = result.data?.archiveWaveProduct.error || 'Failed to archive product';
			}
		} catch (err) {
			actionError = err instanceof Error ? err.message : 'Failed to archive product';
		} finally {
			actionLoading = null;
		}
	}

	// Helper for loading state
	function isLoading(id: string): boolean {
		return actionLoading === id;
	}
</script>

<svelte:head>
	<title>Wave Management | Nexus</title>
</svelte:head>

<div class="py-8">
	<ContentContainer>
		<!-- Header -->
		<AdminDashboardHeader
			title="Wave Accounting"
			subtitle="Manage invoices, products, and customers"
			backHref="/admin/invoices"
		/>

		<!-- Error display -->
		{#if actionError}
			<div class="mb-6 rounded-lg bg-red-50 p-4 dark:bg-red-900/20">
				<div class="flex">
					<svg class="h-5 w-5 shrink-0 text-red-400" viewBox="0 0 20 20" fill="currentColor">
						<path
							fill-rule="evenodd"
							d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
							clip-rule="evenodd"
						/>
					</svg>
					<div class="ml-3 flex-1">
						<p class="text-sm font-medium text-red-800 dark:text-red-200">{actionError}</p>
					</div>
					<button
						type="button"
						class="ml-3 shrink-0 text-red-400 hover:text-red-500"
						onclick={() => {
							actionError = null;
						}}
						aria-label="Dismiss error"
					>
						<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
							<path
								fill-rule="evenodd"
								d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
								clip-rule="evenodd"
							/>
						</svg>
					</button>
				</div>
			</div>
		{/if}

		<!-- Mobile Tab Navigation (carousel style) -->
		<div class="bg-theme-surface mb-6 flex items-center justify-between rounded-lg p-3 md:hidden">
			<button
				type="button"
				onclick={prevTab}
				class="rounded-lg p-2 text-theme-secondary hover:bg-theme-card hover:text-theme"
				aria-label="Previous tab"
			>
				<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="M15 19l-7-7 7-7"
					/>
				</svg>
			</button>
			<div class="text-center">
				<span class="font-medium text-theme">{tabs[activeTabIndex].label}</span>
				<span class="ml-2 rounded-full bg-theme-card px-2 py-0.5 text-xs text-theme-secondary">
					{getTabCount(tabs[activeTabIndex].id)}
				</span>
			</div>
			<button
				type="button"
				onclick={nextTab}
				class="rounded-lg p-2 text-theme-secondary hover:bg-theme-card hover:text-theme"
				aria-label="Next tab"
			>
				<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="M9 5l7 7-7 7" />
				</svg>
			</button>
		</div>

		<!-- Desktop Tab Navigation -->
		<div class="border-theme-border mb-6 hidden border-b md:block">
			<nav class="-mb-px flex gap-6">
				{#each tabs as tab, i}
					<button
						type="button"
						class="border-b-2 px-1 py-4 text-sm font-medium transition-colors {activeTabIndex === i
							? 'border-accent6-500 text-accent6-600 dark:text-accent6-400'
							: 'border-transparent text-theme-secondary hover:border-gray-300 hover:text-theme'}"
						onclick={() => {
							activeTabIndex = i;
						}}
					>
						{tab.label}
						<span
							class="ml-2 rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium text-gray-600 dark:bg-gray-700 dark:text-gray-300"
						>
							{getTabCount(tab.id)}
						</span>
					</button>
				{/each}
			</nav>
		</div>

		<!-- Tab Content -->
		{#if activeTab === 'invoices'}
			<!-- Invoices Tab - Card Grid -->
			{#if invoices.invoices.length === 0}
				<div class="rounded-lg border border-dashed border-theme py-12 text-center">
					<svg
						class="mx-auto h-12 w-12 text-theme-muted"
						fill="none"
						stroke="currentColor"
						viewBox="0 0 24 24"
					>
						<path
							stroke-linecap="round"
							stroke-linejoin="round"
							stroke-width="1.5"
							d="M9 12h6m-6 4h6m2 5H7a2 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>
					<h3 class="mt-4 text-lg font-medium text-theme">No invoices in Wave</h3>
					<p class="mt-2 text-theme-secondary">
						Create invoices from the Nexus invoices page to sync them to Wave.
					</p>
				</div>
			{:else}
				<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
					{#each invoices.invoices as invoice (invoice.id)}
						<div class="card-invoice">
							<!-- Header: Invoice number + Status (clickable) -->
							<a href="/admin/invoices/wave/{invoice.id}" class="block hover:opacity-80">
								<div class="flex items-center justify-between">
									<span class="font-mono text-sm text-theme-muted">#{invoice.invoiceNumber}</span>
									<span
										class="shrink-0 rounded-full px-2 py-0.5 text-xs font-semibold {getStatusColor(
											invoice.status
										)}"
									>
										{invoice.status}
									</span>
								</div>

								<!-- Customer Name -->
								<h3 class="mt-2 truncate font-semibold text-theme">{invoice.customer.name}</h3>

								<!-- Dates -->
								<div
									class="mt-2 flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-theme-secondary"
								>
									<span>Issued: {formatDate(invoice.invoiceDate)}</span>
									{#if invoice.dueDate}
										<span>Due: {formatDate(invoice.dueDate)}</span>
									{/if}
								</div>

								<!-- Financial Summary -->
								<div
									class="border-theme-border mt-3 flex items-center justify-between border-t pt-3"
								>
									<div class="text-sm">
										{#if parseFloat(invoice.amountDue.value.replace(/,/g, '')) > 0}
											<span class="text-theme-muted">Due:</span>
											<span class="ml-1 font-medium text-red-600 dark:text-red-400">
												{formatMoney(invoice.amountDue.value, invoice.amountDue.currencySymbol)}
											</span>
										{:else}
											<span class="font-medium text-success-600 dark:text-success-400">Paid</span>
										{/if}
									</div>
									<span class="text-lg font-bold text-accent6-600 dark:text-accent6-400">
										{formatMoney(invoice.total.value, invoice.total.currencySymbol)}
									</span>
								</div>
							</a>

							<!-- Actions -->
							{#if invoice.status === 'DRAFT' || invoice.status === 'SAVED'}
								<div class="border-theme-border mt-3 flex gap-2 border-t pt-3">
									{#if invoice.status === 'DRAFT'}
										<button
											type="button"
											class="btn-primary flex-1 py-1.5 text-sm"
											onclick={() => approveInvoice(invoice)}
											disabled={isLoading(invoice.id)}
										>
											{#if isLoading(invoice.id)}
												<svg class="mx-auto h-4 w-4 animate-spin" fill="none" viewBox="0 0 24 24">
													<circle
														class="opacity-25"
														cx="12"
														cy="12"
														r="10"
														stroke="currentColor"
														stroke-width="4"
													></circle>
													<path
														class="opacity-75"
														fill="currentColor"
														d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
													></path>
												</svg>
											{:else}
												Approve
											{/if}
										</button>
										<button
											type="button"
											class="btn-danger flex-1 py-1.5 text-sm"
											onclick={() => deleteInvoice(invoice)}
											disabled={isLoading(invoice.id)}
										>
											Delete
										</button>
									{:else if invoice.status === 'SAVED'}
										<button
											type="button"
											class="btn-primary flex-1 py-1.5 text-sm"
											onclick={() => sendInvoice(invoice)}
											disabled={isLoading(invoice.id)}
										>
											{#if isLoading(invoice.id)}
												<svg class="mx-auto h-4 w-4 animate-spin" fill="none" viewBox="0 0 24 24">
													<circle
														class="opacity-25"
														cx="12"
														cy="12"
														r="10"
														stroke="currentColor"
														stroke-width="4"
													></circle>
													<path
														class="opacity-75"
														fill="currentColor"
														d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
													></path>
												</svg>
											{:else}
												Send
											{/if}
										</button>
									{/if}
								</div>
							{/if}
						</div>
					{/each}
				</div>

				<!-- Pagination -->
				{#if invoices.pageInfo.totalPages > 1}
					<div class="mt-6 flex flex-col items-center justify-between gap-4 sm:flex-row">
						<p class="text-sm text-theme-secondary">
							Page {invoices.pageInfo.currentPage} of {invoices.pageInfo.totalPages}
							({invoices.pageInfo.totalCount} total)
						</p>
						<div class="flex gap-2">
							<a
								href="?page={Math.max(1, invoices.pageInfo.currentPage - 1)}"
								class="btn-secondary text-sm {invoices.pageInfo.currentPage === 1
									? 'pointer-events-none opacity-50'
									: ''}"
							>
								Previous
							</a>
							<a
								href="?page={Math.min(
									invoices.pageInfo.totalPages,
									invoices.pageInfo.currentPage + 1
								)}"
								class="btn-secondary text-sm {invoices.pageInfo.currentPage ===
								invoices.pageInfo.totalPages
									? 'pointer-events-none opacity-50'
									: ''}"
							>
								Next
							</a>
						</div>
					</div>
				{/if}
			{/if}
		{:else if activeTab === 'products'}
			<!-- Products Tab - Card Grid -->
			<div class="mb-4 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
				<label class="flex items-center gap-2 text-sm text-theme-secondary">
					<input
						type="checkbox"
						bind:checked={showArchivedProducts}
						class="rounded border-gray-300 text-accent-600 focus:ring-accent-500"
					/>
					Show archived ({archivedProducts.length})
				</label>
				<button
					type="button"
					class="btn-primary flex items-center justify-center gap-2"
					onclick={openProductCreate}
				>
					<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="M12 4v16m8-8H4"
						/>
					</svg>
					New Product
				</button>
			</div>

			{#if activeProducts.length === 0 && !showArchivedProducts}
				<div class="rounded-lg border border-dashed border-theme py-12 text-center">
					<svg
						class="mx-auto h-12 w-12 text-theme-muted"
						fill="none"
						stroke="currentColor"
						viewBox="0 0 24 24"
					>
						<path
							stroke-linecap="round"
							stroke-linejoin="round"
							stroke-width="1.5"
							d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"
						/>
					</svg>
					<h3 class="mt-4 text-lg font-medium text-theme">No products in Wave</h3>
					<p class="mt-2 text-theme-secondary">Create a product to start using it on invoices.</p>
					<button type="button" class="mt-4 btn-primary" onclick={openProductCreate}>
						Create Product
					</button>
				</div>
			{:else}
				<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
					{#each showArchivedProducts ? products : activeProducts as product (product.id)}
						<div class="card-invoice {product.isArchived ? 'opacity-60' : ''}">
							<!-- Header: Name + Archived badge -->
							<div class="flex items-start justify-between gap-2">
								<h3 class="font-semibold text-theme">{product.name}</h3>
								{#if product.isArchived}
									<span
										class="shrink-0 rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-600 dark:bg-gray-700 dark:text-gray-300"
									>
										Archived
									</span>
								{/if}
							</div>

							<!-- Description -->
							{#if product.description}
								<p class="mt-1 line-clamp-2 text-sm text-theme-secondary">{product.description}</p>
							{:else}
								<p class="mt-1 text-sm text-theme-muted italic">No description</p>
							{/if}

							<!-- Price + Is Sold -->
							<div class="mt-3 flex items-center justify-between">
								<span class="text-lg font-semibold text-accent6-600 dark:text-accent6-400">
									${product.unitPrice.toLocaleString('en-US', {
										minimumFractionDigits: 2,
										maximumFractionDigits: 2
									})}
								</span>
								{#if product.isSold}
									<span
										class="rounded-full bg-success-100 px-2 py-0.5 text-xs font-medium text-success-800 dark:bg-success-900/30 dark:text-success-400"
									>
										For Sale
									</span>
								{:else}
									<span
										class="rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-600 dark:bg-gray-700 dark:text-gray-300"
									>
										Expense
									</span>
								{/if}
							</div>

							<!-- Actions -->
							{#if !product.isArchived}
								<div class="border-theme-border mt-3 flex justify-end gap-3 border-t pt-3">
									<button
										type="button"
										class="text-sm text-accent6-600 hover:text-accent6-700 dark:text-accent6-400 dark:hover:text-accent6-300"
										onclick={() => openProductEdit(product)}
									>
										Edit
									</button>
									<button
										type="button"
										class="text-sm text-red-600 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"
										onclick={() => archiveProduct(product)}
										disabled={isLoading(product.id)}
									>
										{#if isLoading(product.id)}
											<svg class="h-4 w-4 animate-spin" fill="none" viewBox="0 0 24 24">
												<circle
													class="opacity-25"
													cx="12"
													cy="12"
													r="10"
													stroke="currentColor"
													stroke-width="4"
												></circle>
												<path
													class="opacity-75"
													fill="currentColor"
													d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
												></path>
											</svg>
										{:else}
											Archive
										{/if}
									</button>
								</div>
							{/if}
						</div>
					{/each}
				</div>
			{/if}
		{:else if activeTab === 'customers'}
			<!-- Customers Tab - Card Grid -->
			{#if customers.length === 0}
				<div class="rounded-lg border border-dashed border-theme py-12 text-center">
					<svg
						class="mx-auto h-12 w-12 text-theme-muted"
						fill="none"
						stroke="currentColor"
						viewBox="0 0 24 24"
					>
						<path
							stroke-linecap="round"
							stroke-linejoin="round"
							stroke-width="1.5"
							d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
						/>
					</svg>
					<h3 class="mt-4 text-lg font-medium text-theme">No customers in Wave</h3>
					<p class="mt-2 text-theme-secondary">
						Link Nexus customers to Wave from the customer edit page.
					</p>
				</div>
			{:else}
				<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
					{#each customers as customer (customer.id)}
						<div class="card-invoice">
							<!-- Name -->
							<h3 class="font-semibold text-theme">{customer.name}</h3>

							<!-- Email -->
							{#if customer.email}
								<p class="mt-1 truncate text-sm text-theme-secondary">{customer.email}</p>
							{:else}
								<p class="mt-1 text-sm text-theme-muted italic">No email</p>
							{/if}

							<!-- Currency -->
							<div class="mt-3 flex items-center justify-between">
								<span class="text-xs text-theme-muted">Currency</span>
								<span
									class="rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-600 dark:bg-gray-700 dark:text-gray-300"
								>
									{customer.currencyCode || 'USD'}
								</span>
							</div>

							<!-- Actions -->
							<div class="border-theme-border mt-3 flex justify-end gap-3 border-t pt-3">
								<button
									type="button"
									class="text-sm text-accent6-600 hover:text-accent6-700 dark:text-accent6-400 dark:hover:text-accent6-300"
									onclick={() => openCustomerEdit(customer)}
								>
									Edit
								</button>
								<button
									type="button"
									class="text-sm text-red-600 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"
									onclick={() => deleteCustomer(customer)}
									disabled={isLoading(customer.id)}
								>
									{#if isLoading(customer.id)}
										<svg class="h-4 w-4 animate-spin" fill="none" viewBox="0 0 24 24">
											<circle
												class="opacity-25"
												cx="12"
												cy="12"
												r="10"
												stroke="currentColor"
												stroke-width="4"
											></circle>
											<path
												class="opacity-75"
												fill="currentColor"
												d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
											></path>
										</svg>
									{:else}
										Delete
									{/if}
								</button>
							</div>
						</div>
					{/each}
				</div>
			{/if}
		{/if}
	</ContentContainer>
</div>

<!-- Customer Edit Slide-over -->
{#if showCustomerPanel}
	<!-- Backdrop -->
	<button
		type="button"
		class="fixed inset-0 z-40 cursor-default bg-overlay backdrop-blur-sm"
		onclick={closeCustomerPanel}
		aria-label="Close panel"
		transition:fade={{ duration: 200 }}
	></button>

	<!-- Panel -->
	<div
		class="fixed inset-0 z-50 flex flex-col bg-theme-card
			sm:inset-y-0 sm:right-0 sm:left-auto sm:w-1/2 sm:max-w-xl sm:min-w-100 sm:border-l sm:border-theme sm:shadow-2xl"
		role="dialog"
		aria-modal="true"
		aria-labelledby="customer-panel-title"
		transition:fly={{ x: 400, duration: 250 }}
	>
		<!-- Header -->
		<div class="flex shrink-0 items-center justify-between border-b border-theme px-5 py-4">
			<h2 id="customer-panel-title" class="text-lg font-semibold text-theme">Edit Customer</h2>
			<button
				type="button"
				class="rounded-lg p-2 text-theme-muted transition-colors hover:bg-theme-secondary hover:text-theme"
				onclick={closeCustomerPanel}
				aria-label="Close drawer"
			>
				<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>
		</div>

		<!-- Form -->
		<div class="flex-1 overflow-y-auto px-5 py-5">
			{#if customerFormError}
				<div
					class="mb-4 rounded-lg bg-red-100 p-3 text-sm text-red-700 dark:bg-red-900/30 dark:text-red-400"
				>
					{customerFormError}
				</div>
			{/if}

			<form
				id="customerForm"
				onsubmit={(e) => {
					e.preventDefault();
					saveCustomer();
				}}
			>
				<label class="mb-4 block">
					<span class="mb-1 block text-sm font-medium text-theme">Name</span>
					<input
						type="text"
						bind:value={customerName}
						class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme"
						required
					/>
				</label>

				<label class="mb-4 block">
					<span class="mb-1 block text-sm font-medium text-theme">Email</span>
					<input
						type="email"
						bind:value={customerEmail}
						class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme"
					/>
				</label>

				<label class="mb-4 block">
					<span class="mb-1 block text-sm font-medium text-theme">Currency</span>
					<select
						bind:value={customerCurrency}
						class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme"
					>
						<option value="USD">USD - US Dollar</option>
						<option value="CAD">CAD - Canadian Dollar</option>
						<option value="EUR">EUR - Euro</option>
						<option value="GBP">GBP - British Pound</option>
					</select>
				</label>

				<div class="mb-4 border-t border-theme pt-4">
					<h3 class="mb-3 text-sm font-medium text-theme">Address</h3>

					<label class="mb-3 block">
						<span class="mb-1 block text-sm text-theme-secondary">Street Address</span>
						<input
							type="text"
							bind:value={customerAddressLine1}
							class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme"
							placeholder="123 Main St"
						/>
					</label>

					<label class="mb-3 block">
						<span class="mb-1 block text-sm text-theme-secondary">Address Line 2</span>
						<input
							type="text"
							bind:value={customerAddressLine2}
							class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme"
							placeholder="Suite 100"
						/>
					</label>

					<div class="mb-3 grid grid-cols-2 gap-3">
						<label class="block">
							<span class="mb-1 block text-sm text-theme-secondary">City</span>
							<input
								type="text"
								bind:value={customerCity}
								class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme"
							/>
						</label>
						<label class="block">
							<span class="mb-1 block text-sm text-theme-secondary">State/Province</span>
							<input
								type="text"
								bind:value={customerProvinceCode}
								class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme"
								placeholder="CA"
							/>
						</label>
					</div>

					<label class="block">
						<span class="mb-1 block text-sm text-theme-secondary">Postal Code</span>
						<input
							type="text"
							bind:value={customerPostalCode}
							class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme"
						/>
					</label>
				</div>
			</form>
		</div>

		<!-- Footer -->
		<div class="flex shrink-0 justify-end gap-3 border-t border-theme px-5 py-4">
			<button
				type="button"
				class="btn-ghost"
				onclick={closeCustomerPanel}
				disabled={customerFormLoading}
			>
				Cancel
			</button>
			<button type="submit" form="customerForm" class="btn-primary" disabled={customerFormLoading}>
				{customerFormLoading ? 'Saving...' : 'Save Changes'}
			</button>
		</div>
	</div>
{/if}

<!-- Product Create/Edit Slide-over -->
{#if showProductPanel}
	<!-- Backdrop -->
	<button
		type="button"
		class="fixed inset-0 z-40 cursor-default bg-overlay backdrop-blur-sm"
		onclick={closeProductPanel}
		aria-label="Close panel"
		transition:fade={{ duration: 200 }}
	></button>

	<!-- Panel -->
	<div
		class="fixed inset-0 z-50 flex flex-col bg-theme-card
			sm:inset-y-0 sm:right-0 sm:left-auto sm:w-1/2 sm:max-w-xl sm:min-w-100 sm:border-l sm:border-theme sm:shadow-2xl"
		role="dialog"
		aria-modal="true"
		aria-labelledby="product-panel-title"
		transition:fly={{ x: 400, duration: 250 }}
	>
		<!-- Header -->
		<div class="flex shrink-0 items-center justify-between border-b border-theme px-5 py-4">
			<h2 id="product-panel-title" class="text-lg font-semibold text-theme">
				{editingProduct ? 'Edit Product' : 'New Product'}
			</h2>
			<button
				type="button"
				class="rounded-lg p-2 text-theme-muted transition-colors hover:bg-theme-secondary hover:text-theme"
				onclick={closeProductPanel}
				aria-label="Close drawer"
			>
				<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>
		</div>

		<!-- Form -->
		<div class="flex-1 overflow-y-auto px-5 py-5">
			{#if productFormError}
				<div
					class="mb-4 rounded-lg bg-red-100 p-3 text-sm text-red-700 dark:bg-red-900/30 dark:text-red-400"
				>
					{productFormError}
				</div>
			{/if}

			<form
				id="productForm"
				onsubmit={(e) => {
					e.preventDefault();
					saveProduct();
				}}
			>
				<label class="mb-4 block">
					<span class="mb-1 block text-sm font-medium text-theme">Name</span>
					<input
						type="text"
						bind:value={productName}
						class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme"
						placeholder="Cleaning Service"
						required
					/>
				</label>

				<label class="mb-4 block">
					<span class="mb-1 block text-sm font-medium text-theme">Description</span>
					<textarea
						bind:value={productDescription}
						class="w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme"
						rows="3"
						placeholder="Optional description..."
					></textarea>
				</label>

				<label class="mb-4 block">
					<span class="mb-1 block text-sm font-medium text-theme">Unit Price</span>
					<span class="relative block">
						<span class="absolute top-1/2 left-3 -translate-y-1/2 text-theme-muted">$</span>
						<input
							type="number"
							step="0.01"
							min="0"
							bind:value={productUnitPrice}
							class="w-full rounded-lg border border-theme bg-theme py-2 pr-3 pl-7 text-theme"
							required
						/>
					</span>
				</label>

				{#if !editingProduct}
					<label class="flex items-center gap-3">
						<input
							type="checkbox"
							bind:checked={productIsSold}
							class="rounded border-gray-300 text-accent6-600 focus:ring-accent6-500"
						/>
						<span>
							<span class="block text-sm font-medium text-theme">Product for Sale</span>
							<span class="text-xs text-theme-secondary"
								>Enable if this product generates revenue (vs expense)</span
							>
						</span>
					</label>
				{/if}
			</form>
		</div>

		<!-- Footer -->
		<div class="flex shrink-0 justify-end gap-3 border-t border-theme px-5 py-4">
			<button
				type="button"
				class="btn-ghost"
				onclick={closeProductPanel}
				disabled={productFormLoading}
			>
				Cancel
			</button>
			<button type="submit" form="productForm" class="btn-primary" disabled={productFormLoading}>
				{productFormLoading ? 'Saving...' : editingProduct ? 'Save Changes' : 'Create Product'}
			</button>
		</div>
	</div>
{/if}
