<script lang="ts">
	import { untrack } from 'svelte';
	import { t } from 'svelte-i18n';

	interface BackupInfo {
		filename: string;
		size: number;
		createdAt: string;
	}

	interface BackupSchedule {
		backupEnabled: boolean;
		backupCronExpression: string;
		backupMaxCount: number;
	}

	type CronPreset = 'daily' | 'twice_daily' | 'weekly' | 'custom';

	let backups: BackupInfo[] = $state([]);
	let schedule: BackupSchedule = $state({
		backupEnabled: false,
		backupCronExpression: '0 3 * * *',
		backupMaxCount: 10
	});

	let creating = $state(false);
	let savingSchedule = $state(false);
	let restoringFilename: string | null = $state(null);
	let deletingFilename: string | null = $state(null);
	let confirmRestore: string | null = $state(null);
	let confirmDelete: string | null = $state(null);
	let statusMessage = $state('');
	let statusType: 'success' | 'error' | '' = $state('');
	let customCron = $state('');
	let cronPreset: CronPreset = $state('daily');

	const CRON_PRESETS: Record<string, string> = {
		daily: '0 3 * * *',
		twice_daily: '0 */12 * * *',
		weekly: '0 3 * * 0'
	};

	function clearStatus() {
		statusMessage = '';
		statusType = '';
	}

	function formatBytes(bytes: number): string {
		if (bytes < 1024) return `${bytes} B`;
		if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
		return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
	}

	function formatDate(iso: string): string {
		return new Date(iso).toLocaleString();
	}

	function detectPreset(cronExpr: string): CronPreset {
		for (const [key, value] of Object.entries(CRON_PRESETS)) {
			if (cronExpr === value) return key as CronPreset;
		}
		return 'custom';
	}

	async function loadBackups() {
		try {
			const response = await fetch('/api/admin/backups');
			const result = await response.json();
			if (result.success) {
				backups = result.data.backups;
				schedule = result.data.schedule;
				cronPreset = detectPreset(schedule.backupCronExpression);
				if (cronPreset === 'custom') {
					customCron = schedule.backupCronExpression;
				}
			}
		} catch {
			// Fail silently on initial load
		}
	}

	async function handleCreate() {
		clearStatus();
		creating = true;

		try {
			const response = await fetch('/api/admin/backups', { method: 'POST' });
			const result = await response.json();

			if (!response.ok || !result.success) {
				throw new Error(result.error || 'Failed to create backup');
			}

			statusMessage = $t('admin.backup_create_success');
			statusType = 'success';
			await loadBackups();
		} catch (err) {
			statusMessage = err instanceof Error ? err.message : 'Failed to create backup';
			statusType = 'error';
		} finally {
			creating = false;
		}
	}

	async function handleDownload(filename: string) {
		const a = document.createElement('a');
		a.href = `/api/admin/backups/${encodeURIComponent(filename)}/download`;
		a.download = filename;
		document.body.appendChild(a);
		a.click();
		document.body.removeChild(a);
	}

	async function handleRestore(filename: string) {
		clearStatus();
		confirmRestore = null;
		restoringFilename = filename;

		try {
			const response = await fetch(`/api/admin/backups/${encodeURIComponent(filename)}/restore`, {
				method: 'POST'
			});
			const result = await response.json();

			if (!response.ok || !result.success) {
				throw new Error(result.error || 'Failed to restore backup');
			}

			statusMessage = $t('admin.backup_restore_success');
			statusType = 'success';
		} catch (err) {
			statusMessage = err instanceof Error ? err.message : 'Failed to restore backup';
			statusType = 'error';
		} finally {
			restoringFilename = null;
		}
	}

	async function handleDelete(filename: string) {
		clearStatus();
		confirmDelete = null;
		deletingFilename = filename;

		try {
			const response = await fetch(`/api/admin/backups/${encodeURIComponent(filename)}`, {
				method: 'DELETE'
			});
			const result = await response.json();

			if (!response.ok || !result.success) {
				throw new Error(result.error || 'Failed to delete backup');
			}

			statusMessage = $t('admin.backup_delete_success');
			statusType = 'success';
			await loadBackups();
		} catch (err) {
			statusMessage = err instanceof Error ? err.message : 'Failed to delete backup';
			statusType = 'error';
		} finally {
			deletingFilename = null;
		}
	}

	async function handleSaveSchedule() {
		clearStatus();
		savingSchedule = true;

		try {
			const cronExpression = cronPreset === 'custom' ? customCron : CRON_PRESETS[cronPreset];

			const response = await fetch('/api/admin/backups/schedule', {
				method: 'PUT',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({
					backupEnabled: schedule.backupEnabled,
					backupCronExpression: cronExpression,
					backupMaxCount: schedule.backupMaxCount
				})
			});
			const result = await response.json();

			if (!response.ok || !result.success) {
				throw new Error(result.error || 'Failed to save schedule');
			}

			schedule = result.data;
			statusMessage = $t('admin.backup_schedule_saved');
			statusType = 'success';
		} catch (err) {
			statusMessage = err instanceof Error ? err.message : 'Failed to save schedule';
			statusType = 'error';
		} finally {
			savingSchedule = false;
		}
	}

	// Load backups on mount (untrack to avoid infinite re-trigger)
	$effect(() => {
		untrack(() => loadBackups());
	});
</script>

<section class="rounded-lg border border-border bg-card p-6">
	<h2 class="mb-1 text-lg font-semibold text-card-foreground">{$t('admin.backup_title')}</h2>
	<p class="mb-6 text-xs text-muted-foreground">{$t('admin.backup_description')}</p>

	<!-- Create Backup -->
	<div class="mb-6">
		<button
			type="button"
			onclick={handleCreate}
			disabled={creating}
			class="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
		>
			{creating ? $t('admin.backup_creating') : $t('admin.backup_create')}
		</button>
	</div>

	<!-- Backup List -->
	<div class="mb-6">
		<h3 class="mb-3 text-sm font-medium text-foreground">{$t('admin.backup_list_title')}</h3>

		{#if backups.length === 0}
			<p class="text-sm text-muted-foreground">{$t('admin.backup_list_empty')}</p>
		{:else}
			<div class="overflow-x-auto">
				<table class="w-full text-left text-sm">
					<thead>
						<tr class="border-b border-border text-xs uppercase text-muted-foreground">
							<th class="pb-2 pr-4 font-medium">{$t('admin.backup_filename')}</th>
							<th class="pb-2 pr-4 font-medium">{$t('admin.backup_size')}</th>
							<th class="pb-2 pr-4 font-medium">{$t('admin.backup_date')}</th>
							<th class="pb-2 font-medium">{$t('admin.backup_actions')}</th>
						</tr>
					</thead>
					<tbody>
						{#each backups as backup (backup.filename)}
							<tr class="border-b border-border/50">
								<td class="py-2.5 pr-4 font-mono text-xs text-foreground">{backup.filename}</td>
								<td class="py-2.5 pr-4 text-muted-foreground">{formatBytes(backup.size)}</td>
								<td class="py-2.5 pr-4 text-muted-foreground">{formatDate(backup.createdAt)}</td>
								<td class="py-2.5">
									<div class="flex gap-2">
										<button
											type="button"
											onclick={() => handleDownload(backup.filename)}
											class="rounded px-2 py-1 text-xs font-medium text-primary hover:bg-primary/10"
										>
											{$t('admin.backup_download')}
										</button>
										<button
											type="button"
											onclick={() => (confirmRestore = backup.filename)}
											disabled={restoringFilename === backup.filename}
											class="rounded px-2 py-1 text-xs font-medium text-amber-600 hover:bg-amber-600/10 disabled:opacity-50 dark:text-amber-400"
										>
											{restoringFilename === backup.filename
												? '...'
												: $t('admin.backup_restore')}
										</button>
										<button
											type="button"
											onclick={() => (confirmDelete = backup.filename)}
											disabled={deletingFilename === backup.filename}
											class="rounded px-2 py-1 text-xs font-medium text-destructive hover:bg-destructive/10 disabled:opacity-50"
										>
											{deletingFilename === backup.filename
												? '...'
												: $t('admin.backup_delete')}
										</button>
									</div>
								</td>
							</tr>
						{/each}
					</tbody>
				</table>
			</div>
		{/if}
	</div>

	<!-- Restore Confirmation Dialog -->
	{#if confirmRestore}
		<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
			<div class="mx-4 w-full max-w-md rounded-lg border border-border bg-card p-6 shadow-lg">
				<h3 class="mb-2 text-lg font-semibold text-card-foreground">
					{$t('admin.backup_restore_confirm_title')}
				</h3>
				<p class="mb-4 text-sm text-muted-foreground">
					{$t('admin.backup_restore_confirm')}
				</p>
				<p class="mb-4 font-mono text-xs text-foreground">{confirmRestore}</p>
				<div class="flex justify-end gap-3">
					<button
						type="button"
						onclick={() => (confirmRestore = null)}
						class="rounded-md border border-border px-4 py-2 text-sm font-medium text-foreground hover:bg-muted"
					>
						Cancel
					</button>
					<button
						type="button"
						onclick={() => confirmRestore && handleRestore(confirmRestore)}
						class="rounded-md bg-amber-600 px-4 py-2 text-sm font-medium text-white hover:bg-amber-700"
					>
						{$t('admin.backup_restore')}
					</button>
				</div>
			</div>
		</div>
	{/if}

	<!-- Delete Confirmation Dialog -->
	{#if confirmDelete}
		<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
			<div class="mx-4 w-full max-w-md rounded-lg border border-border bg-card p-6 shadow-lg">
				<h3 class="mb-2 text-lg font-semibold text-card-foreground">
					{$t('admin.backup_delete_confirm_title')}
				</h3>
				<p class="mb-4 text-sm text-muted-foreground">
					{$t('admin.backup_delete_confirm')}
				</p>
				<p class="mb-4 font-mono text-xs text-foreground">{confirmDelete}</p>
				<div class="flex justify-end gap-3">
					<button
						type="button"
						onclick={() => (confirmDelete = null)}
						class="rounded-md border border-border px-4 py-2 text-sm font-medium text-foreground hover:bg-muted"
					>
						Cancel
					</button>
					<button
						type="button"
						onclick={() => confirmDelete && handleDelete(confirmDelete)}
						class="rounded-md bg-destructive px-4 py-2 text-sm font-medium text-destructive-foreground hover:bg-destructive/90"
					>
						{$t('admin.backup_delete')}
					</button>
				</div>
			</div>
		</div>
	{/if}

	<!-- Divider -->
	<div class="my-6 border-t border-border"></div>

	<!-- Schedule Configuration -->
	<div>
		<h3 class="mb-3 text-sm font-medium text-foreground">{$t('admin.backup_schedule_title')}</h3>

		<div class="space-y-4">
			<!-- Enable toggle -->
			<label class="flex items-center gap-3">
				<input
					type="checkbox"
					bind:checked={schedule.backupEnabled}
					class="h-4 w-4 rounded border-border text-primary focus:ring-ring"
				/>
				<span class="text-sm text-foreground">{$t('admin.backup_schedule_enabled')}</span>
			</label>

			{#if schedule.backupEnabled}
				<!-- Cron preset -->
				<div>
					<label for="cron-preset" class="mb-1 block text-sm text-muted-foreground">
						{$t('admin.backup_schedule_cron')}
					</label>
					<select
						id="cron-preset"
						bind:value={cronPreset}
						class="w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground sm:w-auto"
					>
						<option value="daily">{$t('admin.backup_schedule_preset_daily')}</option>
						<option value="twice_daily">{$t('admin.backup_schedule_preset_twice_daily')}</option>
						<option value="weekly">{$t('admin.backup_schedule_preset_weekly')}</option>
						<option value="custom">{$t('admin.backup_schedule_preset_custom')}</option>
					</select>
				</div>

				{#if cronPreset === 'custom'}
					<div>
						<input
							type="text"
							bind:value={customCron}
							placeholder="0 3 * * *"
							class="w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground sm:w-64"
						/>
					</div>
				{/if}

				<!-- Max count -->
				<div>
					<label for="max-count" class="mb-1 block text-sm text-muted-foreground">
						{$t('admin.backup_schedule_max_count')}
					</label>
					<input
						id="max-count"
						type="number"
						bind:value={schedule.backupMaxCount}
						min="1"
						max="100"
						class="w-24 rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground"
					/>
				</div>
			{/if}

			<button
				type="button"
				onclick={handleSaveSchedule}
				disabled={savingSchedule}
				class="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
			>
				{savingSchedule ? $t('admin.backup_schedule_saving') : $t('admin.backup_schedule_save')}
			</button>
		</div>
	</div>

	<!-- Status message -->
	{#if statusMessage}
		<div
			class="mt-4 rounded-md p-3 text-sm {statusType === 'success'
				? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400'
				: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400'}"
		>
			{statusMessage}
		</div>
	{/if}
</section>
