<script lang="ts">
	import { t } from 'svelte-i18n';
	import { superForm, type SuperValidated } from 'sveltekit-superforms';
	import type { z } from 'zod';
	import type { createAppSchema } from '$lib/utils/validators.js';
	import AppIconPicker from './AppIconPicker.svelte';
	import IntegrationConfigFields from './IntegrationConfigFields.svelte';
	import AppUrlPreview from './AppUrlPreview.svelte';
	import AutocompleteInput from '$lib/components/ui/AutocompleteInput.svelte';
	import TagsInput from '$lib/components/ui/TagsInput.svelte';
	import IconGrid from '$lib/components/ui/IconGrid.svelte';
	import type { IconGridItem } from '$lib/components/ui/IconGrid.svelte';
	import Switch from '$lib/components/ui/Switch.svelte';
	import Button from '$lib/components/ui/Button.svelte';

	type AppSchema = z.infer<typeof createAppSchema>;

	interface Props {
		form: SuperValidated<AppSchema>;
		action?: string;
		mode?: 'create' | 'edit';
	}

	let { form: formData, action = '?/create', mode = 'create' }: Props = $props();

	const { form, errors, enhance, submitting } = superForm(formData, {
		resetForm: mode === 'create'
	});

	let showAdvanced = $state(false);
	let showIntegration = $state(false);
	let categorySuggestions = $state<string[]>([]);
	let tagSuggestions = $state<string[]>([]);

	// Fetch autocomplete suggestions
	$effect(() => {
		fetch('/api/apps/suggestions')
			.then((r) => r.json())
			.then((json) => {
				if (json.success) {
					categorySuggestions = json.data?.categories ?? [];
					tagSuggestions = json.data?.tags ?? [];
				}
			})
			.catch(() => {});
	});
	interface IntegrationField {
		name: string;
		type: 'string' | 'number' | 'boolean';
		required: boolean;
		label: string;
		description?: string;
	}
	let availableIntegrations = $state<
		Array<{
			id: string;
			name: string;
			icon: string;
			authConfigFields: IntegrationField[];
			extraConfigFields: IntegrationField[];
		}>
	>([]);
	let integrationConfig = $state<Record<string, unknown>>({});
	let testingConnection = $state(false);
	let testResult = $state<{ success: boolean; message: string } | null>(null);

	$effect(() => {
		fetch('/api/integrations')
			.then((r) => r.json())
			.then((json) => {
				if (json.success) availableIntegrations = json.data ?? [];
			})
			.catch(() => {});
	});

	const selectedIntegration = $derived(
		availableIntegrations.find((i) => i.id === ($form.integrationType ?? ''))
	);

	async function handleTestConnection() {
		if (!$form.integrationType || !$form.url) return;
		testingConnection = true;
		testResult = null;
		try {
			const res = await fetch('/api/integrations/test', {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({
					integrationType: $form.integrationType,
					appUrl: $form.url,
					config: integrationConfig
				})
			});
			const json = await res.json();
			testResult = json.data ?? { success: false, message: json.error ?? 'Unknown error' };
		} catch {
			testResult = { success: false, message: 'Network error' };
		} finally {
			testingConnection = false;
		}
	}

	$effect(() => {
		if ($form.integrationType && Object.keys(integrationConfig).length > 0) {
			$form.integrationConfig = JSON.stringify(integrationConfig);
		}
	});

	const healthcheckMethodItems: IconGridItem[] = [
		{ value: 'GET', icon: '🔍', label: 'GET', desc: 'Full response' },
		{ value: 'HEAD', icon: '📋', label: 'HEAD', desc: 'Headers only' }
	];
</script>

<form method="POST" {action} use:enhance class="space-y-4">
	<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
		<div>
			<label for="name" class="mb-1 block text-sm font-medium text-card-foreground">
				{$t('app.name')} <span class="text-destructive">{$t('common.required')}</span>
			</label>
			<input
				id="name"
				name="name"
				type="text"
				bind:value={$form.name}
				class="w-full rounded-xl border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/30"
				placeholder={$t('app.name_placeholder')}
			/>
			{#if $errors.name}
				<p class="mt-1 text-sm text-destructive">{$errors.name[0]}</p>
			{/if}
		</div>

		<div>
			<label for="url" class="mb-1 block text-sm font-medium text-card-foreground">
				{$t('app.url')} <span class="text-destructive">{$t('common.required')}</span>
			</label>
			<input
				id="url"
				name="url"
				type="url"
				bind:value={$form.url}
				class="w-full rounded-xl border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/30"
				placeholder={$t('app.url_placeholder')}
			/>
			{#if $errors.url}
				<p class="mt-1 text-sm text-destructive">{$errors.url[0]}</p>
			{/if}
		</div>
	</div>

	<!-- URL Preview / Test Connection -->
	<AppUrlPreview
		url={$form.url ?? ''}
		currentIcon={$form.icon ?? ''}
		currentName={$form.name ?? ''}
		onApplyFavicon={(favicon) => {
			$form.icon = favicon;
			$form.iconType = 'url';
		}}
		onApplyTitle={(title) => {
			$form.name = title;
		}}
	/>

	<div>
		<label for="description" class="mb-1 block text-sm font-medium text-card-foreground">
			{$t('app.description')}
		</label>
		<input
			id="description"
			name="description"
			type="text"
			bind:value={$form.description}
			class="w-full rounded-xl border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/30"
			placeholder={$t('app.description_placeholder')}
		/>
	</div>

	<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
		<div>
			<label for="category" class="mb-1 block text-sm font-medium text-card-foreground">
				{$t('app.category')}
			</label>
			<AutocompleteInput
				id="category"
				name="category"
				bind:value={$form.category}
				suggestions={categorySuggestions}
				placeholder={$t('app.category_placeholder')}
				class="w-full rounded-xl border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/30"
			/>
		</div>

		<div>
			<label for="tags" class="mb-1 block text-sm font-medium text-card-foreground">
				{$t('app.tags')}
			</label>
			<TagsInput
				id="tags"
				name="tags"
				bind:value={$form.tags}
				suggestions={tagSuggestions}
				placeholder={$t('app.tags_placeholder')}
				class="w-full rounded-xl border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/30"
			/>
		</div>
	</div>

	<AppIconPicker
		iconType={$form.iconType ?? 'lucide'}
		iconValue={$form.icon ?? ''}
		onchange={(type, value) => {
			$form.iconType = type as typeof $form.iconType;
			$form.icon = value;
		}}
	/>
	<input type="hidden" name="icon" value={$form.icon ?? ''} />
	<input type="hidden" name="iconType" value={$form.iconType ?? 'lucide'} />

	<button
		type="button"
		onclick={() => (showAdvanced = !showAdvanced)}
		aria-expanded={showAdvanced}
		class="group inline-flex items-center gap-1.5 text-sm text-muted-foreground transition-colors hover:text-foreground"
	>
		<svg
			class="h-3.5 w-3.5 transition-transform duration-200 {showAdvanced ? 'rotate-90' : ''}"
			viewBox="0 0 16 16"
			fill="none"
			stroke="currentColor"
			stroke-width="1.75"
			stroke-linecap="round"
			stroke-linejoin="round"
			aria-hidden="true"
		>
			<polyline points="6 4 10 8 6 12" />
		</svg>
		{showAdvanced ? $t('app.healthcheck_hide') : $t('app.healthcheck_show')} {$t('app.healthcheck_toggle')}
	</button>

	{#if showAdvanced}
		<div class="cozy-expand space-y-4 rounded-xl border border-border p-4">
			<div class="flex items-center gap-3">
				<Switch
					id="healthcheckEnabled"
					name="healthcheckEnabled"
					bind:checked={$form.healthcheckEnabled}
					ariaLabelledby="healthcheckEnabledLabel"
				/>
				<label id="healthcheckEnabledLabel" for="healthcheckEnabled" class="cursor-pointer text-sm text-card-foreground">
					{$t('app.healthcheck_enabled')}
				</label>
			</div>

			{#if $form.healthcheckEnabled}
				<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
					<div>
						<!-- svelte-ignore a11y_label_has_associated_control -->
						<label
							class="mb-1 block text-sm font-medium text-card-foreground"
						>
							{$t('app.healthcheck_method')}
						</label>
						<IconGrid
							items={healthcheckMethodItems}
							value={$form.healthcheckMethod ?? 'GET'}
							onchange={(v) => ($form.healthcheckMethod = v as 'GET' | 'HEAD')}
							name="healthcheckMethod"
							columns={2}
						/>
					</div>

					<div>
						<label
							for="healthcheckExpectedStatus"
							class="mb-1 block text-sm font-medium text-card-foreground"
						>
							{$t('app.healthcheck_expected_status')}
						</label>
						<input
							id="healthcheckExpectedStatus"
							name="healthcheckExpectedStatus"
							type="number"
							bind:value={$form.healthcheckExpectedStatus}
							class="w-full rounded-xl border border-input bg-background px-3 py-2 text-sm text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/30"
							min="100"
							max="599"
						/>
					</div>

					<div>
						<label
							for="healthcheckTimeout"
							class="mb-1 block text-sm font-medium text-card-foreground"
						>
							{$t('app.healthcheck_timeout')}
						</label>
						<input
							id="healthcheckTimeout"
							name="healthcheckTimeout"
							type="number"
							bind:value={$form.healthcheckTimeout}
							class="w-full rounded-xl border border-input bg-background px-3 py-2 text-sm text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/30"
							min="1000"
							max="30000"
							step="1000"
						/>
					</div>
				</div>

				<div>
					<label
						for="healthcheckInterval"
						class="mb-1 block text-sm font-medium text-card-foreground"
					>
						{$t('app.healthcheck_interval')}
					</label>
					<input
						id="healthcheckInterval"
						name="healthcheckInterval"
						type="number"
						bind:value={$form.healthcheckInterval}
						class="w-full rounded-xl border border-input bg-background px-3 py-2 text-sm text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/30"
						min="30"
						max="86400"
					/>
				</div>
			{/if}
		</div>
	{/if}

	<!-- Integration Section -->
	<button
		type="button"
		onclick={() => (showIntegration = !showIntegration)}
		aria-expanded={showIntegration}
		class="group inline-flex items-center gap-1.5 text-sm text-muted-foreground transition-colors hover:text-foreground"
	>
		<svg
			class="h-3.5 w-3.5 transition-transform duration-200 {showIntegration ? 'rotate-90' : ''}"
			viewBox="0 0 16 16"
			fill="none"
			stroke="currentColor"
			stroke-width="1.75"
			stroke-linecap="round"
			stroke-linejoin="round"
			aria-hidden="true"
		>
			<polyline points="6 4 10 8 6 12" />
		</svg>
		{showIntegration ? 'Hide' : 'Show'} Integration Settings
	</button>

	{#if showIntegration}
		<div class="cozy-expand space-y-4 rounded-xl border border-border p-4">
			<div class="flex items-center gap-3">
				<Switch
					id="integrationEnabled"
					name="integrationEnabled"
					bind:checked={$form.integrationEnabled}
					ariaLabelledby="integrationEnabledLabel"
				/>
				<label id="integrationEnabledLabel" for="integrationEnabled" class="cursor-pointer text-sm text-card-foreground">
					Enable Integration
				</label>
			</div>

			{#if $form.integrationEnabled}
				<div>
					<label for="integrationType" class="mb-1 block text-sm font-medium text-card-foreground">
						Integration Type
					</label>
					<select
						id="integrationType"
						name="integrationType"
						bind:value={$form.integrationType}
						class="w-full rounded-xl border border-input bg-background px-3 py-2 text-sm text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/30"
					>
						<option value="">None</option>
						{#each availableIntegrations as integration (integration.id)}
							<option value={integration.id}>{integration.name}</option>
						{/each}
					</select>
				</div>

				{#if selectedIntegration}
					<div>
						<h4 class="mb-2 text-sm font-medium text-card-foreground">Authentication</h4>
						<IntegrationConfigFields
							fields={selectedIntegration.authConfigFields}
							values={integrationConfig}
							onchange={(name, value) => {
								integrationConfig = { ...integrationConfig, [name]: value };
							}}
							idPrefix="int-auth"
						/>
					</div>

					{#if selectedIntegration.extraConfigFields.length > 0}
						<div>
							<h4 class="mb-2 text-sm font-medium text-card-foreground">Extra Configuration</h4>
							<IntegrationConfigFields
								fields={selectedIntegration.extraConfigFields}
								values={integrationConfig}
								onchange={(name, value) => {
									integrationConfig = { ...integrationConfig, [name]: value };
								}}
								idPrefix="int-extra"
							/>
						</div>
					{/if}

					<div class="flex items-center gap-3">
						<button
							type="button"
							onclick={handleTestConnection}
							disabled={testingConnection}
							class="rounded-md border border-border px-3 py-1.5 text-sm text-foreground hover:bg-accent disabled:opacity-50"
						>
							{testingConnection ? 'Testing...' : 'Test Connection'}
						</button>
						{#if testResult}
							<span class="text-sm {testResult.success ? 'text-status-online-ink' : 'text-destructive'}">
								{testResult.message}
							</span>
						{/if}
					</div>
				{/if}
			{/if}

			<input type="hidden" name="integrationConfig" value={$form.integrationConfig ?? ''} />
			<input type="hidden" name="integrationType" value={$form.integrationType ?? ''} />
		</div>
	{/if}

	<div class="flex justify-end">
		<Button type="submit" size="lg" disabled={$submitting} loading={$submitting}>
			{#if $submitting}
				{$t('app.saving')}
			{:else}
				{mode === 'edit' ? $t('app.update') : $t('app.save')}
			{/if}
		</Button>
	</div>
</form>
