<script lang="ts">
	import { client } from '$lib/graphql/client';
	import {
		UPDATE_CUSTOMER,
		CREATE_CUSTOMER_ADDRESS,
		UPDATE_CUSTOMER_ADDRESS,
		type UpdateCustomerInput,
		type CreateCustomerAddressInput,
		type UpdateCustomerAddressInput
	} from '$lib/graphql/mutations/customer';
	import type { Customer } from '$lib/graphql/queries/customer';

	interface WaveCustomer {
		id: string;
		name: string;
		email?: string;
	}

	interface Props {
		customer: Customer;
		waveCustomers?: WaveCustomer[];
		onSuccess: () => void;
		onCancel: () => void;
	}

	let { customer, waveCustomers = [], onSuccess, onCancel }: Props = $props();

	// Get active billing address
	let activeAddress = $derived(customer.addresses?.find((a) => a.isActive) ?? null);

	// Form state - use $effect to sync from props
	let name = $state('');
	let status = $state<'ACTIVE' | 'INACTIVE' | 'PENDING'>('ACTIVE');
	let billingEmail = $state('');
	let billingTerms = $state('');
	let waveCustomerId = $state('');
	let startDate = $state('');
	let endDate = $state('');

	// Billing address state
	let streetAddress = $state('');
	let city = $state('');
	let stateCode = $state('');
	let zipCode = $state('');
	let isNewAddress = $state(false); // When true, creates new address instead of updating

	$effect(() => {
		name = customer.name;
		status = (customer.status as 'ACTIVE' | 'INACTIVE' | 'PENDING') ?? 'ACTIVE';
		billingEmail = customer.billingEmail ?? '';
		billingTerms = customer.billingTerms ?? '';
		waveCustomerId = customer.waveCustomerId ?? '';
		startDate = customer.startDate ?? '';
		endDate = customer.endDate ?? '';
		const addr = customer.addresses?.find((a) => a.isActive) ?? null;
		streetAddress = addr?.streetAddress ?? '';
		city = addr?.city ?? '';
		stateCode = addr?.state ?? '';
		zipCode = addr?.zipCode ?? '';
		isNewAddress = false;
	});

	let loading = $state(false);
	let error = $state<string | null>(null);

	// Check if address fields have any content
	let hasAddressData = $derived(
		streetAddress.trim() !== '' || city.trim() !== '' || stateCode.trim() !== ''
	);

	// Check if address has changed from original
	let addressChanged = $derived(
		activeAddress
			? streetAddress !== activeAddress.streetAddress ||
					city !== activeAddress.city ||
					stateCode !== activeAddress.state ||
					zipCode !== activeAddress.zipCode
			: hasAddressData
	);

	async function handleSubmit(event: SubmitEvent) {
		event.preventDefault();
		loading = true;
		error = null;

		try {
			// Update customer info
			const input: UpdateCustomerInput = {
				name: name || undefined,
				status: status || undefined,
				billingEmail: billingEmail || undefined,
				billingTerms: billingTerms || undefined,
				waveCustomerId: waveCustomerId || undefined,
				startDate: startDate || undefined,
				endDate: endDate || undefined
			};

			await client.mutate({
				mutation: UPDATE_CUSTOMER,
				variables: { id: customer.id, input }
			});

			// Handle billing address
			if (hasAddressData && addressChanged) {
				if (activeAddress && isNewAddress) {
					// Mark old address as inactive, then create new one
					await client.mutate({
						mutation: UPDATE_CUSTOMER_ADDRESS,
						variables: { id: activeAddress.id, input: { isActive: false } }
					});
					// Create new address
					const addressInput: CreateCustomerAddressInput = {
						streetAddress,
						city,
						state: stateCode,
						zipCode
					};
					await client.mutate({
						mutation: CREATE_CUSTOMER_ADDRESS,
						variables: { customerId: customer.id, input: addressInput }
					});
				} else if (activeAddress) {
					// Update existing address in place
					const addressInput: UpdateCustomerAddressInput = {
						streetAddress: streetAddress || undefined,
						city: city || undefined,
						state: stateCode || undefined,
						zipCode: zipCode || undefined
					};
					await client.mutate({
						mutation: UPDATE_CUSTOMER_ADDRESS,
						variables: { id: activeAddress.id, input: addressInput }
					});
				} else {
					// No existing address, create new one
					const addressInput: CreateCustomerAddressInput = {
						streetAddress,
						city,
						state: stateCode,
						zipCode
					};
					await client.mutate({
						mutation: CREATE_CUSTOMER_ADDRESS,
						variables: { customerId: customer.id, input: addressInput }
					});
				}
			}

			onSuccess();
		} catch (err) {
			error = err instanceof Error ? err.message : 'An error occurred';
		} finally {
			loading = false;
		}
	}
</script>

<form onsubmit={handleSubmit} class="space-y-5">
	{#if error}
		<div class="rounded-lg border border-error-500/30 bg-error-50/50 p-3 dark:bg-error-950/30">
			<p class="text-sm text-error-700 dark:text-error-400">{error}</p>
		</div>
	{/if}

	<div>
		<label for="name" class="form-label">
			Customer Name <span class="required-indicator">*</span>
		</label>
		<input id="name" type="text" bind:value={name} class="input-base" required disabled={loading} />
	</div>

	<div>
		<label for="status" class="form-label">Status</label>
		<select id="status" bind:value={status} class="select-base" disabled={loading}>
			<option value="ACTIVE">Active</option>
			<option value="INACTIVE">Inactive</option>
			<option value="PENDING">Pending</option>
		</select>
	</div>

	<div>
		<label for="billingEmail" class="form-label">Billing Email</label>
		<input
			id="billingEmail"
			type="email"
			bind:value={billingEmail}
			class="input-base"
			disabled={loading}
		/>
	</div>

	<div>
		<label for="billingTerms" class="form-label">Billing Terms</label>
		<input
			id="billingTerms"
			type="text"
			bind:value={billingTerms}
			class="input-base"
			placeholder="e.g., Net 30"
			disabled={loading}
		/>
	</div>

	<div>
		<label for="waveCustomerId" class="form-label">Wave Customer</label>
		<select
			id="waveCustomerId"
			class="select-base"
			disabled={loading}
			onchange={(e) => (waveCustomerId = e.currentTarget.value)}
		>
			<option value="" selected={!waveCustomerId}>None</option>
			{#each waveCustomers as wc (wc.id)}
				<option value={wc.id} selected={waveCustomerId === wc.id}>
					{wc.name}{wc.email ? ` (${wc.email})` : ''}
				</option>
			{/each}
		</select>
		<p class="mt-1 text-xs text-theme-muted">Wave accounting customer for invoicing</p>
	</div>

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

		<div class="space-y-4">
			<div>
				<label for="streetAddress" class="form-label">Street Address</label>
				<input
					id="streetAddress"
					type="text"
					bind:value={streetAddress}
					class="input-base"
					disabled={loading}
					placeholder="123 Main St"
				/>
			</div>

			<div class="grid grid-cols-2 gap-4">
				<div>
					<label for="city" class="form-label">City</label>
					<input
						id="city"
						type="text"
						bind:value={city}
						class="input-base"
						disabled={loading}
						placeholder="City"
					/>
				</div>

				<div>
					<label for="stateCode" class="form-label">State</label>
					<input
						id="stateCode"
						type="text"
						bind:value={stateCode}
						class="input-base"
						disabled={loading}
						placeholder="CA"
						maxlength="2"
					/>
				</div>
			</div>

			<div class="w-1/2">
				<label for="zipCode" class="form-label">ZIP Code</label>
				<input
					id="zipCode"
					type="text"
					bind:value={zipCode}
					class="input-base"
					disabled={loading}
					placeholder="12345"
					maxlength="10"
				/>
			</div>

			{#if activeAddress && addressChanged}
				<label
					class="bg-theme-secondary/50 flex items-start gap-3 rounded-lg border border-theme p-3"
				>
					<input
						type="checkbox"
						bind:checked={isNewAddress}
						class="border-theme-muted mt-0.5 h-4 w-4 rounded text-primary-600 focus:ring-primary-500"
						disabled={loading}
					/>
					<span>
						<span class="text-sm font-medium text-theme">This is a new address</span>
						<span class="text-xs text-theme-muted">
							Check this if the customer moved. The previous address will be kept in history.
						</span>
					</span>
				</label>
			{/if}
		</div>
	</div>

	<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
		<div>
			<label for="startDate" class="form-label">Start Date</label>
			<input
				id="startDate"
				type="date"
				bind:value={startDate}
				class="input-base"
				disabled={loading}
			/>
		</div>
		<div>
			<label for="endDate" class="form-label">End Date</label>
			<input id="endDate" type="date" bind:value={endDate} class="input-base" disabled={loading} />
		</div>
	</div>

	<div class="form-actions border-t border-theme pt-5">
		<button type="button" class="btn-cancel" onclick={onCancel} disabled={loading}>Cancel</button>
		<button type="submit" class="btn-submit" disabled={loading}>
			{#if loading}
				Saving...
			{:else}
				Update Customer
			{/if}
		</button>
	</div>
</form>
