<script lang="ts">
	import { client } from '$lib/graphql/client';
	import { CREATE_PROJECT, type CreateProjectInput } from '$lib/graphql/mutations/project';
	import {
		CUSTOMERS_QUERY,
		type CustomerListItem,
		type CustomersQueryResult
	} from '$lib/graphql/queries/customers';
	import {
		ACCOUNTS_QUERY,
		type AccountListItem,
		type AccountsQueryResult
	} from '$lib/graphql/queries/accounts';
	import {
		ACCOUNT_QUERY,
		type Account,
		type AccountQueryResult
	} from '$lib/graphql/queries/account';

	interface Props {
		onSuccess: (projectId: string) => void;
		onCancel: () => void;
	}

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

	// Form state
	let customerId = $state('');
	let name = $state('');
	let date = $state(getTodayDate());

	// Location - either from account address or manual
	let locationType = $state<'account' | 'manual'>('manual');
	let accountId = $state('');
	let accountAddressId = $state('');
	let streetAddress = $state('');
	let city = $state('');
	let stateCode = $state('');
	let zipCode = $state('');

	// Data state
	let customers: CustomerListItem[] = $state([]);
	let accounts: AccountListItem[] = $state([]);
	let selectedAccount: Account | null = $state(null);
	let loadingCustomers = $state(true);
	let loadingAccounts = $state(false);
	let loadingAddresses = $state(false);

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

	function getTodayDate(): string {
		return new Date().toISOString().split('T')[0];
	}

	// Load customers on mount
	$effect(() => {
		loadCustomers();
	});

	// Load accounts when customer changes
	$effect(() => {
		if (customerId) {
			loadCustomerAccounts(customerId);
		} else {
			accounts = [];
			selectedAccount = null;
			accountId = '';
			accountAddressId = '';
		}
	});

	// Load addresses when account changes
	$effect(() => {
		if (accountId && locationType === 'account') {
			loadAccountAddresses(accountId);
		} else if (!accountId) {
			selectedAccount = null;
			accountAddressId = '';
		}
	});

	async function loadCustomers() {
		try {
			const result = await client.query<CustomersQueryResult>({
				query: CUSTOMERS_QUERY,
				variables: { filter: { isActive: true } },
				fetchPolicy: 'network-only'
			});
			customers = result.data?.customers ?? [];
		} catch (err) {
			error = 'Failed to load customers';
		} finally {
			loadingCustomers = false;
		}
	}

	async function loadCustomerAccounts(custId: string) {
		loadingAccounts = true;
		accounts = [];
		accountId = '';
		try {
			const result = await client.query<AccountsQueryResult>({
				query: ACCOUNTS_QUERY,
				variables: { customerId: custId, filter: { isActive: true } },
				fetchPolicy: 'network-only'
			});
			accounts = result.data?.accounts ?? [];
		} catch (err) {
			// Silently fail - accounts are optional
		} finally {
			loadingAccounts = false;
		}
	}

	async function loadAccountAddresses(id: string) {
		loadingAddresses = true;
		accountAddressId = '';
		try {
			const result = await client.query<AccountQueryResult>({
				query: ACCOUNT_QUERY,
				variables: { id },
				fetchPolicy: 'network-only'
			});
			selectedAccount = result.data?.account ?? null;
		} catch (err) {
			error = 'Failed to load account locations';
		} finally {
			loadingAddresses = false;
		}
	}

	let activeAddresses = $derived(
		(selectedAccount as Account | null)?.addresses?.filter((a) => a.isActive) ?? []
	);

	// Validation - manual address is required if not using account address
	let isManualAddressValid = $derived(
		locationType === 'account'
			? true
			: streetAddress.trim() !== '' && city.trim() !== '' && stateCode.trim() !== ''
	);

	let isAccountAddressValid = $derived(locationType === 'manual' ? true : accountAddressId !== '');

	let isFormValid = $derived(
		customerId !== '' &&
			name.trim() !== '' &&
			date !== '' &&
			isManualAddressValid &&
			isAccountAddressValid
	);

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

		try {
			const input: CreateProjectInput = {
				customerId,
				name,
				date
			};

			if (locationType === 'account' && accountAddressId) {
				input.accountAddressId = accountAddressId;
			} else {
				input.streetAddress = streetAddress;
				input.city = city;
				input.state = stateCode;
				input.zipCode = zipCode || undefined;
			}

			const result = await client.mutate<{ createProject: { id: string } }>({
				mutation: CREATE_PROJECT,
				variables: { input }
			});

			onSuccess(result.data!.createProject.id);
		} catch (err) {
			error = err instanceof Error ? err.message : 'An error occurred';
		} finally {
			loading = false;
		}
	}

	function formatAddress(address: {
		name: string | null;
		streetAddress: string;
		city: string;
		state: string;
	}): string {
		const parts = [];
		if (address.name) parts.push(address.name);
		parts.push(`${address.streetAddress}, ${address.city}, ${address.state}`);
		return parts.join(' - ');
	}
</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="customer" class="form-label">
			Customer <span class="required-indicator">*</span>
		</label>
		{#if loadingCustomers}
			<div class="input-base text-theme-muted">Loading customers...</div>
		{:else}
			<select id="customer" bind:value={customerId} class="input-base" required disabled={loading}>
				<option value="">Select a customer...</option>
				{#each customers as customer (customer.id)}
					<option value={customer.id}>{customer.name}</option>
				{/each}
			</select>
		{/if}
	</div>

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

	<div>
		<label for="date" class="form-label">
			Project Date <span class="required-indicator">*</span>
		</label>
		<input id="date" type="date" bind:value={date} class="input-base" required disabled={loading} />
	</div>

	<!-- Location Section -->
	<div class="border-t border-theme pt-5">
		<h3 class="mb-3 text-sm font-medium text-theme">
			Location <span class="required-indicator">*</span>
		</h3>

		<!-- Location Type Toggle -->
		{#if customerId && accounts.length > 0}
			<div class="mb-4 flex gap-2">
				<button
					type="button"
					class="rounded-lg px-3 py-1.5 text-sm font-medium transition-colors {locationType ===
					'account'
						? 'bg-primary-100 text-primary-700 dark:bg-primary-900/30 dark:text-primary-400'
						: 'bg-theme-secondary text-theme-muted hover:text-theme'}"
					onclick={() => {
						locationType = 'account';
						streetAddress = '';
						city = '';
						stateCode = '';
						zipCode = '';
					}}
					disabled={loading}
				>
					From Account
				</button>
				<button
					type="button"
					class="rounded-lg px-3 py-1.5 text-sm font-medium transition-colors {locationType ===
					'manual'
						? 'bg-primary-100 text-primary-700 dark:bg-primary-900/30 dark:text-primary-400'
						: 'bg-theme-secondary text-theme-muted hover:text-theme'}"
					onclick={() => {
						locationType = 'manual';
						accountId = '';
						accountAddressId = '';
					}}
					disabled={loading}
				>
					Manual Entry
				</button>
			</div>
		{/if}

		{#if locationType === 'account' && customerId && accounts.length > 0}
			<!-- Account Selection -->
			<div class="space-y-4">
				<div>
					<label for="account" class="form-label">Account</label>
					{#if loadingAccounts}
						<div class="input-base text-theme-muted">Loading accounts...</div>
					{:else}
						<select id="account" bind:value={accountId} class="input-base" disabled={loading}>
							<option value="">Select an account...</option>
							{#each accounts as account (account.id)}
								<option value={account.id}>{account.name}</option>
							{/each}
						</select>
					{/if}
				</div>

				{#if accountId}
					<div>
						<label for="location" class="form-label">
							Location <span class="required-indicator">*</span>
						</label>
						{#if loadingAddresses}
							<div class="input-base text-theme-muted">Loading locations...</div>
						{:else if activeAddresses.length === 0}
							<div class="input-base text-theme-muted">No active locations for this account</div>
						{:else}
							<select
								id="location"
								bind:value={accountAddressId}
								class="input-base"
								required
								disabled={loading}
							>
								<option value="">Select a location...</option>
								{#each activeAddresses as address (address.id)}
									<option value={address.id}>{formatAddress(address)}</option>
								{/each}
							</select>
						{/if}
					</div>
				{/if}
			</div>
		{:else}
			<!-- Manual Address Entry -->
			<div class="space-y-4">
				<div>
					<label for="streetAddress" class="form-label">
						Street Address <span class="required-indicator">*</span>
					</label>
					<input
						id="streetAddress"
						type="text"
						bind:value={streetAddress}
						class="input-base"
						required={locationType === 'manual'}
						disabled={loading}
						placeholder="123 Main St"
					/>
				</div>

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

					<div>
						<label for="stateCode" class="form-label">
							State <span class="required-indicator">*</span>
						</label>
						<input
							id="stateCode"
							type="text"
							bind:value={stateCode}
							class="input-base"
							required={locationType === 'manual'}
							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>
			</div>
		{/if}
	</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 || !isFormValid}>
			{#if loading}
				Creating...
			{:else}
				Create Project
			{/if}
		</button>
	</div>
</form>
