<!--
  Settings › Maintenance

  Housekeeping that's adjacent to destructive operations: stale-container
  thresholds and Docker-image pruning. Isolated so the prune button is
  never within casual miss-click distance of general form fields.
-->
<script lang="ts">
	import { onMount } from 'svelte';
	import { get } from 'svelte/store';
	import { updateSettings, pruneImages, pruneBuildCache } from '$lib/api';
	import type { Settings } from '$lib/types';
	import { settingsCache } from '$lib/stores/caches';
	import FormField from '$lib/components/FormField.svelte';
	import ConfirmDialog from '$lib/components/ConfirmDialog.svelte';
	import Skeleton from '$lib/components/Skeleton.svelte';
	import { toasts } from '$lib/stores/toast';
	import { t } from '$lib/i18n';
	import { IconLoader, IconAlert } from '$lib/components/icons';

	let loading = $state(true);
	let saving = $state(false);
	let pruning = $state(false);
	let showPruneConfirm = $state(false);
	let pruningCache = $state(false);
	let showPruneCacheConfirm = $state(false);

	let staleThresholdDays = $state('7');
	let imagePruneThresholdMb = $state('1024');
	let statsIntervalSeconds = $state('15');
	let statsRetentionHours = $state('2');

	// Seed form fields once from the shared settings cache (warm → no skeleton
	// on revisit); never re-applied during background refresh, so unsaved edits
	// are safe. See caches.ts / settings landing page for the pattern.
	function seed(s: Settings) {
		staleThresholdDays = String(s.stale_threshold_days ?? 7);
		imagePruneThresholdMb = String(s.image_prune_threshold_mb ?? 1024);
		statsIntervalSeconds = String(s.stats_interval_seconds ?? 15);
		statsRetentionHours = String(s.stats_retention_hours ?? 2);
	}

	async function load() {
		const cached = get(settingsCache).value;
		if (cached) {
			seed(cached);
			loading = false;
		}
		await settingsCache.refresh();
		const fresh = get(settingsCache).value;
		if (fresh && loading) seed(fresh);
		loading = false;
		const { error } = get(settingsCache);
		if (error && !cached) toasts.error(error || $t('settingsGeneral.loadFailed'));
	}

	async function handleSave() {
		saving = true;
		try {
			const intervalParsed = parseInt(statsIntervalSeconds, 10);
			const retentionParsed = parseInt(statsRetentionHours, 10);
			// Interval 0 disables collection; otherwise clamp to [5, 300].
			const interval = isNaN(intervalParsed)
				? 15
				: intervalParsed === 0
					? 0
					: Math.max(5, Math.min(300, intervalParsed));
			const retention = isNaN(retentionParsed) ? 2 : Math.max(0, Math.min(24, retentionParsed));
			await updateSettings({
				stale_threshold_days: Math.max(1, parseInt(staleThresholdDays, 10) || 7),
				image_prune_threshold_mb: Math.max(0, parseInt(imagePruneThresholdMb, 10) || 0),
				stats_interval_seconds: interval,
				stats_retention_hours: retention
			});
			// PUT returns {status:"updated"}, not Settings — refetch the cache.
			await settingsCache.refresh();
			toasts.success($t('settingsGeneral.saved'));
		} catch (err) {
			toasts.error(err instanceof Error ? err.message : $t('settingsGeneral.saveFailed'));
		} finally {
			saving = false;
		}
	}

	async function handlePruneImages() {
		pruning = true;
		try {
			const result = await pruneImages();
			toasts.success($t('settings.pruneResult', { count: String(result.images_removed), mb: String(result.space_reclaimed_mb) }));
		} catch (err) {
			toasts.error(err instanceof Error ? err.message : $t('settings.pruneFailed'));
		} finally {
			pruning = false;
		}
	}

	async function handlePruneBuildCache() {
		pruningCache = true;
		try {
			const result = await pruneBuildCache();
			toasts.success($t('settings.pruneCacheResult', { count: String(result.caches_deleted), mb: String(result.space_reclaimed_mb) }));
		} catch (err) {
			toasts.error(err instanceof Error ? err.message : $t('settings.pruneCacheFailed'));
		} finally {
			pruningCache = false;
		}
	}

	onMount(load);
</script>

<svelte:head>
	<title>{$t('settingsMaintenance.title')} - {$t('app.name')}</title>
</svelte:head>

<div class="space-y-6">
	{#if loading}
		<div class="space-y-4">
			<Skeleton height="2rem" width="12rem" />
			<Skeleton height="6rem" />
			<Skeleton height="8rem" />
		</div>
	{:else}
		<!-- Thresholds card -->
		<div class="rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-6 shadow-[var(--shadow-sm)]">
			<h2 class="mb-1 text-lg font-semibold text-[var(--text-primary)]">{$t('settingsMaintenance.thresholds')}</h2>
			<p class="mb-4 text-sm text-[var(--text-secondary)]">{$t('settingsMaintenance.thresholdsDesc')}</p>

			<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
				<FormField
					label={$t('settings.staleThreshold')}
					name="staleThresholdDays"
					type="number"
					bind:value={staleThresholdDays}
					placeholder="7"
					helpText={$t('settings.staleThresholdHelp')}
				/>
				<FormField
					label={$t('settings.pruneThreshold')}
					name="imagePruneThresholdMb"
					type="number"
					bind:value={imagePruneThresholdMb}
					placeholder="1024"
					helpText={$t('settings.pruneThresholdHelp')}
				/>
				<FormField
					label={$t('statsSettings.intervalLabel')}
					name="statsIntervalSeconds"
					type="number"
					bind:value={statsIntervalSeconds}
					placeholder="15"
					helpText={$t('statsSettings.intervalHelp')}
				/>
				<FormField
					label={$t('statsSettings.retentionLabel')}
					name="statsRetentionHours"
					type="number"
					bind:value={statsRetentionHours}
					placeholder="2"
					helpText={$t('statsSettings.retentionHelp')}
				/>
			</div>

			<div class="mt-6">
				<button onclick={handleSave} disabled={saving} class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-brand-600)] px-4 py-2.5 text-sm font-medium text-white shadow-sm transition-all duration-150 hover:bg-[var(--color-brand-700)] disabled:opacity-50 active:animate-press">
					{#if saving}<IconLoader size={16} />{/if}
					{saving ? $t('settingsGeneral.saving') : $t('settingsGeneral.saveSettings')}
				</button>
			</div>
		</div>

		<!-- Danger zone: prune images -->
		<div class="rounded-xl border border-[var(--color-danger)]/40 bg-[var(--color-danger-light)]/30 p-6">
			<div class="flex items-start gap-3">
				<div class="shrink-0 rounded-lg bg-[var(--color-danger-light)] p-2 text-[var(--color-danger)]">
					<IconAlert size={18} />
				</div>
				<div class="min-w-0 flex-1">
					<h2 class="text-lg font-semibold text-[var(--color-danger-dark)]">{$t('settingsMaintenance.dangerZone')}</h2>
					<p class="mt-1 text-sm text-[var(--text-secondary)]">{$t('settings.dockerCleanupHelp')}</p>

					<div class="mt-4">
						<button
							type="button"
							onclick={() => { showPruneConfirm = true; }}
							disabled={pruning}
							class="inline-flex items-center gap-2 rounded-lg border border-[var(--color-danger)] bg-[var(--surface-card)] px-4 py-2 text-sm font-medium text-[var(--color-danger)] hover:bg-[var(--color-danger)] hover:text-white disabled:opacity-50 transition-colors"
						>
							{#if pruning}
								<IconLoader size={16} />
								{$t('settings.pruning')}
							{:else}
								{$t('settings.pruneImages')}
							{/if}
						</button>
					</div>

					<hr class="my-5 border-[var(--color-danger)]/20" />

					<p class="text-sm text-[var(--text-secondary)]">{$t('settings.buildCacheCleanupHelp')}</p>

					<div class="mt-4">
						<button
							type="button"
							onclick={() => { showPruneCacheConfirm = true; }}
							disabled={pruningCache}
							class="inline-flex items-center gap-2 rounded-lg border border-[var(--color-danger)] bg-[var(--surface-card)] px-4 py-2 text-sm font-medium text-[var(--color-danger)] hover:bg-[var(--color-danger)] hover:text-white disabled:opacity-50 transition-colors"
						>
							{#if pruningCache}
								<IconLoader size={16} />
								{$t('settings.pruningCache')}
							{:else}
								{$t('settings.pruneBuildCache')}
							{/if}
						</button>
					</div>
				</div>
			</div>
		</div>
	{/if}
</div>

<ConfirmDialog
	open={showPruneConfirm}
	title={$t('settings.pruneImages')}
	message={$t('settings.pruneConfirmMessage')}
	confirmLabel={$t('settings.pruneImages')}
	confirmVariant="danger"
	onconfirm={() => { showPruneConfirm = false; handlePruneImages(); }}
	oncancel={() => { showPruneConfirm = false; }}
/>

<ConfirmDialog
	open={showPruneCacheConfirm}
	title={$t('settings.pruneBuildCache')}
	message={$t('settings.pruneBuildCacheConfirmMessage')}
	confirmLabel={$t('settings.pruneBuildCache')}
	confirmVariant="danger"
	onconfirm={() => { showPruneCacheConfirm = false; handlePruneBuildCache(); }}
	oncancel={() => { showPruneCacheConfirm = false; }}
/>
