<!--
  TimezoneSelector — "Forge Chronograph"

  A calibrated instrument for picking the display timezone. Shows a live
  tabular-nums clock in the chosen zone so the user sees exactly what timestamps
  across the app will look like. Supports auto-detect (follows the browser) or
  a manual IANA zone via the command-palette picker.
-->
<script lang="ts">
	import { onDestroy } from 'svelte';
	import { t } from '$lib/i18n';
	import {
		timezonePreference,
		setTimezonePreference,
		detectBrowserTimezone,
		effectiveTimezone,
		listAllTimezones,
		formatOffsetLabel,
		COMMON_TIMEZONES,
		AUTO_TIMEZONE
	} from '$lib/stores/timezone';
	import { fmt } from '$lib/format/datetime';
	import EntityPicker from '$lib/components/EntityPicker.svelte';
	import type { EntityPickerItem } from '$lib/types';
	import { IconClock, IconGlobe, IconCheck } from '$lib/components/icons';

	let pickerOpen = $state(false);
	let now = $state(new Date());

	// 1-second tick so the clock actually ticks. Cleared on destroy.
	const ticker = setInterval(() => { now = new Date(); }, 1000);
	onDestroy(() => clearInterval(ticker));

	const detected = $derived(detectBrowserTimezone());
	const isAuto = $derived($timezonePreference === AUTO_TIMEZONE);

	// Build the picker catalogue once: curated shortlist first (grouped as
	// "Popular"), then the full IANA list. This keeps the UX fast for most
	// users while still permitting "Antarctica/Vostok" style edge cases.
	const pickerItems = $derived.by<EntityPickerItem[]>(() => {
		const items: EntityPickerItem[] = [];
		const seen = new Set<string>();

		items.push({
			value: AUTO_TIMEZONE,
			label: $t('timezone.autoDetect'),
			description: `${detected} · ${formatOffsetLabel(detected, now)}`,
			group: $t('timezone.groupAuto')
		});
		seen.add(AUTO_TIMEZONE);

		for (const tz of COMMON_TIMEZONES) {
			if (seen.has(tz)) continue;
			seen.add(tz);
			items.push({
				value: tz,
				label: tz.replace(/_/g, ' '),
				description: formatOffsetLabel(tz, now),
				group: $t('timezone.groupPopular')
			});
		}

		for (const tz of listAllTimezones()) {
			if (seen.has(tz)) continue;
			seen.add(tz);
			items.push({
				value: tz,
				label: tz.replace(/_/g, ' '),
				description: formatOffsetLabel(tz, now),
				group: $t('timezone.groupAll')
			});
		}
		return items;
	});

	function handleSelect(value: string) {
		setTimezonePreference(value as typeof AUTO_TIMEZONE | string);
		pickerOpen = false;
	}

	// Sample timestamps surfaced below the clock — demonstrates exactly where
	// the user's choice takes effect. Ticking clock keeps them live.
	const previewNow = $derived($fmt.dateTime(now));
	const previewDate = $derived($fmt.date(now));
	const clockReading = $derived($fmt.clock(now));
	const currentOffset = $derived(formatOffsetLabel($effectiveTimezone, now));
	const currentZoneLabel = $derived($effectiveTimezone.replace(/_/g, ' '));
</script>

<section class="tz-card">
	<!-- Header: label + mode toggle (auto vs manual) -->
	<header class="tz-card__head">
		<div class="tz-card__title-group">
			<span class="tz-card__eyebrow">
				<IconClock size={12} />
				<span>{$t('timezone.eyebrow')}</span>
			</span>
			<h3 class="tz-card__title">{$t('timezone.title')}</h3>
			<p class="tz-card__subtitle">{$t('timezone.subtitle')}</p>
		</div>

		<div class="tz-card__mode" role="tablist" aria-label={$t('timezone.modeLabel')}>
			<button
				type="button"
				role="tab"
				aria-selected={isAuto}
				class="tz-mode-btn"
				class:is-active={isAuto}
				onclick={() => setTimezonePreference(AUTO_TIMEZONE)}
			>
				<IconGlobe size={13} />
				<span>{$t('timezone.modeAuto')}</span>
				{#if isAuto}<IconCheck size={12} />{/if}
			</button>
			<button
				type="button"
				role="tab"
				aria-selected={!isAuto}
				class="tz-mode-btn"
				class:is-active={!isAuto}
				onclick={() => {
					// Moving out of auto: pin to whatever is currently effective so
					// the UI doesn't silently drift if the browser zone changes.
					if (isAuto) setTimezonePreference($effectiveTimezone);
					pickerOpen = true;
				}}
			>
				<IconClock size={13} />
				<span>{$t('timezone.modeManual')}</span>
				{#if !isAuto}<IconCheck size={12} />{/if}
			</button>
		</div>
	</header>

	<!-- Instrument display: live clock + zone plate -->
	<div class="tz-instrument">
		<div class="tz-instrument__clock" aria-live="off">
			<span class="tz-digit-group">{clockReading}</span>
			<span class="tz-instrument__offset">{currentOffset}</span>
		</div>

		<button
			type="button"
			class="tz-instrument__zone"
			onclick={() => { pickerOpen = true; }}
			aria-label={$t('timezone.changeZone')}
		>
			<span class="tz-instrument__zone-label">{$t('timezone.activeZone')}</span>
			<span class="tz-instrument__zone-value">
				<IconGlobe size={14} />
				<span>{currentZoneLabel}</span>
				{#if isAuto}
					<span class="tz-auto-badge">{$t('timezone.autoBadge')}</span>
				{/if}
			</span>
			<span class="tz-instrument__zone-hint">{$t('timezone.clickToChange')}</span>
		</button>
	</div>

	<!-- Preview — "this is how dates will render across the app" -->
	<div class="tz-preview">
		<div class="tz-preview__row">
			<span class="tz-preview__label">{$t('timezone.previewFull')}</span>
			<code class="tz-preview__value">{previewNow}</code>
		</div>
		<div class="tz-preview__row">
			<span class="tz-preview__label">{$t('timezone.previewDate')}</span>
			<code class="tz-preview__value">{previewDate}</code>
		</div>
		<p class="tz-preview__hint">{$t('timezone.previewHint')}</p>
	</div>
</section>

<EntityPicker
	bind:open={pickerOpen}
	items={pickerItems}
	current={$timezonePreference}
	title={$t('timezone.pickerTitle')}
	placeholder={$t('timezone.pickerPlaceholder')}
	onselect={handleSelect}
	onclose={() => { pickerOpen = false; }}
/>

<style>
	.tz-card {
		position: relative;
		display: flex;
		flex-direction: column;
		gap: var(--space-4);
		padding: var(--space-5);
		border: 1px solid var(--border-primary);
		border-radius: var(--radius-xl);
		background:
			radial-gradient(120% 60% at 100% 0%, color-mix(in srgb, var(--color-brand-500) 6%, transparent) 0%, transparent 60%),
			var(--surface-card);
		overflow: hidden;
	}

	.tz-card::before {
		/* Subtle tick-mark texture along the top edge — evokes a chronometer bezel. */
		content: '';
		position: absolute;
		inset: 0 0 auto 0;
		height: 8px;
		background-image: repeating-linear-gradient(
			to right,
			color-mix(in srgb, var(--color-brand-500) 30%, transparent) 0 1px,
			transparent 1px 10px
		);
		opacity: 0.55;
		pointer-events: none;
	}

	.tz-card__head {
		display: flex;
		align-items: flex-start;
		justify-content: space-between;
		gap: var(--space-4);
		flex-wrap: wrap;
	}

	.tz-card__title-group {
		display: flex;
		flex-direction: column;
		gap: 2px;
		min-width: 0;
	}

	.tz-card__eyebrow {
		display: inline-flex;
		align-items: center;
		gap: 6px;
		font-size: 10px;
		font-weight: 700;
		letter-spacing: 0.18em;
		text-transform: uppercase;
		color: var(--color-brand-600);
	}
	:global([data-theme='dark']) .tz-card__eyebrow {
		color: var(--color-brand-300);
	}

	.tz-card__title {
		margin: 0;
		font-size: var(--text-lg);
		font-weight: 600;
		color: var(--text-primary);
	}

	.tz-card__subtitle {
		margin: 0;
		font-size: var(--text-xs);
		color: var(--text-tertiary);
		max-width: 42ch;
	}

	.tz-card__mode {
		display: inline-flex;
		align-items: center;
		gap: 2px;
		padding: 3px;
		border-radius: var(--radius-lg, 10px);
		background: var(--surface-card-hover);
		border: 1px solid var(--border-primary);
	}

	.tz-mode-btn {
		display: inline-flex;
		align-items: center;
		gap: 6px;
		padding: 6px 10px;
		border: none;
		border-radius: 7px;
		background: transparent;
		color: var(--text-tertiary);
		font-size: 11px;
		font-weight: 600;
		letter-spacing: 0.04em;
		cursor: pointer;
		transition: background var(--transition-fast), color var(--transition-fast), box-shadow var(--transition-fast);
	}

	.tz-mode-btn:hover {
		color: var(--text-primary);
	}

	.tz-mode-btn.is-active {
		background: var(--surface-card);
		color: var(--color-brand-700);
		box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08);
	}
	:global([data-theme='dark']) .tz-mode-btn.is-active {
		color: var(--color-brand-300);
		box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
	}

	/* ── Instrument display ────────────────────────────────────────────── */
	.tz-instrument {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
		gap: var(--space-4);
		padding: var(--space-4) var(--space-5);
		border-radius: var(--radius-lg, 12px);
		border: 1px solid var(--border-primary);
		background:
			linear-gradient(135deg, color-mix(in srgb, var(--color-brand-500) 4%, transparent), transparent 60%),
			var(--surface-card-hover);
	}

	@media (max-width: 640px) {
		.tz-instrument { grid-template-columns: 1fr; }
	}

	.tz-instrument__clock {
		display: flex;
		flex-direction: column;
		gap: 6px;
		justify-content: center;
	}

	.tz-digit-group {
		font-family: var(--font-family-mono);
		font-variant-numeric: tabular-nums;
		font-weight: 600;
		font-size: clamp(1.8rem, 2.6vw + 1rem, 2.6rem);
		line-height: 1;
		color: var(--text-primary);
		letter-spacing: 0.02em;
		text-shadow: 0 1px 0 color-mix(in srgb, var(--color-brand-500) 8%, transparent);
	}

	.tz-instrument__offset {
		display: inline-flex;
		align-items: center;
		width: fit-content;
		padding: 2px 8px;
		font-family: var(--font-family-mono);
		font-size: 10px;
		font-weight: 700;
		letter-spacing: 0.08em;
		color: var(--color-brand-700);
		background: color-mix(in srgb, var(--color-brand-500) 12%, transparent);
		border: 1px solid color-mix(in srgb, var(--color-brand-500) 24%, transparent);
		border-radius: 999px;
	}
	:global([data-theme='dark']) .tz-instrument__offset { color: var(--color-brand-200); }

	.tz-instrument__zone {
		all: unset;
		cursor: pointer;
		display: flex;
		flex-direction: column;
		justify-content: center;
		gap: 4px;
		padding: var(--space-3);
		border-radius: var(--radius-md, 8px);
		border: 1px dashed color-mix(in srgb, var(--color-brand-500) 28%, transparent);
		background: var(--surface-card);
		transition: border-color var(--transition-fast), transform var(--transition-fast);
	}

	.tz-instrument__zone:hover {
		border-color: var(--color-brand-500);
		transform: translateY(-1px);
	}

	.tz-instrument__zone:focus-visible {
		outline: 2px solid var(--color-brand-500);
		outline-offset: 2px;
	}

	.tz-instrument__zone-label {
		font-size: 10px;
		font-weight: 700;
		letter-spacing: 0.14em;
		text-transform: uppercase;
		color: var(--text-tertiary);
	}

	.tz-instrument__zone-value {
		display: inline-flex;
		align-items: center;
		gap: 8px;
		font-family: var(--font-family-mono);
		font-size: var(--text-sm);
		font-weight: 600;
		color: var(--text-primary);
		word-break: break-all;
	}

	.tz-auto-badge {
		display: inline-flex;
		align-items: center;
		padding: 1px 6px;
		font-family: var(--font-family-sans);
		font-size: 9px;
		font-weight: 700;
		letter-spacing: 0.14em;
		text-transform: uppercase;
		color: var(--color-success-dark);
		background: var(--color-success-light);
		border-radius: 999px;
	}
	:global([data-theme='dark']) .tz-auto-badge {
		color: #86efac;
		background: color-mix(in srgb, var(--color-success) 18%, transparent);
	}

	.tz-instrument__zone-hint {
		font-size: 11px;
		color: var(--text-tertiary);
	}

	/* ── Preview rows ──────────────────────────────────────────────────── */
	.tz-preview {
		display: flex;
		flex-direction: column;
		gap: 6px;
		padding: var(--space-3) var(--space-4);
		background: var(--surface-page);
		border: 1px solid var(--border-secondary);
		border-radius: var(--radius-md, 8px);
	}

	.tz-preview__row {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--space-3);
	}

	.tz-preview__label {
		font-size: 10px;
		font-weight: 700;
		letter-spacing: 0.12em;
		text-transform: uppercase;
		color: var(--text-tertiary);
	}

	.tz-preview__value {
		font-family: var(--font-family-mono);
		font-variant-numeric: tabular-nums;
		font-size: var(--text-xs);
		color: var(--text-secondary);
		background: transparent;
		padding: 0;
	}

	.tz-preview__hint {
		margin: 2px 0 0;
		font-size: 11px;
		color: var(--text-tertiary);
	}
</style>
