<script lang="ts">
	import EmptyDayTile from './EmptyDayTile.svelte';
	import { formatDayAbbr } from '$lib/planner/week';
	import type { Recipe, Slot, Suggestion } from '$lib/planner/types';
	import { sanitizeForCssUrl } from '$lib/planner/DesktopDayTile.utils';

	let {
		slot,
		isToday,
		activeSlotId,
		isPlanner,
		slotMap,
		suggestions,
		topSuggestion,
		onflip,
		onclose,
		onswap,
		onremove,
		onaddrecipe
	}: {
		slot: Slot;
		isToday: boolean;
		activeSlotId: string | null;
		isPlanner: boolean;
		slotMap: Record<string, any>;
		suggestions: Suggestion[];
		topSuggestion?: Suggestion;
		onflip?: (slotId: string) => void;
		onclose?: () => void;
		onswap?: () => void;
		onremove?: () => void;
		onaddrecipe?: () => void;
	} = $props();

	const slotId = $derived(slot.id ?? '');
	const isFlipped = $derived(activeSlotId === slot.id && !!slot.recipe);
	const isDimmed = $derived(activeSlotId !== null && activeSlotId !== slot.id && !!slot.recipe);

	const dayAbbr = $derived(slot.slotDate ? formatDayAbbr(slot.slotDate, 'short') : '');
	const dateNum = $derived(slot.slotDate ? slot.slotDate.slice(-2).replace(/^0/, '') : '');

	const visibleTags = $derived(
		(slot.recipe?.tags ?? []).filter((t) => t.tagType === 'protein' || t.tagType === 'cuisine')
	);

	const metaLine = $derived((() => {
		const parts: string[] = [];
		if (slot.recipe?.cookTimeMin) parts.push(`${slot.recipe.cookTimeMin} Min`);
		if (slot.recipe?.effort) parts.push(slot.recipe.effort);
		return parts.join(' · ');
	})());

	function handleFlip() {
		onflip?.(slotId);
	}

	function handleKeydown(e: KeyboardEvent) {
		if (e.key === 'Enter' || e.key === ' ') {
			e.preventDefault();
			onflip?.(slotId);
		}
	}

	const umlautMap: Record<string, string> = { ä: 'ae', ö: 'oe', ü: 'ue', ß: 'ss' };
	function toCssKey(name: string): string {
		return name.toLowerCase().replace(/[äöüß]/g, (c) => umlautMap[c] ?? c);
	}

	const gradientBackground = $derived((() => {
		if (!slot.recipe) return 'var(--color-surface)';
		if (slot.recipe.heroImageUrl) return `url("${sanitizeForCssUrl(slot.recipe.heroImageUrl)}")`;
		const proteinTag = slot.recipe.tags?.find((t) => t.tagType === 'protein');
		if (proteinTag?.name) {
			return `var(--gradient-protein-${toCssKey(proteinTag.name)})`;
		}
		const cuisineTag = slot.recipe.tags?.find((t) => t.tagType === 'cuisine');
		if (cuisineTag?.name) {
			return `var(--gradient-cuisine-${toCssKey(cuisineTag.name)})`;
		}
		return 'var(--color-surface)';
	})());
</script>

{#if slot.recipe}
	<div
		data-testid="day-meal-card-{slot.slotDate ?? ''}"
		role="button"
		tabindex="0"
		aria-label={slot.recipe?.name ?? 'Gericht'}
		aria-expanded={isFlipped}
		data-today={isToday}
		data-flipped={isFlipped}
		data-dimmed={isDimmed}
		class="scene"
		class:scene-today={isToday && !isFlipped}
		class:scene-selected={isFlipped}
		class:scene-dimmed={isDimmed}
		onclick={handleFlip}
		onkeydown={handleKeydown}
	>
			<!-- FRONT -->
			<div class="card-front" class:flipped={isFlipped}>
				<div
					class="card-front-inner"
					style="background: {gradientBackground}; background-size: cover; background-position: center;"
				>
				<!-- Full-tile dual gradient overlay -->
				<div class="tile-overlay"></div>

				<!-- Day header -->
				<div class="tile-head">
					<span class="tile-day-abbr">{dayAbbr}</span>
					<span class="tile-day-num" class:dn-today={isToday} class:dn-selected={isFlipped}>
						{dateNum}
					</span>
				</div>

				<!-- Recipe info at bottom -->
				<div class="tile-info">
					<p class="tile-name">{slot.recipe.name}</p>
					{#if metaLine}
						<p class="tile-meta">{metaLine}</p>
					{/if}
					{#if visibleTags.length > 0}
						<div class="tile-tags">
							{#each visibleTags as tag (tag.id)}
								<span class="tile-tag" class:tag-today={isToday} class:tag-selected={isFlipped}>
									{tag.name}
								</span>
							{/each}
						</div>
					{/if}
				</div>
				</div> <!-- /.card-front-inner -->
			</div>

			<!-- BACK -->
			<div class="card-back" class:flipped={isFlipped} aria-hidden={!isFlipped}>
			<div class="card-back-inner">
				<button
					type="button"
					aria-label="Schließen"
					class="btn-close"
					onclick={(e) => { e.stopPropagation(); onclose?.(); }}
				>
					×
				</button>

				<p class="back-name">{slot.recipe.name}</p>
				{#if metaLine}
					<p class="back-meta">{metaLine}</p>
				{/if}

				<div class="back-actions">
					<a class="btn-action btn-primary" href="/recipes/{slot.recipe.id}/cook" onclick={(e) => e.stopPropagation()}>Koch-Modus</a>
					<a class="btn-action" href="/recipes/{slot.recipe.id}" onclick={(e) => e.stopPropagation()}>Rezept ansehen</a>

					{#if isPlanner}
						<button
							type="button"
							class="btn-action"
							onclick={(e) => { e.stopPropagation(); onswap?.(); }}
						>
							Gericht tauschen
						</button>

						{#if slot.id}
							<button
								type="button"
								class="btn-action btn-danger"
								onclick={(e) => { e.stopPropagation(); onremove?.(); }}
							>
								Entfernen
							</button>
						{/if}
					{/if}
				</div>
			</div> <!-- /.card-back-inner -->
			</div>

	</div>
{:else}
	<EmptyDayTile
		slotDate={slot.slotDate ?? ''}
		slotId={slot.id ?? ''}
		{isPlanner}
		{slotMap}
		{topSuggestion}
		{onaddrecipe}
	/>
{/if}

<style>
	/* ── Scene (outermost positioned element) ── */
	.scene {
		perspective: 900px;
		height: 100%;
		width: 100%;
		cursor: pointer;
		border-radius: var(--radius-lg);
		box-shadow: 0 1px 3px rgba(28,28,24,.06), 0 1px 2px rgba(28,28,24,.04);
		transition: box-shadow .15s, opacity .15s;
	}
	.scene:hover {
		box-shadow: 0 6px 18px rgba(28,28,24,.14), 0 2px 6px rgba(28,28,24,.08);
	}
	.scene-today {
		box-shadow: 0 0 0 2px var(--color-ring-today), 0 1px 3px rgba(28,28,24,.06);
	}
	.scene-today:hover {
		box-shadow: 0 0 0 2px var(--color-ring-today), 0 6px 18px rgba(28,28,24,.14);
	}
	.scene-selected {
		box-shadow: 0 0 0 2px var(--green-dark), 0 6px 18px rgba(28,28,24,.14);
	}
	/* Keep ring visible on hover — :hover alone has higher specificity than .scene-selected */
	.scene-selected:hover {
		box-shadow: 0 0 0 2px var(--green-dark), 0 6px 18px rgba(28,28,24,.14);
	}
	.scene-dimmed {
		opacity: var(--opacity-dimmed);
		pointer-events: none;
	}

	/* ── Card flip — independent face transforms, no preserve-3d ──
	   preserve-3d + box-shadow/transition on parent causes Chrome to
	   fail backface-visibility:hidden. Rotating each face independently
	   avoids the 3D context entirely. */
	.card-front,
	.card-back {
		position: absolute;
		inset: 0;
		backface-visibility: hidden;
		-webkit-backface-visibility: hidden;
		transition: transform 0.45s cubic-bezier(0.4, 0, 0.2, 1);
		will-change: transform;
	}
	.card-front { transform: rotateY(0deg); }
	.card-front.flipped { transform: rotateY(-180deg); }
	.card-back { transform: rotateY(180deg); pointer-events: none; }
	.card-back.flipped { transform: rotateY(0deg); pointer-events: auto; }
	.card-front.flipped { pointer-events: none; }
	.card-front-inner {
		position: absolute;
		inset: 0;
		border-radius: var(--radius-lg);
		overflow: hidden;
	}

	/* ── Front face ── */
	.tile-overlay {
		position: absolute;
		inset: 0;
		background: linear-gradient(
			to bottom,
			rgba(0,0,0,.32) 0%,
			rgba(0,0,0,0)   30%,
			rgba(0,0,0,0)   45%,
			rgba(0,0,0,.55) 100%
		);
		border-radius: inherit;
	}
	.tile-head {
		position: absolute;
		top: 0; left: 0; right: 0;
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 7px 8px;
		z-index: 2;
	}
	.tile-day-abbr {
		font-size: 13px;
		text-transform: uppercase;
		letter-spacing: .06em;
		color: rgba(255,255,255,.85);
		font-weight: 500;
	}
	.tile-day-num {
		width: 20px; height: 20px;
		border-radius: 9999px;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 14px;
		font-weight: 500;
		color: rgba(255,255,255,.9);
		background: rgba(255,255,255,.22);
	}
	.dn-today {
		background: var(--color-ring-today) !important;
		color: #fff !important;
	}
	.dn-selected {
		background: var(--green-dark) !important;
		color: #fff !important;
	}
	.tile-info {
		position: absolute;
		bottom: 0; left: 0; right: 0;
		padding: 8px 9px 9px;
		z-index: 2;
	}
	.tile-name {
		font-size: 19px;
		font-weight: 300;
		color: #fff;
		line-height: 1.3;
		margin: 0;
		text-shadow: 0 1px 3px rgba(0,0,0,.4);
	}
	.tile-meta {
		font-size: 14px;
		color: rgba(255,255,255,.75);
		margin: 2px 0 0;
	}
	.tile-tags {
		display: flex;
		gap: 3px;
		flex-wrap: wrap;
		margin-top: 5px;
	}
	.tile-tag {
		font-size: 12px;
		font-weight: 500;
		padding: 2px 5px;
		border-radius: 2px;
		background: rgba(255,255,255,.2);
		color: rgba(255,255,255,.92);
		backdrop-filter: blur(2px);
	}
	.tag-today { background: rgba(242,193,46,.35); }
	.tag-selected { background: rgba(46,110,57,.45); }

	/* ── Back face ── */
	.card-back-inner {
		position: absolute;
		inset: 0;
		border-radius: var(--radius-lg);
		overflow-y: auto;
		background: var(--color-page);
		border: 1px solid var(--color-border);
		padding: 10px;
		display: flex;
		flex-direction: column;
	}
	.btn-close {
		background: none;
		border: none;
		cursor: pointer;
		font-size: 18px;
		line-height: 1;
		color: var(--color-text-muted);
		padding: 2px 6px;
		align-self: flex-end;
		margin: -4px -4px 2px 0;
	}
	.btn-close:hover { color: var(--color-text); }
	.back-name {
		font-family: var(--font-display);
		font-size: 13px;
		font-weight: 300;
		margin: 0 0 2px;
		line-height: 1.3;
		color: var(--color-text);
	}
	.back-meta {
		font-size: 10px;
		color: var(--color-text-muted);
		margin: 0 0 10px;
	}
	.back-actions {
		display: flex;
		flex-direction: column;
		gap: 5px;
		margin-top: auto;
	}
	.btn-action {
		display: block;
		width: 100%;
		padding: 7px;
		border-radius: 6px;
		border: 1px solid var(--color-border);
		background: #fff;
		color: var(--color-text);
		font-size: 11px;
		font-weight: 500;
		letter-spacing: .04em;
		text-align: center;
		text-decoration: none;
		cursor: pointer;
		box-sizing: border-box;
	}
	.btn-action:hover { background: var(--color-surface); }
	.btn-primary {
		background: var(--green-dark);
		color: #fff;
		border: none;
	}
	.btn-primary:hover { background: var(--green-dark); filter: brightness(1.1); }
	.btn-danger {
		color: #dc4c3e;
		border-color: #dc4c3e;
		background: transparent;
	}
	.btn-danger:hover { background: rgba(220,76,62,.08); }

	@media (prefers-reduced-motion: reduce) {
		.card-front, .card-back { transition: none; }
		.scene { transition: none; }
	}
</style>
