<script lang="ts">
	import { onMount } from 'svelte';
	import { slide } from 'svelte/transition';
	import { api } from '$lib/api';
	import { t } from '$lib/i18n';
	import PageHeader from '$lib/components/PageHeader.svelte';
	import Card from '$lib/components/Card.svelte';
	import Loading from '$lib/components/Loading.svelte';
	import IconPicker from '$lib/components/IconPicker.svelte';
	import MdiIcon from '$lib/components/MdiIcon.svelte';
	import ConfirmModal from '$lib/components/ConfirmModal.svelte';
	import Hint from '$lib/components/Hint.svelte';
	import IconButton from '$lib/components/IconButton.svelte';
	import Modal from '$lib/components/Modal.svelte';
	import JinjaEditor from '$lib/components/JinjaEditor.svelte';

	let configs = $state<any[]>([]);
	let loaded = $state(false);
	let varsRef = $state<Record<string, any>>({});
	let showVarsFor = $state<string | null>(null);
	let showForm = $state(false);
	let editing = $state<number | null>(null);
	let error = $state('');
	let confirmDelete = $state<any>(null);
	let slotPreview = $state<Record<string, string>>({});
	let slotErrors = $state<Record<string, string>>({});
	let slotErrorLines = $state<Record<string, number | null>>({});
	let slotErrorTypes = $state<Record<string, string>>({});
	let validateTimers: Record<string, ReturnType<typeof setTimeout>> = {};

	function validateSlot(slotKey: string, template: string) {
		// Clear previous timer
		if (validateTimers[slotKey]) clearTimeout(validateTimers[slotKey]);
		if (!template) {
			slotErrors = { ...slotErrors, [slotKey]: '' };
			slotErrorLines = { ...slotErrorLines, [slotKey]: null };
			slotErrorTypes = { ...slotErrorTypes, [slotKey]: '' };
			const { [slotKey]: _, ...rest } = slotPreview;
			slotPreview = rest;
			return;
		}

		// Debounce 800ms
		validateTimers[slotKey] = setTimeout(async () => {
			try {
				const res = await api('/template-configs/preview-raw', { method: 'POST', body: JSON.stringify({ template }) });
				slotErrors = { ...slotErrors, [slotKey]: res.error || '' };
				slotErrorLines = { ...slotErrorLines, [slotKey]: res.error_line || null };
				slotErrorTypes = { ...slotErrorTypes, [slotKey]: res.error_type || '' };
				// Live preview: show rendered result when no error
				if (res.rendered) {
					slotPreview = { ...slotPreview, [slotKey]: res.rendered };
				} else {
					const { [slotKey]: _, ...rest } = slotPreview;
					slotPreview = rest;
				}
			} catch {
				// Network error, don't show as template error
				slotErrors = { ...slotErrors, [slotKey]: '' };
				slotErrorLines = { ...slotErrorLines, [slotKey]: null };
				slotErrorTypes = { ...slotErrorTypes, [slotKey]: '' };
			}
		}, 800);
	}

	const defaultForm = () => ({
		name: '', description: '', icon: '',
		message_assets_added: '',
		message_assets_removed: '',
		message_album_renamed: '',
		message_album_deleted: '',
		periodic_summary_message: '',
		scheduled_assets_message: '',
		memory_mode_message: '',
		date_format: '%d.%m.%Y, %H:%M UTC',
		video_warning: '\n\n⚠️ Note: Videos may not be sent due to Telegram\'s 50 MB file size limit.',
	});
	let form = $state(defaultForm());

	const templateSlots = [
		{ group: 'eventMessages', slots: [
			{ key: 'message_assets_added', label: 'assetsAdded', rows: 10 },
			{ key: 'message_assets_removed', label: 'assetsRemoved', rows: 3 },
			{ key: 'message_album_renamed', label: 'albumRenamed', rows: 2 },
			{ key: 'message_album_deleted', label: 'albumDeleted', rows: 2 },
		]},
		{ group: 'scheduledMessages', slots: [
			{ key: 'periodic_summary_message', label: 'periodicSummary', rows: 6 },
			{ key: 'scheduled_assets_message', label: 'scheduledAssets', rows: 6 },
			{ key: 'memory_mode_message', label: 'memoryMode', rows: 6 },
		]},
		{ group: 'telegramSettings', slots: [
			{ key: 'date_format', label: 'dateFormat', rows: 1 },
			{ key: 'video_warning', label: 'videoWarning', rows: 2 },
		]},
	];

	onMount(load);
	async function load() {
		try {
			[configs, varsRef] = await Promise.all([
				api('/template-configs'),
				api('/template-configs/variables'),
			]);
		} catch (err: any) { error = err.message || t('common.loadError'); }
		finally { loaded = true; }
	}

	function openNew() { form = defaultForm(); editing = null; showForm = true; }
	function edit(c: any) { form = { ...defaultForm(), ...c }; editing = c.id; showForm = true; }

	async function save(e: SubmitEvent) {
		e.preventDefault(); error = '';
		try {
			if (editing) await api(`/template-configs/${editing}`, { method: 'PUT', body: JSON.stringify(form) });
			else await api('/template-configs', { method: 'POST', body: JSON.stringify(form) });
			showForm = false; editing = null; await load();
		} catch (err: any) { error = err.message; }
	}

	async function previewSlot(slotKey: string) {
		// Toggle: if already showing, hide it
		if (slotPreview[slotKey]) { delete slotPreview[slotKey]; slotPreview = { ...slotPreview }; return; }
		const template = (form as any)[slotKey] || '';
		if (!template) { slotPreview = { ...slotPreview, [slotKey]: '(empty)' }; return; }
		try {
			const res = await api('/template-configs/preview-raw', { method: 'POST', body: JSON.stringify({ template }) });
			slotPreview = { ...slotPreview, [slotKey]: res.error ? `Error: ${res.error}` : res.rendered };
		} catch (err: any) { slotPreview = { ...slotPreview, [slotKey]: `Error: ${err.message}` }; }
	}

	async function preview(configId: number, slotKey: string) {
		const config = configs.find(c => c.id === configId);
		if (!config) return;
		const template = config[slotKey] || '';
		if (!template) return;
		try {
			const res = await api('/template-configs/preview-raw', { method: 'POST', body: JSON.stringify({ template }) });
			slotPreview[slotKey + '_' + configId] = res.error ? `Error: ${res.error}` : res.rendered;
		} catch (err: any) { slotPreview[slotKey + '_' + configId] = `Error: ${err.message}`; }
	}

	function remove(id: number) {
		confirmDelete = {
			id,
			onconfirm: async () => {
				try { await api(`/template-configs/${id}`, { method: 'DELETE' }); await load(); }
				catch (err: any) { error = err.message; }
				finally { confirmDelete = null; }
			}
		};
	}
</script>

<PageHeader title={t('templateConfig.title')} description={t('templateConfig.description')}>
	<button onclick={() => { showForm ? (showForm = false, editing = null) : openNew(); }}
		class="px-3 py-1.5 bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded-md text-sm font-medium hover:opacity-90">
		{showForm ? t('common.cancel') : t('templateConfig.newConfig')}
	</button>
</PageHeader>

{#if !loaded}<Loading />{:else}

{#if showForm}
<div in:slide>
<Card class="mb-6">
	{#if error}<div class="bg-[var(--color-error-bg)] text-[var(--color-error-fg)] text-sm rounded-md p-3 mb-4">{error}</div>{/if}
	<form onsubmit={save} class="space-y-5">
		<div>
			<label for="tpc-name" class="block text-sm font-medium mb-1">{t('templateConfig.name')}</label>
			<div class="flex gap-2">
				<IconPicker value={form.icon} onselect={(v) => form.icon = v} />
				<input id="tpc-name" bind:value={form.name} required placeholder={t('templateConfig.namePlaceholder')}
					class="flex-1 px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
			</div>
		</div>
		<div>
			<label for="tpc-desc" class="block text-sm font-medium mb-1">{t('common.description')}</label>
			<input id="tpc-desc" bind:value={form.description} placeholder={t('templateConfig.descriptionPlaceholder')}
				class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
		</div>

		{#each templateSlots as group}
			<fieldset class="border border-[var(--color-border)] rounded-md p-3">
				<legend class="text-sm font-medium px-1">{t(`templateConfig.${group.group}`)}{#if group.group === 'eventMessages'}<Hint text={t('hints.eventMessages')} />{:else if group.group === 'assetFormatting'}<Hint text={t('hints.assetFormatting')} />{:else if group.group === 'dateLocation'}<Hint text={t('hints.dateLocation')} />{:else if group.group === 'scheduledMessages'}<Hint text={t('hints.scheduledMessages')} />{/if}</legend>
				<div class="space-y-3 mt-2">
					{#each group.slots as slot}
						<div>
							<div class="flex items-center justify-between mb-1">
								<label class="text-xs text-[var(--color-muted-foreground)]">{t(`templateConfig.${slot.label}`)}</label>
								<div class="flex items-center gap-2">
									<button type="button" onclick={() => previewSlot(slot.key)}
										class="text-xs text-[var(--color-muted-foreground)] hover:underline">{t('templateConfig.preview')}</button>
									{#if varsRef[slot.key]}
										<button type="button" onclick={() => showVarsFor = slot.key}
											class="text-xs text-[var(--color-muted-foreground)] hover:underline">{t('templateConfig.variables')}</button>
									{/if}
								</div>
							</div>
							{#if (slot.rows || 2) > 2}
								<JinjaEditor value={(form as any)[slot.key] || ''} onchange={(v) => { (form as any)[slot.key] = v; validateSlot(slot.key, v); }} rows={slot.rows || 6} errorLine={slotErrorLines[slot.key] || null} />
								{#if slotErrors[slot.key]}
									{#if slotErrorTypes[slot.key] === 'undefined'}
										<p class="mt-1 text-xs" style="color: #d97706;">⚠ {t('common.undefinedVar')}: {slotErrors[slot.key]}</p>
									{:else}
										<p class="mt-1 text-xs" style="color: var(--color-error-fg);">✕ {t('common.syntaxError')}: {slotErrors[slot.key]}{slotErrorLines[slot.key] ? ` (${t('common.line')} ${slotErrorLines[slot.key]})` : ''}</p>
									{/if}
								{/if}
								{#if slotPreview[slot.key]}
									<div class="mt-1 p-2 bg-[var(--color-muted)] rounded text-sm">
										<pre class="whitespace-pre-wrap">{slotPreview[slot.key]}</pre>
									</div>
								{/if}
							{:else}
								<input bind:value={(form as any)[slot.key]}
									class="w-full px-2 py-1 border border-[var(--color-border)] rounded text-sm bg-[var(--color-background)] font-mono" />
							{/if}
						</div>
					{/each}
				</div>
			</fieldset>
		{/each}

		<button type="submit" class="px-4 py-2 bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded-md text-sm font-medium hover:opacity-90">
			{editing ? t('common.save') : t('common.create')}
		</button>
	</form>
</Card>
</div>
{/if}

{#if configs.length === 0 && !showForm}
	<Card><p class="text-sm text-[var(--color-muted-foreground)]">{t('templateConfig.noConfigs')}</p></Card>
{:else}
	<div class="space-y-3">
		{#each configs as config}
			<Card hover>
				<div class="flex items-start justify-between">
					<div class="flex-1">
						<div class="flex items-center gap-2">
							{#if config.icon}<MdiIcon name={config.icon} />{/if}
							<p class="font-medium">{config.name}</p>
						</div>
						{#if config.description}
							<p class="text-sm text-[var(--color-muted-foreground)] mt-1">{config.description}</p>
						{/if}
					</div>
					<div class="flex items-center gap-1 ml-4">
						<IconButton icon="mdiPencil" title={t('common.edit')} onclick={() => edit(config)} />
						<IconButton icon="mdiDelete" title={t('common.delete')} onclick={() => remove(config.id)} variant="danger" />
					</div>
				</div>
			</Card>
		{/each}
	</div>
{/if}

{/if}

<ConfirmModal open={confirmDelete !== null} message={t('templateConfig.confirmDelete')}
	onconfirm={() => confirmDelete?.onconfirm()} oncancel={() => confirmDelete = null} />

<!-- Variables reference modal -->
<Modal open={showVarsFor !== null} title="{t('templateConfig.variables')}: {showVarsFor ? t(`templateConfig.${templateSlots.flatMap(g => g.slots).find(s => s.key === showVarsFor)?.label || showVarsFor}`) : ''}" onclose={() => showVarsFor = null}>
	{#if showVarsFor && varsRef[showVarsFor]}
		<p class="text-sm text-[var(--color-muted-foreground)] mb-3">{t(`templateVars.${showVarsFor}.description`, varsRef[showVarsFor].description)}</p>
		<div class="space-y-1">
			<p class="text-xs font-medium mb-1">{t('templateConfig.variables')}:</p>
			{#each Object.entries(varsRef[showVarsFor].variables || {}) as [name, desc]}
				<div class="flex items-start gap-2 text-sm">
					<code class="text-xs bg-[var(--color-muted)] px-1 py-0.5 rounded font-mono whitespace-nowrap">{'{{ ' + name + ' }}'}</code>
					<span class="text-xs text-[var(--color-muted-foreground)]">{t(`templateVars.${name}`, desc as string)}</span>
				</div>
			{/each}
		</div>
		{#if varsRef[showVarsFor].asset_fields && typeof varsRef[showVarsFor].asset_fields === 'object'}
			<div class="mt-3 pt-3 border-t border-[var(--color-border)]">
				<p class="text-xs font-medium mb-1">{t('templateConfig.assetFields')}:</p>
				{#each Object.entries(varsRef[showVarsFor].asset_fields) as [name, desc]}
					<div class="flex items-start gap-2 text-sm">
						<code class="text-xs bg-[var(--color-muted)] px-1 py-0.5 rounded font-mono whitespace-nowrap">{'{{ asset.' + name + ' }}'}</code>
						<span class="text-xs text-[var(--color-muted-foreground)]">{t(`templateVars.asset_${name}`, desc as string)}</span>
					</div>
				{/each}
			</div>
		{/if}
		{#if varsRef[showVarsFor].album_fields && typeof varsRef[showVarsFor].album_fields === 'object'}
			<div class="mt-3 pt-3 border-t border-[var(--color-border)]">
				<p class="text-xs font-medium mb-1">{t('templateConfig.albumFields')}:</p>
				{#each Object.entries(varsRef[showVarsFor].album_fields) as [name, desc]}
					<div class="flex items-start gap-2 text-sm">
						<code class="text-xs bg-[var(--color-muted)] px-1 py-0.5 rounded font-mono whitespace-nowrap">{'{{ album.' + name + ' }}'}</code>
						<span class="text-xs text-[var(--color-muted-foreground)]">{t(`templateVars.album_${name}`, desc as string)}</span>
					</div>
				{/each}
			</div>
		{/if}
	{/if}
</Modal>
