<script lang="ts">
	import {
		CreateNotificationRuleStore,
		UpdateNotificationRuleStore,
		type EventTypeChoices$options,
		type NotificationChannelChoices$options,
		type RoleChoices$options
	} from '$houdini';
	import { offCanvas } from '$lib/stores/offCanvas.svelte';
	import EventTypeSelector from './EventTypeSelector.svelte';
	import ChannelSelector from './ChannelSelector.svelte';
	import TargetSelector from './TargetSelector.svelte';
	import TemplateEditor from './TemplateEditor.svelte';
	import type { AdminNotificationRules$result } from '$houdini';
	import IconSpinner from '$lib/components/icons/IconSpinner.svelte';

	type NotificationRule = AdminNotificationRules$result['notificationRules'][number];

	interface TeamProfile {
		id: string;
		fullName: string;
		email?: string | null;
		role: string;
	}

	interface CustomerProfile {
		id: string;
		fullName: string;
		email?: string | null;
	}

	interface Props {
		rule?: NotificationRule | null;
		teamProfiles: TeamProfile[];
		customerProfiles: CustomerProfile[];
		onSuccess?: () => void;
		onCancel?: () => void;
	}

	let { rule = null, teamProfiles, customerProfiles, onSuccess, onCancel }: Props = $props();

	let isEdit = $derived(!!rule);
	let submitting = $state(false);
	let error = $state('');

	// Form fields
	let name = $state(rule?.name ?? '');
	let description = $state(rule?.description ?? '');
	let eventTypes = $state<string[]>(rule?.eventTypes ?? []);
	let channels = $state<string[]>(rule?.channels ?? ['IN_APP']);
	let targetRoles = $state<string[]>(rule?.targetRoles ?? []);
	let targetTeamProfileIds = $state<string[]>(rule?.targetTeamProfileIds ?? []);
	let targetCustomerProfileIds = $state<string[]>(rule?.targetCustomerProfileIds ?? []);
	let templateSubject = $state(rule?.templateSubject ?? '');
	let templateBody = $state(rule?.templateBody ?? '');
	let conditions = $state<string>(rule?.conditions ? JSON.stringify(rule.conditions, null, 2) : '');
	let isActive = $state(rule?.isActive ?? true);

	let showAdvanced = $state(false);
	let conditionsError = $state('');

	const createStore = new CreateNotificationRuleStore();
	const updateStore = new UpdateNotificationRuleStore();

	const conditionsExample = '{"status": "COMPLETED"}';

	const roleOptions = [
		{ value: 'ADMIN', label: 'Admin' },
		{ value: 'TEAM_LEADER', label: 'Team Leader' },
		{ value: 'TEAM_MEMBER', label: 'Team Member' }
	];

	function toggleRole(role: string) {
		if (targetRoles.includes(role)) {
			targetRoles = targetRoles.filter((r) => r !== role);
		} else {
			targetRoles = [...targetRoles, role];
		}
	}

	function parseConditions(): Record<string, unknown> | null {
		if (!conditions.trim()) return null;
		try {
			const parsed = JSON.parse(conditions);
			conditionsError = '';
			return parsed;
		} catch {
			conditionsError = 'Invalid JSON';
			return null;
		}
	}

	async function handleSubmit(e: SubmitEvent) {
		e.preventDefault();
		submitting = true;
		error = '';

		try {
			// Validation
			if (!name.trim()) {
				error = 'Please provide a name for the rule';
				return;
			}

			if (eventTypes.length === 0) {
				error = 'Please select at least one event type';
				return;
			}

			if (channels.length === 0) {
				error = 'Please select at least one notification channel';
				return;
			}

			// Parse conditions if provided
			let parsedConditions: Record<string, unknown> | null = null;
			if (conditions.trim()) {
				parsedConditions = parseConditions();
				if (conditionsError) {
					error = 'Invalid JSON in conditions field';
					return;
				}
			}

			if (isEdit && rule) {
				const res = await updateStore.mutate({
					input: {
						id: rule.id,
						name: name.trim(),
						description: description.trim() || null,
						eventTypes: eventTypes as EventTypeChoices$options[],
						channels: channels as NotificationChannelChoices$options[],
						targetRoles: targetRoles.length > 0 ? (targetRoles as RoleChoices$options[]) : null,
						targetTeamProfileIds: targetTeamProfileIds.length > 0 ? targetTeamProfileIds : null,
						targetCustomerProfileIds:
							targetCustomerProfileIds.length > 0 ? targetCustomerProfileIds : null,
						templateSubject: templateSubject.trim() || null,
						templateBody: templateBody.trim() || null,
						conditions: parsedConditions,
						isActive
					}
				});
				if (res.errors?.length) {
					error = res.errors.map((e: { message: string }) => e.message).join(', ');
					return;
				}
			} else {
				const res = await createStore.mutate({
					input: {
						name: name.trim(),
						description: description.trim() || '',
						eventTypes: eventTypes as EventTypeChoices$options[],
						channels: channels as NotificationChannelChoices$options[],
						targetRoles: targetRoles.length > 0 ? (targetRoles as RoleChoices$options[]) : [],
						targetTeamProfileIds: targetTeamProfileIds.length > 0 ? targetTeamProfileIds : [],
						targetCustomerProfileIds:
							targetCustomerProfileIds.length > 0 ? targetCustomerProfileIds : [],
						templateSubject: templateSubject.trim() || '',
						templateBody: templateBody.trim() || '',
						conditions: parsedConditions,
						isActive
					}
				});
				if (res.errors?.length) {
					error = res.errors.map((e: { message: string }) => e.message).join(', ');
					return;
				}
			}

			offCanvas.closeRight();
			onSuccess?.();
		} catch (err) {
			error = err instanceof Error ? err.message : 'Failed to save notification rule';
		} finally {
			submitting = false;
		}
	}

	function handleCancel() {
		offCanvas.closeRight();
		onCancel?.();
	}
</script>

<div class="space-y-6">
	{#if error}
		<div class="alert-error">
			{error}
		</div>
	{/if}

	<form class="space-y-6" onsubmit={handleSubmit}>
		<!-- Basic Info -->
		<div class="space-y-4">
			<h3 class="text-sm font-semibold tracking-wide text-theme-secondary uppercase">Basic Info</h3>

			<div>
				<label for="name" class="mb-1.5 block text-sm font-medium text-theme">
					Name <span class="text-error-500">*</span>
				</label>
				<input
					id="name"
					type="text"
					bind:value={name}
					disabled={submitting}
					placeholder="e.g., Service Completion Alert"
					class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500 disabled:cursor-not-allowed disabled:opacity-50"
				/>
			</div>

			<div>
				<label for="description" class="mb-1.5 block text-sm font-medium text-theme">
					Description
				</label>
				<textarea
					id="description"
					bind:value={description}
					disabled={submitting}
					rows={2}
					placeholder="Describe when this rule triggers and what it does"
					class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme px-3 py-2 text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500 disabled:cursor-not-allowed disabled:opacity-50"
				></textarea>
			</div>

			<!-- Active Toggle -->
			<label class="flex cursor-pointer items-center gap-3">
				<input
					type="checkbox"
					bind:checked={isActive}
					disabled={submitting}
					class="border-theme-muted h-5 w-5 rounded text-primary-500 focus:ring-primary-500"
				/>
				<span class="text-sm font-medium text-theme">Active</span>
				<span class="text-xs text-theme-muted">
					{isActive ? 'This rule will trigger notifications' : 'This rule is disabled'}
				</span>
			</label>
		</div>

		<hr class="border-theme" />

		<!-- Event Types -->
		<div class="space-y-4">
			<h3 class="text-sm font-semibold tracking-wide text-theme-secondary uppercase">
				Trigger Events
			</h3>
			<EventTypeSelector bind:selected={eventTypes} />
		</div>

		<hr class="border-theme" />

		<!-- Channels -->
		<div class="space-y-4">
			<h3 class="text-sm font-semibold tracking-wide text-theme-secondary uppercase">
				Delivery Channels
			</h3>
			<ChannelSelector bind:selected={channels} />
		</div>

		<hr class="border-theme" />

		<!-- Targets -->
		<div class="space-y-4">
			<h3 class="text-sm font-semibold tracking-wide text-theme-secondary uppercase">Recipients</h3>

			<!-- Target by Role -->
			<div>
				<span class="mb-2 block text-sm font-medium text-theme">Target by Role</span>
				<p class="mb-2 text-xs text-theme-muted">
					Leave empty to notify all roles. Select specific roles to limit recipients.
				</p>
				<div class="flex flex-wrap gap-2">
					{#each roleOptions as role (role.value)}
						<button
							type="button"
							onclick={() => toggleRole(role.value)}
							disabled={submitting}
							class="rounded-lg border px-3 py-1.5 text-sm transition-colors {targetRoles.includes(
								role.value
							)
								? 'border-primary-500 bg-primary-500/10 text-primary-600 dark:text-primary-400'
								: 'border-theme bg-theme hover:bg-black/5 dark:hover:bg-white/10'}"
						>
							{role.label}
						</button>
					{/each}
				</div>
				{#if targetRoles.length === 0}
					<p class="mt-2 text-xs text-success-600 dark:text-success-400">
						All team members will receive notifications
					</p>
				{/if}
			</div>

			<!-- Specific Team Members -->
			<TargetSelector
				label="Specific Team Members"
				profiles={teamProfiles}
				bind:selectedIds={targetTeamProfileIds}
				placeholder="Search team members..."
			/>

			<!-- Specific Customers -->
			<TargetSelector
				label="Specific Customers"
				profiles={customerProfiles}
				bind:selectedIds={targetCustomerProfileIds}
				placeholder="Search customers..."
			/>
		</div>

		<hr class="border-theme" />

		<!-- Template -->
		<div class="space-y-4">
			<h3 class="text-sm font-semibold tracking-wide text-theme-secondary uppercase">
				Message Template
			</h3>
			<TemplateEditor
				bind:subject={templateSubject}
				bind:body={templateBody}
				selectedEventTypes={eventTypes}
			/>
		</div>

		<!-- Advanced Options -->
		<div>
			<button
				type="button"
				onclick={() => (showAdvanced = !showAdvanced)}
				class="flex items-center gap-2 text-sm font-medium text-theme-secondary hover:text-theme"
			>
				<svg
					class="h-4 w-4 transition-transform {showAdvanced ? 'rotate-90' : ''}"
					style="fill: none"
					viewBox="0 0 24 24"
					stroke="currentColor"
				>
					<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
				</svg>
				Advanced Options
			</button>

			{#if showAdvanced}
				<div class="mt-4 space-y-4">
					<div>
						<label for="conditions" class="mb-1.5 block text-sm font-medium text-theme">
							Conditions (JSON)
						</label>
						<p class="mb-2 text-xs text-theme-muted">
							Add JSON conditions to filter events. Example: {conditionsExample}
						</p>
						<textarea
							id="conditions"
							bind:value={conditions}
							oninput={() => parseConditions()}
							disabled={submitting}
							rows={3}
							placeholder={conditionsExample}
							class="placeholder-theme-muted w-full rounded-lg border border-theme bg-theme px-3 py-2 font-mono text-sm text-theme focus:border-primary-500 focus:ring-1 focus:ring-primary-500 disabled:cursor-not-allowed disabled:opacity-50"
						></textarea>
						{#if conditionsError}
							<p class="mt-1 text-xs text-error-500">{conditionsError}</p>
						{/if}
					</div>
				</div>
			{/if}
		</div>

		<!-- Actions -->
		<div class="flex items-center gap-3 pt-4">
			<button
				type="submit"
				disabled={submitting}
				class="flex-1 rounded-lg bg-primary-500 px-4 py-2 font-medium text-white transition-colors hover:bg-primary-600 disabled:cursor-not-allowed disabled:opacity-50"
			>
				{#if submitting}
					<span class="flex items-center justify-center gap-2">
						<IconSpinner class="h-4 w-4" />
						<span>{isEdit ? 'Saving...' : 'Creating...'}</span>
					</span>
				{:else}
					{isEdit ? 'Save Changes' : 'Create Rule'}
				{/if}
			</button>
			<button
				type="button"
				onclick={handleCancel}
				disabled={submitting}
				class="rounded-lg border border-theme bg-theme px-4 py-2 font-medium text-theme transition-colors hover:bg-black/5 disabled:cursor-not-allowed disabled:opacity-50 dark:hover:bg-white/10"
			>
				Cancel
			</button>
		</div>
	</form>
</div>
