<script lang="ts">
	import { onMount } from 'svelte';
	import { slide } from 'svelte/transition';
	import { api } from '$lib/api';
	import { t, getLocale } 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 { snackSuccess, snackError } from '$lib/stores/snackbar.svelte';

	let loaded = $state(false);
	let loadError = $state('');
	let trackers = $state<any[]>([]);
	let providers = $state<any[]>([]);
	let targets = $state<any[]>([]);
	let trackingConfigs = $state<any[]>([]);
	let templateConfigs = $state<any[]>([]);
	let collections = $state<any[]>([]);
	let showForm = $state(false);
	let editing = $state<number | null>(null);
	let collectionFilter = $state('');
	let submitting = $state(false);
	let confirmDelete = $state<any>(null);
	let toggling = $state<Record<number, boolean>>({});
	// Per tracker-target test state (keyed by `${ttId}_${testType}`)
	let ttTesting = $state<Record<string, string>>({});

	// Shared link validation
	let linkWarning = $state<{ albums: any[], providerId: number } | null>(null);
	let linkCheckLoading = $state(false);
	let linkCreating = $state(false);
	let previousCollectionIds = $state<string[]>([]);

	// Tracker form
	const defaultForm = () => ({
		name: '', icon: '', provider_id: 0, collection_ids: [] as string[],
		scan_interval: 60, batch_duration: 0,
	});
	let form = $state(defaultForm());
	let error = $state('');

	// Linked targets management (inline in tracker detail)
	let expandedTracker = $state<number | null>(null);
	let linkedTargets = $state<Record<number, any[]>>({});
	let addingTarget = $state<Record<number, boolean>>({});
	let newLinkTargetId = $state<Record<number, number>>({});
	let newLinkTrackingConfigId = $state<Record<number, number>>({});
	let newLinkTemplateConfigId = $state<Record<number, number>>({});

	onMount(load);
	async function load() {
		loadError = '';
		try {
			[trackers, providers, targets, trackingConfigs, templateConfigs] = await Promise.all([
				api('/trackers'), api('/providers'), api('/targets'),
				api('/tracking-configs'), api('/template-configs'),
			]);
		} catch (err: any) {
			loadError = err.message || 'Failed to load data';
			snackError(loadError);
		} finally { loaded = true; }
	}
	async function loadCollections() {
		if (!form.provider_id) return;
		try { collections = await api(`/providers/${form.provider_id}/collections`); } catch { collections = []; }
	}

	function openNew() { form = defaultForm(); editing = null; showForm = true; collections = []; previousCollectionIds = []; }
	async function edit(trk: any) {
		form = {
			name: trk.name, icon: trk.icon || '', provider_id: trk.provider_id,
			collection_ids: [...(trk.collection_ids || [])],
			scan_interval: trk.scan_interval, batch_duration: trk.batch_duration ?? 0,
		};
		previousCollectionIds = [...(trk.collection_ids || [])];
		editing = trk.id; showForm = true;
		if (form.provider_id) await loadCollections();
	}

	async function save(e: SubmitEvent) {
		e.preventDefault(); error = '';
		if (submitting) return;

		// Check shared links for newly added albums
		const newAlbumIds = form.collection_ids.filter(id => !previousCollectionIds.includes(id));
		if (newAlbumIds.length > 0 && form.provider_id) {
			linkCheckLoading = true;
			try {
				const missingAlbums: any[] = [];
				for (const albumId of newAlbumIds) {
					const links = await api(`/providers/${form.provider_id}/albums/${albumId}/shared-links`);
					const validLink = (links as any[]).find((l: any) => l.is_accessible && !l.is_expired);
					if (!validLink) {
						const album = collections.find(c => c.id === albumId);
						const problematicLink = (links as any[]).find((l: any) => l.is_expired || l.has_password);
						missingAlbums.push({
							id: albumId,
							name: album?.albumName || album?.name || albumId,
							issue: problematicLink
								? (problematicLink.is_expired ? 'expired' : 'password-protected')
								: 'missing',
						});
					}
				}
				if (missingAlbums.length > 0) {
					linkWarning = { albums: missingAlbums, providerId: form.provider_id };
					linkCheckLoading = false;
					return; // Show warning, don't save yet
				}
			} catch { /* Proceed if check fails */ }
			linkCheckLoading = false;
		}

		await doSave();
	}

	async function doSave() {
		submitting = true;
		try {
			if (editing) {
				await api(`/trackers/${editing}`, { method: 'PUT', body: JSON.stringify(form) });
				snackSuccess(t('snack.trackerUpdated'));
			} else {
				await api('/trackers', { method: 'POST', body: JSON.stringify(form) });
				snackSuccess(t('snack.trackerCreated'));
			}
			showForm = false; editing = null; linkWarning = null; await load();
		} catch (err: any) { error = err.message; snackError(err.message); } finally { submitting = false; }
	}

	async function autoCreateLinks() {
		if (!linkWarning) return;
		linkCreating = true;
		let created = 0;
		for (const album of linkWarning.albums) {
			if (album.issue === 'missing') {
				try {
					await api(`/providers/${linkWarning.providerId}/albums/${album.id}/shared-links`, { method: 'POST' });
					created++;
				} catch (err: any) {
					snackError(`Failed to create link for "${album.name}": ${err.message}`);
				}
			}
		}
		if (created > 0) snackSuccess(`Created ${created} public link(s)`);
		linkWarning = null;
		linkCreating = false;
		await doSave();
	}

	function dismissLinkWarning() {
		linkWarning = null;
		doSave();
	}
	async function toggle(tracker: any) {
		if (toggling[tracker.id]) return;
		toggling = { ...toggling, [tracker.id]: true };
		try {
			await api(`/trackers/${tracker.id}`, { method: 'PUT', body: JSON.stringify({ enabled: !tracker.enabled }) });
			await load();
			snackSuccess(tracker.enabled ? t('snack.trackerPaused') : t('snack.trackerResumed'));
		} catch (err: any) { snackError(err.message); } finally { toggling = { ...toggling, [tracker.id]: false }; }
	}
	function startDelete(tracker: any) { confirmDelete = tracker; }
	async function doDelete() {
		if (!confirmDelete) return;
		try {
			await api(`/trackers/${confirmDelete.id}`, { method: 'DELETE' });
			await load();
			snackSuccess(t('snack.trackerDeleted'));
		} catch (err: any) { error = err.message; snackError(err.message); }
		confirmDelete = null;
	}
	let testMenuOpen = $state<string | null>(null);
	let testMenuStyle = $state('');

	const testTypes = [
		{ key: 'basic', icon: 'mdiSend', labelKey: 'trackers.testBasic' },
		{ key: 'periodic', icon: 'mdiCalendarClock', labelKey: 'trackers.testPeriodic' },
		{ key: 'scheduled', icon: 'mdiImageMultiple', labelKey: 'trackers.testScheduled' },
		{ key: 'memory', icon: 'mdiHistory', labelKey: 'trackers.testMemory' },
	];

	async function testTrackerTarget(trackerId: number, ttId: number, testType: string) {
		testMenuOpen = null;
		const key = `${ttId}_${testType}`;
		if (ttTesting[key]) return;
		ttTesting = { ...ttTesting, [key]: testType };
		try {
			await api(`/trackers/${trackerId}/targets/${ttId}/test/${testType}?locale=${getLocale()}`, { method: 'POST' });
			snackSuccess(t('snack.targetTestSent'));
		} catch (err: any) {
			snackError(err.message);
		} finally {
			ttTesting = { ...ttTesting, [key]: '' };
		}
	}

	function openTestMenu(ttId: number, event: MouseEvent) {
		const btn = event.currentTarget as HTMLElement;
		const rect = btn.getBoundingClientRect();
		testMenuStyle = `position:fixed; z-index:9999; top:${rect.bottom + 4}px; right:${window.innerWidth - rect.right}px;`;
		testMenuOpen = testMenuOpen === String(ttId) ? null : String(ttId);
	}
	function toggleCollection(collectionId: string) { form.collection_ids = form.collection_ids.includes(collectionId) ? form.collection_ids.filter(id => id !== collectionId) : [...form.collection_ids, collectionId]; }

	function formatDate(dateStr: string): string {
		if (!dateStr) return '';
		try {
			const d = new Date(dateStr);
			return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' });
		} catch { return ''; }
	}

	// --- Linked Targets Management ---
	function toggleExpand(trackerId: number) {
		if (expandedTracker === trackerId) { expandedTracker = null; return; }
		expandedTracker = trackerId;
		// tracker_targets already loaded in tracker response
	}

	function getUnlinkedTargets(tracker: any): any[] {
		const linkedIds = new Set((tracker.tracker_targets || []).map((tt: any) => tt.target_id));
		return targets.filter(t => !linkedIds.has(t.id));
	}

	async function addTargetLink(trackerId: number) {
		const targetId = newLinkTargetId[trackerId];
		if (!targetId) return;
		addingTarget = { ...addingTarget, [trackerId]: true };
		try {
			await api(`/trackers/${trackerId}/targets`, {
				method: 'POST',
				body: JSON.stringify({
					target_id: targetId,
					tracking_config_id: newLinkTrackingConfigId[trackerId] || null,
					template_config_id: newLinkTemplateConfigId[trackerId] || null,
				}),
			});
			newLinkTargetId[trackerId] = 0;
			newLinkTrackingConfigId[trackerId] = 0;
			newLinkTemplateConfigId[trackerId] = 0;
			await load();
			snackSuccess(t('snack.targetLinked'));
		} catch (err: any) { snackError(err.message); }
		addingTarget = { ...addingTarget, [trackerId]: false };
	}

	async function removeTargetLink(trackerId: number, ttId: number) {
		try {
			await api(`/trackers/${trackerId}/targets/${ttId}`, { method: 'DELETE' });
			await load();
			snackSuccess(t('snack.targetUnlinked'));
		} catch (err: any) { snackError(err.message); }
	}

	async function updateTargetLink(trackerId: number, tt: any, field: string, value: any) {
		try {
			await api(`/trackers/${trackerId}/targets/${tt.id}`, {
				method: 'PUT',
				body: JSON.stringify({ [field]: value }),
			});
			await load();
		} catch (err: any) { snackError(err.message); }
	}
</script>

<PageHeader title={t('trackers.title')} description={t('trackers.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('trackers.cancel') : t('trackers.newTracker')}
	</button>
</PageHeader>

{#if !loaded}
<Loading />
{:else if loadError}
	<Card>
		<div class="bg-[var(--color-error-bg)] text-[var(--color-error-fg)] text-sm rounded-md p-3">{loadError}</div>
	</Card>
{:else if showForm}
	<div in:slide={{ duration: 200 }}>
	<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-4">
			<div>
				<label for="trk-name" class="block text-sm font-medium mb-1">{t('trackers.name')}</label>
				<div class="flex gap-2">
					<IconPicker value={form.icon} onselect={(v: string) => form.icon = v} />
					<input id="trk-name" bind:value={form.name} required placeholder={t('trackers.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="trk-provider" class="block text-sm font-medium mb-1">{t('trackers.server')}</label>
				<select id="trk-provider" bind:value={form.provider_id} onchange={loadCollections} required class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]">
					<option value={0} disabled>{t('trackers.selectServer')}</option>
					{#each providers as p}<option value={p.id}>{p.name}</option>{/each}
				</select>
			</div>
			{#if collections.length > 0}
				<div>
					<label class="block text-sm font-medium mb-1">{t('trackers.albums')} ({collections.length})</label>
					<input type="text" bind:value={collectionFilter} placeholder="Filter..."
						class="w-full px-3 py-1.5 mb-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
					<div class="max-h-56 overflow-y-auto border border-[var(--color-border)] rounded-md p-2 space-y-1">
						{#each collections.filter(a => !collectionFilter || (a.albumName || a.name || '').toLowerCase().includes(collectionFilter.toLowerCase())) as col}
							<label class="flex items-center justify-between text-sm cursor-pointer hover:bg-[var(--color-muted)] px-2 py-1 rounded">
								<span class="flex items-center gap-2">
									<input type="checkbox" checked={form.collection_ids.includes(col.id)} onchange={() => toggleCollection(col.id)} />
									{col.albumName || col.name} <span class="text-[var(--color-muted-foreground)]">({col.assetCount ?? col.asset_count ?? 0})</span>
								</span>
								{#if col.updatedAt || col.updated_at}
									<span class="text-xs text-[var(--color-muted-foreground)] whitespace-nowrap ml-2">{formatDate(col.updatedAt || col.updated_at)}</span>
								{/if}
							</label>
						{/each}
					</div>
				</div>
			{/if}
			<div class="grid grid-cols-2 gap-3">
				<div>
					<label for="trk-interval" class="block text-sm font-medium mb-1">{t('trackers.scanInterval')}<Hint text={t('hints.scanInterval')} /></label>
					<input id="trk-interval" type="number" bind:value={form.scan_interval} min="10" max="3600" class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
				</div>
				<div>
					<label for="trk-batch" class="block text-sm font-medium mb-1">{t('trackers.batchDuration')}<Hint text={t('hints.batchDuration')} /></label>
					<input id="trk-batch" type="number" bind:value={form.batch_duration} min="0" max="3600" class="w-full px-3 py-2 border border-[var(--color-border)] rounded-md text-sm bg-[var(--color-background)]" />
				</div>
			</div>

			<button type="submit" disabled={submitting || linkCheckLoading} class="px-4 py-2 bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded-md text-sm font-medium hover:opacity-90 disabled:opacity-50">
				{#if linkCheckLoading}Checking links...{:else}{editing ? t('common.save') : t('trackers.createTracker')}{/if}
			</button>
		</form>
	</Card>
	</div>
{/if}

{#if loaded && !loadError}
{#if trackers.length === 0 && !showForm}
	<Card>
		<div class="flex flex-col items-center py-8 gap-3" style="color: var(--color-muted-foreground);">
			<div style="opacity: 0.4;"><MdiIcon name="mdiRadar" size={40} /></div>
			<p class="text-sm">{t('trackers.noTrackers')}</p>
		</div>
	</Card>
{:else if !showForm}
	<div class="space-y-3 stagger-children">
		{#each trackers as tracker}
			<Card hover>
				<div class="flex items-center justify-between">
					<div>
						<div class="flex items-center gap-2">
							<span style="color: var(--color-primary);"><MdiIcon name={tracker.icon || 'mdiRadar'} size={20} /></span>
							<p class="font-medium">{tracker.name}</p>
							<span class="text-xs px-1.5 py-0.5 rounded {tracker.enabled ? 'bg-[var(--color-success-bg)] text-[var(--color-success-fg)]' : 'bg-[var(--color-muted)] text-[var(--color-muted-foreground)]'}">
								{tracker.enabled ? t('trackers.active') : t('trackers.paused')}
							</span>
						</div>
						<p class="text-sm text-[var(--color-muted-foreground)]">
							{(tracker.collection_ids || []).length} {t('trackers.albums_count')} · {t('trackers.every')} {tracker.scan_interval}s · {(tracker.tracker_targets || []).length} {t('trackers.linkedTargets')}
						</p>
					</div>
					<div class="flex items-center gap-1 flex-wrap justify-end">
						<IconButton icon="mdiPencil" title={t('common.edit')} onclick={() => edit(tracker)} />
						<IconButton icon="mdiPlay" title={t('common.test')} onclick={async () => { try { await api(`/trackers/${tracker.id}/trigger`, { method: 'POST' }); snackSuccess(t('snack.targetTestSent')); } catch (err) { snackError((err as any).message); } }} />
						<IconButton icon={tracker.enabled ? 'mdiPause' : 'mdiPlay'} title={tracker.enabled ? t('trackers.pause') : t('trackers.resume')} onclick={() => toggle(tracker)} disabled={toggling[tracker.id]} />
						<button onclick={() => toggleExpand(tracker.id)}
							class="text-xs text-[var(--color-muted-foreground)] hover:underline px-2 py-1">
							{t('trackers.linkedTargets')} {expandedTracker === tracker.id ? '▲' : '▼'}
						</button>
						<IconButton icon="mdiDelete" title={t('trackers.delete')} onclick={() => startDelete(tracker)} variant="danger" />
					</div>
				</div>

				<!-- Linked Targets Section -->
				{#if expandedTracker === tracker.id}
					<div class="mt-3 border-t border-[var(--color-border)] pt-3 space-y-2" in:slide>
						{#if (tracker.tracker_targets || []).length === 0}
							<p class="text-xs text-[var(--color-muted-foreground)]">{t('trackers.noLinkedTargets')}</p>
						{:else}
							{#each tracker.tracker_targets as tt}
								<div class="flex items-center justify-between text-sm px-2 py-1.5 rounded bg-[var(--color-muted)]/30">
									<div class="flex items-center gap-2">
										<span style="color: var(--color-primary);"><MdiIcon name={tt.target_icon || (tt.target_type === 'telegram' ? 'mdiSend' : 'mdiWebhook')} size={16} /></span>
										<span class="font-medium">{tt.target_name || `Target #${tt.target_id}`}</span>
										<span class="text-xs px-1.5 py-0.5 rounded bg-[var(--color-muted)] text-[var(--color-muted-foreground)]">{tt.target_type}</span>
										{#if !tt.enabled}
											<span class="text-xs px-1.5 py-0.5 rounded bg-[var(--color-warning-bg)] text-[var(--color-warning-fg)]">{t('trackers.paused')}</span>
										{/if}
									</div>
									<div class="flex items-center gap-2 flex-wrap justify-end">
										<select value={tt.tracking_config_id || 0}
											onchange={(e: Event) => updateTargetLink(tracker.id, tt, 'tracking_config_id', Number((e.target as HTMLSelectElement).value) || null)}
											class="text-xs px-2 py-1 border border-[var(--color-border)] rounded-md bg-[var(--color-background)]">
											<option value={0}>— {t('trackingConfig.title')} —</option>
											{#each trackingConfigs as tc}<option value={tc.id}>{tc.name}</option>{/each}
										</select>
										<select value={tt.template_config_id || 0}
											onchange={(e: Event) => updateTargetLink(tracker.id, tt, 'template_config_id', Number((e.target as HTMLSelectElement).value) || null)}
											class="text-xs px-2 py-1 border border-[var(--color-border)] rounded-md bg-[var(--color-background)]">
											<option value={0}>— {t('templateConfig.title')} —</option>
											{#each templateConfigs as tc}<option value={tc.id}>{tc.name}</option>{/each}
										</select>
										<div class="relative">
											<IconButton icon="mdiDotsVertical" size={14} title={t('common.test')}
												onclick={(e: MouseEvent) => openTestMenu(tt.id, e)}
												disabled={Object.keys(ttTesting).some(k => k.startsWith(`${tt.id}_`) && ttTesting[k])} />
										</div>
										<IconButton icon={tt.enabled ? 'mdiPause' : 'mdiPlay'} size={14}
											title={tt.enabled ? t('trackers.pause') : t('trackers.resume')}
											onclick={() => updateTargetLink(tracker.id, tt, 'enabled', !tt.enabled)} />
										<IconButton icon="mdiClose" size={14} title={t('common.delete')}
											onclick={() => removeTargetLink(tracker.id, tt.id)} variant="danger" />
									</div>
								</div>
							{/each}
						{/if}

						<!-- Add target link -->
						{#if getUnlinkedTargets(tracker).length > 0}
							<div class="flex items-center gap-2 mt-2">
								<select bind:value={newLinkTargetId[tracker.id]}
									class="text-xs px-2 py-1 border border-[var(--color-border)] rounded-md bg-[var(--color-background)] flex-1">
									<option value={0}>— {t('trackers.addTarget')} —</option>
									{#each getUnlinkedTargets(tracker) as tgt}<option value={tgt.id}>{tgt.name} ({tgt.type})</option>{/each}
								</select>
								<select bind:value={newLinkTrackingConfigId[tracker.id]}
									class="text-xs px-2 py-1 border border-[var(--color-border)] rounded-md bg-[var(--color-background)]">
									<option value={0}>— {t('trackingConfig.title')} —</option>
									{#each trackingConfigs as tc}<option value={tc.id}>{tc.name}</option>{/each}
								</select>
								<select bind:value={newLinkTemplateConfigId[tracker.id]}
									class="text-xs px-2 py-1 border border-[var(--color-border)] rounded-md bg-[var(--color-background)]">
									<option value={0}>— {t('templateConfig.title')} —</option>
									{#each templateConfigs as tc}<option value={tc.id}>{tc.name}</option>{/each}
								</select>
								<button onclick={() => addTargetLink(tracker.id)}
									disabled={!newLinkTargetId[tracker.id] || addingTarget[tracker.id]}
									class="text-xs px-3 py-1 bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded hover:opacity-90 disabled:opacity-50">
									{t('common.add')}
								</button>
							</div>
						{/if}
					</div>
				{/if}
			</Card>
		{/each}
	</div>
{/if}
{/if}

{#if testMenuOpen}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div style="position:fixed; top:0; left:0; right:0; bottom:0; z-index:9998;"
		onclick={() => testMenuOpen = null}
		onkeydown={(e) => { if (e.key === 'Escape') testMenuOpen = null; }}>
	</div>
	<div style="{testMenuStyle} background:var(--color-card); border:1px solid var(--color-border); border-radius:0.5rem; box-shadow:0 10px 25px rgba(0,0,0,0.3); padding:0.25rem; min-width:10rem;">
		{#each testTypes as tt}
			{@const trackerId = trackers.find(t => t.tracker_targets?.some((x: any) => String(x.id) === testMenuOpen))?.id}
			<button
				onclick={() => trackerId && testTrackerTarget(trackerId, Number(testMenuOpen), tt.key)}
				disabled={!!ttTesting[`${testMenuOpen}_${tt.key}`]}
				class="flex items-center gap-2 w-full px-3 py-1.5 text-sm rounded hover:bg-[var(--color-muted)] transition-colors disabled:opacity-50 text-left">
				<MdiIcon name={tt.icon} size={14} />
				{t(tt.labelKey)}
				{#if ttTesting[`${testMenuOpen}_${tt.key}`]}
					<span class="ml-auto text-xs text-[var(--color-muted-foreground)]">...</span>
				{/if}
			</button>
		{/each}
	</div>
{/if}

{#if linkWarning}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div style="position:fixed; top:0; left:0; right:0; bottom:0; z-index:9998; background:rgba(0,0,0,0.5);"
		onclick={() => { linkWarning = null; }}
		onkeydown={(e) => { if (e.key === 'Escape') linkWarning = null; }}>
	</div>
	<div style="position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); z-index:9999; width:28rem; max-width:90vw; background:var(--color-card); border:1px solid var(--color-border); border-radius:0.75rem; padding:1.5rem; box-shadow:0 20px 60px rgba(0,0,0,0.4);">
		<div class="flex items-center gap-2 mb-3">
			<span style="color: var(--color-warning-fg);"><MdiIcon name="mdiAlertCircle" size={22} /></span>
			<h3 class="font-semibold">Albums Missing Public Links</h3>
		</div>
		<p class="text-sm mb-3" style="color: var(--color-muted-foreground);">
			The following albums don't have valid public shared links. Without public links, notification messages won't include clickable URLs to albums or assets.
		</p>
		<div class="space-y-1.5 mb-4 max-h-40 overflow-y-auto">
			{#each linkWarning.albums as album}
				<div class="flex items-center justify-between text-sm px-2 py-1.5 rounded bg-[var(--color-muted)]/30">
					<span class="font-medium">{album.name}</span>
					<span class="text-xs px-1.5 py-0.5 rounded {album.issue === 'expired' ? 'bg-[var(--color-error-bg)] text-[var(--color-error-fg)]' : album.issue === 'password-protected' ? 'bg-[var(--color-warning-bg)] text-[var(--color-warning-fg)]' : 'bg-[var(--color-muted)] text-[var(--color-muted-foreground)]'}">
						{album.issue === 'expired' ? 'Expired' : album.issue === 'password-protected' ? 'Password Protected' : 'No Link'}
					</span>
				</div>
			{/each}
		</div>
		<p class="text-xs mb-4" style="color: var(--color-muted-foreground);">
			<MdiIcon name="mdiInformation" size={14} /> Public links allow anyone with the URL to view album contents. Albums without links will still be tracked and assets sent to chats, but messages won't include clickable links.
		</p>
		<div class="flex items-center gap-2 justify-end">
			<button onclick={dismissLinkWarning}
				class="px-3 py-1.5 text-sm border border-[var(--color-border)] rounded-md hover:bg-[var(--color-muted)]">
				Save without links
			</button>
			{#if linkWarning.albums.some(a => a.issue === 'missing')}
				<button onclick={autoCreateLinks} disabled={linkCreating}
					class="px-3 py-1.5 text-sm bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded-md hover:opacity-90 disabled:opacity-50">
					{linkCreating ? 'Creating...' : `Create ${linkWarning.albums.filter(a => a.issue === 'missing').length} link(s)`}
				</button>
			{/if}
		</div>
	</div>
{/if}

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