<script lang="ts">
	import { onMount } from 'svelte';
	import type { EventTrigger } from '$lib/api';
	import { eventTriggersCache } from '$lib/stores/caches';
	import { IconPlus, IconRefresh } from '$lib/components/icons';
	import ForgeHero from '$lib/components/ForgeHero.svelte';
	import { t } from '$lib/i18n';

	// Cache-backed (stale-while-revalidate) so revisiting this tab renders the
	// list immediately instead of flashing the cold skeleton. See caches.ts.
	const triggers = $derived<EventTrigger[]>($eventTriggersCache.value);
	const loading = $derived($eventTriggersCache.loading);
	const error = $derived($eventTriggersCache.error);

	const enabledCount = $derived(triggers.filter((t) => t.enabled).length);
	const disabledCount = $derived(triggers.length - enabledCount);

	const load = () => eventTriggersCache.refresh();

	// Render a short, comma-separated filter summary so the list table can
	// fit each trigger in a single row without a sub-table. The
	// "any event" fallback is i18n'd; the field=value join keeps the
	// (untranslated) field names so the format stays grep-friendly
	// across locales.
	function filterSummary(trig: EventTrigger): string {
		const parts: string[] = [];
		if (trig.filter_severity) parts.push(`severity=${trig.filter_severity}`);
		if (trig.filter_source) parts.push(`source=${trig.filter_source}`);
		if (trig.filter_message_regex) parts.push(`message~/${trig.filter_message_regex}/`);
		return parts.length === 0 ? $t('observability.anyEvent') : parts.join(' · ');
	}

	onMount(load);
</script>

<svelte:head>
	<title>{$t('triggers.title')} · Tinyforge</title>
</svelte:head>

<div class="forge" aria-busy={loading}>
	{#snippet toolbar()}
		<button
			class="forge-btn-icon"
			onclick={load}
			aria-label={$t('observability.refresh')}
			disabled={loading}
		>
			<IconRefresh size={16} />
		</button>
		<a href="/event-triggers/new" class="forge-btn">
			<IconPlus size={14} />
			<span>{$t('triggers.toolbar.newButton')}</span>
		</a>
	{/snippet}

	{#snippet stats()}
		<div>
			<dt>{$t('triggers.stat.total')}</dt>
			<dd>{loading ? '—' : String(triggers.length).padStart(2, '0')}</dd>
		</div>
		<div>
			<dt>{$t('triggers.stat.enabled')}</dt>
			<dd>{loading ? '—' : String(enabledCount).padStart(2, '0')}</dd>
		</div>
		<div>
			<dt>{$t('triggers.stat.disabled')}</dt>
			<dd class="accent">{loading ? '—' : String(disabledCount).padStart(2, '0')}</dd>
		</div>
	{/snippet}

	{#snippet lede()}
		{$t('triggers.lede')}
	{/snippet}

	<ForgeHero
		eyebrowSuffix={$t('observability.section').toUpperCase()}
		title={$t('triggers.title')}
		size="lg"
		toolbar={toolbar}
		lede_html={lede}
		stats={stats}
	/>

	{#if error}
		<div class="alert" role="alert">
			<span class="alert-tag">ERR</span><span>{error}</span>
		</div>
	{/if}

	{#if loading}
		<div class="skeleton-rows" aria-busy="true" aria-live="polite" aria-label={$t('observability.loading')}>
			{#each Array(3) as _, i}
				<div class="skeleton-row" style:--i={i}></div>
			{/each}
		</div>
	{:else if triggers.length === 0}
		<div class="empty">
			<div class="empty-mark" aria-hidden="true">
				<span></span><span></span><span></span>
			</div>
			<h2>{$t('triggers.empty.heading')}</h2>
			<p>{$t('triggers.empty.body')}</p>
			<a href="/event-triggers/new" class="forge-btn">
				<IconPlus size={14} /><span>{$t('triggers.empty.cta')}</span>
			</a>
		</div>
	{:else}
		<div class="table-wrap">
			<table class="forge-table">
				<thead>
					<tr>
						<th>{$t('triggers.list.name')}</th>
						<th class="hide-md">{$t('triggers.list.filters')}</th>
						<th>{$t('triggers.list.action')}</th>
						<th>{$t('triggers.list.status')}</th>
						<th class="t-right">{$t('triggers.list.open')}</th>
					</tr>
				</thead>
				<tbody>
					{#each triggers as trig, i (trig.id)}
						<tr>
							<td>
								<a class="row-link" href={`/event-triggers/${trig.id}`}>
									<span class="row-ref">{String(i + 1).padStart(2, '0')}</span>
									<span class="row-name">{trig.name}</span>
								</a>
							</td>
							<td class="muted mono small hide-md filters-cell">
								{filterSummary(trig)}
							</td>
							<td>
								<div class="action-cell">
									<span class="badge action">{trig.action_type}</span>
									<span class="action-target muted mono small">{trig.action_target}</span>
								</div>
							</td>
							<td>
								<span class="status" class:on={trig.enabled} class:off={!trig.enabled}>
									<span class="status-dot" aria-hidden="true"></span>
									{trig.enabled ? $t('triggers.status.enabled') : $t('triggers.status.disabled')}
								</span>
							</td>
							<td class="actions-cell">
								<a class="row-action" href={`/event-triggers/${trig.id}`}>
									{$t('observability.open')} <span class="arrow" aria-hidden="true">→</span>
								</a>
							</td>
						</tr>
					{/each}
				</tbody>
			</table>
		</div>
	{/if}
</div>

<style>
	.forge {
		display: flex;
		flex-direction: column;
		gap: 1.25rem;
		max-width: 1100px;
		margin: 0 auto;
	}

	/* ── Alert ─────────────────────────────────────── */
	.alert {
		display: flex;
		gap: 0.7rem;
		align-items: center;
		padding: 0.7rem 0.9rem;
		background: var(--color-danger-light);
		color: var(--color-danger-dark);
		border: 1px solid var(--color-danger);
		border-left-width: 4px;
		border-radius: var(--radius-lg);
		font-size: 0.875rem;
	}
	.alert-tag {
		font-family: var(--forge-mono);
		font-weight: 700;
		font-size: 0.65rem;
		letter-spacing: 0.16em;
		padding: 0.15rem 0.4rem;
		background: var(--color-danger);
		color: var(--surface-card);
		border-radius: var(--radius-sm);
	}
	:global([data-theme='dark']) .alert {
		background: color-mix(in srgb, var(--color-danger) 14%, transparent);
		color: color-mix(in srgb, var(--color-danger) 60%, var(--text-primary));
	}

	/* ── Skeleton ──────────────────────────────────── */
	.skeleton-rows {
		display: flex;
		flex-direction: column;
		gap: 0.55rem;
	}
	.skeleton-row {
		height: 52px;
		border: 1px solid var(--border-primary);
		border-radius: var(--radius-lg);
		background: linear-gradient(
			110deg,
			var(--surface-card) 20%,
			var(--surface-card-hover) 50%,
			var(--surface-card) 80%
		);
		background-size: 200% 100%;
		animation: shimmer 1.6s linear infinite;
		animation-delay: calc(var(--i) * 120ms);
	}
	@keyframes shimmer {
		0% {
			background-position: 200% 0;
		}
		100% {
			background-position: -200% 0;
		}
	}

	/* ── Empty ─────────────────────────────────────── */
	.empty {
		text-align: center;
		padding: 4rem 2rem;
		border: 1px dashed var(--border-primary);
		border-radius: var(--radius-2xl);
		background: var(--surface-card);
	}
	.empty-mark {
		display: inline-flex;
		gap: 4px;
		margin-bottom: 1.5rem;
	}
	.empty-mark span {
		width: 10px;
		height: 10px;
		border-radius: 50%;
		background: var(--border-input);
	}
	.empty-mark span:nth-child(2) {
		background: var(--forge-accent);
		animation: ember 2.4s ease-in-out infinite;
	}
	@keyframes ember {
		0%,
		100% {
			box-shadow: 0 0 0 3px var(--forge-accent-soft);
		}
		50% {
			box-shadow: 0 0 0 6px color-mix(in srgb, var(--color-brand-500) 18%, transparent);
		}
	}
	.empty h2 {
		font-weight: 700;
		font-size: 1.5rem;
		margin: 0 0 0.5rem;
		letter-spacing: -0.01em;
		color: var(--text-primary);
	}
	.empty p {
		color: var(--text-secondary);
		margin: 0 auto 1.5rem;
		font-size: 0.95rem;
		max-width: 52ch;
		line-height: 1.5;
	}

	/* ── Table ─────────────────────────────────────── */
	.table-wrap {
		border: 1px solid var(--border-primary);
		border-radius: var(--radius-xl);
		background: var(--surface-card);
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}
	.table-wrap :global(.forge-table) {
		min-width: 640px;
	}
	.t-right {
		text-align: right;
	}
	.actions-cell {
		text-align: right;
	}
	.filters-cell {
		max-width: 320px;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
	@media (max-width: 820px) {
		.hide-md {
			display: none;
		}
	}

	/* ── Row link / action ─────────────────────────── */
	.row-link {
		display: inline-flex;
		align-items: baseline;
		gap: 0.6rem;
		color: var(--text-primary);
		text-decoration: none;
		transition: color 120ms ease;
	}
	.row-link:hover {
		color: var(--forge-accent);
	}
	.row-link:focus-visible {
		outline: 2px solid var(--border-focus);
		outline-offset: 2px;
		border-radius: var(--radius-sm);
	}
	.row-ref {
		font-family: var(--forge-mono);
		font-size: 0.68rem;
		letter-spacing: 0.1em;
		color: var(--text-tertiary);
	}
	.row-name {
		font-weight: 600;
	}
	.row-action {
		font-family: var(--forge-mono);
		font-size: 0.68rem;
		font-weight: 600;
		letter-spacing: 0.1em;
		text-transform: uppercase;
		color: var(--forge-accent);
		text-decoration: none;
	}
	.row-action:hover {
		color: var(--color-brand-500);
	}
	.row-action:focus-visible {
		outline: 2px solid var(--border-focus);
		outline-offset: 2px;
		border-radius: var(--radius-sm);
	}
	.arrow {
		display: inline-block;
		transition: transform 150ms ease;
	}
	.row-action:hover .arrow {
		transform: translateX(3px);
	}

	/* ── Action badge + target ─────────────────────── */
	.action-cell {
		display: flex;
		align-items: center;
		gap: 0.5rem;
		min-width: 0;
	}
	.badge.action {
		display: inline-flex;
		align-items: center;
		padding: 0.18rem 0.55rem;
		background: var(--surface-card-hover);
		border: 1px solid var(--border-primary);
		border-radius: var(--radius-full);
		font-family: var(--forge-mono);
		font-size: 0.62rem;
		font-weight: 600;
		letter-spacing: 0.1em;
		text-transform: uppercase;
		color: var(--text-secondary);
		flex: 0 0 auto;
	}
	.action-target {
		max-width: 320px;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
		min-width: 0;
	}
	.small {
		font-size: 0.72rem;
	}

	/* ── Status ────────────────────────────────────── */
	.status {
		display: inline-flex;
		align-items: center;
		gap: 0.4rem;
		font-family: var(--forge-mono);
		font-size: 0.62rem;
		letter-spacing: 0.1em;
		font-weight: 600;
		text-transform: uppercase;
		white-space: nowrap;
	}
	.status-dot {
		width: 7px;
		height: 7px;
		border-radius: 50%;
	}
	.status.on {
		color: var(--color-success-dark);
	}
	.status.on .status-dot {
		background: var(--color-success);
		box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-success) 20%, transparent);
	}
	.status.off {
		color: var(--text-tertiary);
	}
	.status.off .status-dot {
		background: var(--text-tertiary);
		opacity: 0.5;
	}

	.muted {
		color: var(--text-tertiary);
	}
	.mono {
		font-family: var(--forge-mono);
	}
</style>
