<script lang="ts">
	import { api } from '$lib/api';
	import { t } from '$lib/i18n';
	import { snackSuccess, snackError } from '$lib/stores/snackbar.svelte';
	import Card from '$lib/components/Card.svelte';
	import IconPicker from '$lib/components/IconPicker.svelte';
	import IconGridSelect from '$lib/components/IconGridSelect.svelte';
	import { goto } from '$app/navigation';
	import { providerTypeItems, webhookAuthModeItems } from '$lib/grid-items';

	const gridItemSources: Record<string, () => any[]> = { webhookAuthModeItems };
	import { getDescriptor, buildProviderFormDefaults } from '$lib/providers';
	import Button from '$lib/components/Button.svelte';
	import ErrorBanner from '$lib/components/ErrorBanner.svelte';

	let form = $state(buildProviderFormDefaults());
	let error = $state('');
	let testing = $state(false);
	let saving = $state(false);
	let descriptor = $derived(getDescriptor(form.type));

	async function testAndSave() {
		const desc = descriptor;
		if (!desc) { error = t('providers.selectType'); return; }
		const { config, error: buildError } = desc.buildConfig(form, false);
		if (buildError) { error = t(buildError); snackError(error); return; }

		testing = true; error = '';
		let createdId: number | null = null;
		try {
			const provider = await api('/providers', {
				method: 'POST',
				body: JSON.stringify({ type: form.type, name: form.name || desc.defaultName, icon: form.icon, config }),
			});
			createdId = provider.id;
			const result = await api(`/providers/${provider.id}/test`, { method: 'POST' });
			if (!result.ok) {
				await api(`/providers/${provider.id}`, { method: 'DELETE' }).catch(() => {});
				createdId = null;
				error = result.message || t('providers.testFailed');
				snackError(error);
			} else {
				snackSuccess(t('snack.providerSaved'));
				goto('/providers');
			}
		} catch (e: any) {
			if (createdId) await api(`/providers/${createdId}`, { method: 'DELETE' }).catch(() => {});
			error = e.message || t('providers.testFailed'); snackError(error);
		}
		finally { testing = false; }
	}

	async function saveWithoutTest() {
		const desc = descriptor;
		if (!desc) { error = t('providers.selectType'); return; }
		const { config, error: buildError } = desc.buildConfig(form, false);
		if (buildError) { error = t(buildError); snackError(error); return; }

		saving = true; error = '';
		try {
			await api('/providers', {
				method: 'POST',
				body: JSON.stringify({ type: form.type, name: form.name || desc.defaultName, icon: form.icon, config }),
			});
			snackSuccess(t('snack.providerSaved'));
			goto('/providers');
		} catch (e: any) { error = e.message || t('common.saveFailed'); snackError(error); }
		finally { saving = false; }
	}
</script>

<div class="mb-4">
	<a href="/providers" class="text-sm text-[var(--color-muted-foreground)] hover:underline">← {t('providers.title')}</a>
</div>

<h2 class="text-xl font-semibold mb-8">{t('providers.addProvider')}</h2>

<Card>
	<div class="space-y-4">
		<div>
			<div class="block text-sm font-medium mb-1">{t('providers.type')}</div>
			<IconGridSelect items={providerTypeItems()} bind:value={form.type} columns={2} />
		</div>
		<div>
			<label for="prv-name" class="block text-sm font-medium mb-1">{t('providers.name')}</label>
			<div class="flex gap-2">
				<IconPicker value={form.icon} onselect={(v: string) => form.icon = v} />
				<input id="prv-name" bind:value={form.name} placeholder={descriptor?.defaultName || ''} class="flex-1 px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
			</div>
		</div>

		{#if descriptor?.hasUrl}
			<div>
				<label for="prv-url" class="block text-sm font-medium mb-1">{t('providers.url')}</label>
				<input id="prv-url" type="url" bind:value={form.url} required placeholder={descriptor.urlPlaceholder || t('providers.urlPlaceholder')} class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
			</div>
		{/if}

		{#each descriptor?.configFields ?? [] as field (field.key)}
			<div>
				<label for="prv-{field.key}" class="block text-sm font-medium mb-1">
					{t(field.label)}
					{#if field.optional}<span class="text-xs text-[var(--color-muted-foreground)]">({t('providers.optional')})</span>{/if}
				</label>
				{#if field.type === 'grid-select' && field.gridItems}
					<IconGridSelect items={gridItemSources[field.gridItems]()} bind:value={form[field.key]} columns={field.gridColumns ?? 2} compact />
				{:else if field.type === 'number'}
					<input id="prv-{field.key}" type="number" bind:value={form[field.key]} min={field.min} max={field.max}
						class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
				{:else}
					<input id="prv-{field.key}" type={field.type} bind:value={form[field.key]}
						required={field.required === true || field.required === 'create-only'}
						placeholder={field.placeholder || ''} autocomplete="off"
						class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
				{/if}
				{#if field.hint}
					<p class="text-xs text-[var(--color-muted-foreground)] mt-1">{t(field.hint)}</p>
				{/if}
			</div>
		{/each}

		<ErrorBanner message={error} />

		<div class="flex gap-3 pt-2">
			<Button onclick={testAndSave} disabled={testing || saving}>
				{testing ? t('providers.connecting') : t('providers.testAndSave')}
			</Button>
			<Button variant="secondary" onclick={saveWithoutTest} disabled={testing || saving}>
				{saving ? t('common.loading') : t('providers.saveWithoutTest')}
			</Button>
			<Button variant="secondary" href="/providers">
				{t('common.cancel')}
			</Button>
		</div>
	</div>
</Card>
