<script lang="ts">
	import { client } from '$lib/graphql/client';
	import { CREATE_SERVICE, type CreateServiceInput } from '$lib/graphql/mutations/service';
	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: (serviceId: string) => void;
		onCancel: () => void;
	}

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

	// Form state
	let accountId = $state('');
	let accountAddressId = $state('');
	let date = $state(getTodayDate());
	let notes = $state('');

	// Data state
	let accounts: AccountListItem[] = $state([]);
	let selectedAccount: Account | null = $state(null);
	let loadingAccounts = $state(true);
	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 accounts on mount
	$effect(() => {
		loadAccounts();
	});

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

	async function loadAccounts() {
		try {
			const result = await client.query<AccountsQueryResult>({
				query: ACCOUNTS_QUERY,
				variables: { filter: { isActive: true } },
				fetchPolicy: 'network-only'
			});
			accounts = result.data?.accounts ?? [];
		} catch (err) {
			error = 'Failed to load accounts';
		} 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) ?? []
	);

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

		try {
			const input: CreateServiceInput = {
				accountId,
				accountAddressId,
				date,
				notes: notes || undefined
			};

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

			onSuccess(result.data!.createService.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="account" class="form-label">
			Account <span class="required-indicator">*</span>
		</label>
		{#if loadingAccounts}
			<div class="input-base text-theme-muted">Loading accounts...</div>
		{:else}
			<select id="account" bind:value={accountId} class="input-base" required 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>

	<div>
		<label for="location" class="form-label">
			Location <span class="required-indicator">*</span>
		</label>
		{#if !accountId}
			<div class="input-base text-theme-muted">Select an account first</div>
		{:else 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>

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

	<div>
		<label for="notes" class="form-label">Notes</label>
		<textarea
			id="notes"
			bind:value={notes}
			class="textarea-base"
			rows="3"
			disabled={loading}
			placeholder="Add any notes about this service..."
		></textarea>
	</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 || !accountId || !accountAddressId || !date}
		>
			{#if loading}
				Creating...
			{:else}
				Create Service
			{/if}
		</button>
	</div>
</form>
