<script lang="ts">
	import { onMount } from 'svelte';
	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 MdiIcon from '$lib/components/MdiIcon.svelte';
	import Hint from '$lib/components/Hint.svelte';
	import ErrorBanner from '$lib/components/ErrorBanner.svelte';
	import Button from '$lib/components/Button.svelte';
	import ConfirmModal from '$lib/components/ConfirmModal.svelte';
	import LocaleSelector from '$lib/components/LocaleSelector.svelte';
	import TimezoneSelector from '$lib/components/TimezoneSelector.svelte';
	import IconGridSelect from '$lib/components/IconGridSelect.svelte';
	import { logLevelItems, logFormatItems } from '$lib/grid-items';
	import { snackSuccess, snackError } from '$lib/stores/snackbar.svelte';
	import { externalUrlCache } from '$lib/stores/caches.svelte';

	interface CacheBucketStats {
		count: number;
		total_size_bytes: number;
		oldest: string | null;
		newest: string | null;
	}
	interface CacheStats {
		url: CacheBucketStats;
		asset: CacheBucketStats;
	}

	let loaded = $state(false);
	let saving = $state(false);
	let clearingCache = $state(false);
	let confirmClearCache = $state(false);
	let error = $state('');
	let settings = $state({
		external_url: '',
		telegram_webhook_secret: '',
		telegram_cache_ttl_hours: '720',
		telegram_asset_cache_max_entries: '5000',
		supported_locales: 'en,ru',
		timezone: 'UTC',
		log_level: 'INFO',
		log_format: 'text',
		log_levels: '',
	});
	let cacheStats = $state<CacheStats | null>(null);

	async function loadCacheStats() {
		try {
			cacheStats = await api<CacheStats>('/settings/telegram-cache/stats');
		} catch { cacheStats = null; }
	}

	onMount(async () => {
		try {
			settings = await api('/settings');
			await loadCacheStats();
		} catch (err: any) { error = err.message; snackError(err.message); }
		finally { loaded = true; }
	});

	function formatBytes(bytes: number): string {
		if (!bytes) return '0 B';
		const units = ['B', 'KB', 'MB', 'GB'];
		let i = 0;
		let v = bytes;
		while (v >= 1024 && i < units.length - 1) { v /= 1024; i++; }
		return `${v.toFixed(v < 10 && i > 0 ? 1 : 0)} ${units[i]}`;
	}

	function formatTs(iso: string | null): string {
		if (!iso) return '—';
		const d = new Date(iso.endsWith('Z') || /[+-]\d{2}:?\d{2}$/.test(iso) ? iso : iso + 'Z');
		return isNaN(d.getTime()) ? iso : d.toLocaleString();
	}

	async function save() {
		saving = true; error = '';
		try {
			settings = await api('/settings', { method: 'PUT', body: JSON.stringify(settings) });
			externalUrlCache.invalidate();
			snackSuccess(t('settings.saved'));
		} catch (err: any) { error = err.message; snackError(err.message); }
		saving = false;
	}

	async function clearTelegramCache() {
		confirmClearCache = false;
		clearingCache = true;
		try {
			await api('/settings/telegram-cache/clear', { method: 'POST' });
			snackSuccess(t('settings.clearCacheDone'));
			await loadCacheStats();
		} catch (err: any) { snackError(err.message); }
		clearingCache = false;
	}
</script>

<PageHeader
	title={t('settings.title')}
	emphasis={t('settings.titleEmphasis')}
	description={t('settings.description')}
	crumb={t('crumbs.systemConfiguration')}
/>

{#if !loaded}
	<Loading />
{:else}
	<ErrorBanner message={error} />
	<div class="space-y-6">
		<!-- General section -->
		<Card>
			<h3 class="text-sm font-semibold mb-4 flex items-center gap-2">
				<MdiIcon name="mdiCog" size={18} />
				{t('settings.general')}
			</h3>
			<div class="space-y-3">
				<div>
					<label class="block text-xs font-medium mb-1">{t('settings.externalUrl')}<Hint text={t('settings.externalUrlHint')} /></label>
					<input bind:value={settings.external_url} placeholder="https://notify.example.com"
						class="w-full max-w-md px-3 py-1.5 text-sm border border-[var(--color-border)] rounded-md bg-[var(--color-background)] font-mono" />
				</div>
				<div>
					<label class="block text-xs font-medium mb-2">{t('settings.timezone')}<Hint text={t('settings.timezoneHint')} /></label>
					<TimezoneSelector bind:value={settings.timezone} />
				</div>
			</div>
		</Card>

		<!-- Telegram section -->
		<Card>
			<h3 class="text-sm font-semibold mb-4 flex items-center gap-2">
				<MdiIcon name="mdiSend" size={18} />
				{t('settings.telegram')}
			</h3>
			<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
				<div>
					<label class="block text-xs font-medium mb-1">{t('settings.webhookSecret')}<Hint text={t('settings.webhookSecretHint')} /></label>
					<form onsubmit={(e) => e.preventDefault()} autocomplete="off">
						<input bind:value={settings.telegram_webhook_secret} type="password" autocomplete="off" placeholder={t('providers.optional')}
							class="w-full px-3 py-1.5 text-sm border border-[var(--color-border)] rounded-md bg-[var(--color-background)] font-mono" />
					</form>
				</div>
				<div>
					<label class="block text-xs font-medium mb-1">{t('settings.cacheTtl')}<Hint text={t('settings.cacheTtlHint')} /></label>
					<input bind:value={settings.telegram_cache_ttl_hours} type="number" min="0" max="8760"
						class="w-full px-3 py-1.5 text-sm border border-[var(--color-border)] rounded-md bg-[var(--color-background)]" />
				</div>
				<div>
					<label class="block text-xs font-medium mb-1">{t('settings.cacheMaxEntries')}<Hint text={t('settings.cacheMaxEntriesHint')} /></label>
					<input bind:value={settings.telegram_asset_cache_max_entries} type="number" min="100" max="100000"
						class="w-full px-3 py-1.5 text-sm border border-[var(--color-border)] rounded-md bg-[var(--color-background)]" />
				</div>
			</div>
			<div class="mt-4 pt-4 border-t border-[var(--color-border)]">
				<div class="text-xs font-medium mb-2 flex items-center" style="color: var(--color-muted-foreground);">
					{t('settings.cacheStats')}<Hint text={t('settings.cacheStatsHint')} />
				</div>
				<div class="grid grid-cols-1 sm:grid-cols-2 gap-2 mb-3">
					{#each [
						{ label: t('settings.cacheStatsUrl'), data: cacheStats?.url },
						{ label: t('settings.cacheStatsAsset'), data: cacheStats?.asset },
					] as bucket}
						<div class="px-3 py-2 rounded-md border border-[var(--color-border)] bg-[var(--color-background)] text-xs">
							<div class="flex items-baseline justify-between gap-2">
								<span class="font-medium">{bucket.label}</span>
								{#if bucket.data && bucket.data.count > 0}
									<span>
										<span class="font-mono">{bucket.data.count}</span>
										<span style="color: var(--color-muted-foreground);"> {t('settings.cacheStatsEntries')}</span>
										{#if bucket.data.total_size_bytes > 0}
											<span style="color: var(--color-muted-foreground);"> · </span>
											<span class="font-mono">{formatBytes(bucket.data.total_size_bytes)}</span>
										{/if}
									</span>
								{:else}
									<span style="color: var(--color-muted-foreground);">{t('settings.cacheStatsEmpty')}</span>
								{/if}
							</div>
							{#if bucket.data && bucket.data.count > 0 && (bucket.data.oldest || bucket.data.newest)}
								<div class="mt-1 flex flex-wrap gap-x-3 gap-y-0.5" style="color: var(--color-muted-foreground);">
									{#if bucket.data.oldest}
										<span>{t('settings.cacheStatsOldest')}: <span class="font-mono">{formatTs(bucket.data.oldest)}</span></span>
									{/if}
									{#if bucket.data.newest}
										<span>{t('settings.cacheStatsNewest')}: <span class="font-mono">{formatTs(bucket.data.newest)}</span></span>
									{/if}
								</div>
							{/if}
						</div>
					{/each}
				</div>
				<div class="flex items-center gap-3 flex-wrap">
					<button type="button" onclick={() => confirmClearCache = true} disabled={clearingCache}
						class="inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-md border border-[var(--color-border)] bg-[var(--color-background)] hover:bg-[var(--color-muted)] disabled:opacity-50">
						<MdiIcon name="mdiDeleteSweep" size={16} />
						{clearingCache ? t('common.loading') : t('settings.clearCache')}
					</button>
					<span class="text-xs" style="color: var(--color-muted-foreground);">{t('settings.clearCacheHint')}</span>
				</div>
			</div>
		</Card>

		<!-- Locales section -->
		<Card>
			<h3 class="text-sm font-semibold mb-4 flex items-center gap-2">
				<MdiIcon name="mdiTranslate" size={18} />
				{t('settings.locales')}
			</h3>
			<div class="space-y-3">
				<div>
					<label class="block text-xs font-medium mb-2">{t('settings.supportedLocales')}<Hint text={t('settings.supportedLocalesHint')} /></label>
					<LocaleSelector bind:value={settings.supported_locales} />
				</div>
			</div>
		</Card>

		<!-- Logging section -->
		<Card>
			<h3 class="text-sm font-semibold mb-4 flex items-center gap-2">
				<MdiIcon name="mdiTextBoxOutline" size={18} />
				{t('settings.logging')}
			</h3>
			<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
				<div>
					<label class="block text-xs font-medium mb-1">{t('settings.logLevel')}<Hint text={t('settings.logLevelHint')} /></label>
					<IconGridSelect items={logLevelItems()} bind:value={settings.log_level} columns={2} />
				</div>
				<div>
					<label class="block text-xs font-medium mb-1">{t('settings.logFormat')}<Hint text={t('settings.logFormatHint')} /></label>
					<IconGridSelect items={logFormatItems()} bind:value={settings.log_format} columns={2} />
				</div>
				<div class="sm:col-span-2">
					<label class="block text-xs font-medium mb-1">{t('settings.logLevels')}<Hint text={t('settings.logLevelsHint')} /></label>
					<input bind:value={settings.log_levels}
						placeholder="sqlalchemy.engine=WARNING,notify_bridge_core.notifications.telegram.client=DEBUG"
						class="w-full px-3 py-1.5 text-sm border border-[var(--color-border)] rounded-md bg-[var(--color-background)] font-mono" />
				</div>
			</div>
		</Card>

		<Button onclick={save} disabled={saving}>
			{saving ? t('common.loading') : t('common.save')}
		</Button>
	</div>

	<ConfirmModal open={confirmClearCache}
		title={t('settings.clearCacheConfirmTitle')}
		message={t('settings.clearCacheConfirm')}
		confirmLabel={t('settings.clearCacheConfirmBtn')}
		confirmIcon="mdiDeleteSweep"
		onconfirm={clearTelegramCache}
		oncancel={() => confirmClearCache = false} />
{/if}
