<script lang="ts">
	import type { QueueItem } from '$lib/server/queue/types';
	import Chip from './Chip.svelte';
	import Close from './ic/Close.svelte';
	import Check from './ic/Check.svelte';
	import Retry from './ic/Retry.svelte';
	import Link from './ic/Link.svelte';
	import External from './ic/External.svelte';
	import PhasePrepping from './ic/PhasePrepping.svelte';
	import PhaseSimmering from './ic/PhaseSimmering.svelte';
	import PhasePlating from './ic/PhasePlating.svelte';

	interface Props {
		item: QueueItem | null;
		onClose?: () => void;
		onRetry?: (id: string) => void;
	}
	let { item, onClose, onRetry }: Props = $props();

	const PALETTE = ['#E1306C', '#FD7E14', '#FCAF45', '#833AB4', '#C13584'];
	function strHash(s: string): number {
		let h = 0;
		for (let i = 0; i < s.length; i++) h = (Math.imul(31, h) + s.charCodeAt(i)) | 0;
		return Math.abs(h);
	}
	function swatch(id: string): [string, string] {
		const h = strHash(id);
		return [PALETTE[h % PALETTE.length], PALETTE[(h + 2) % PALETTE.length]];
	}

	const isSuccess = $derived(item?.status === 'success');
	const isError = $derived(item?.status === 'error' || item?.status === 'unhealthy');
	const isCooking = $derived(item?.status === 'in_progress');
	const isPending = $derived(item?.status === 'pending');

	const recipe = $derived(item?.recipe ?? item?.results?.recipe);
	const sw = $derived(item ? swatch(item.id) : (['#E1306C', '#FD7E14'] as [string, string]));

	function statusLabel(item: QueueItem): string {
		if (item.status === 'success') return 'Saved';
		if (item.status === 'error' || item.status === 'unhealthy') return 'Failed';
		if (item.status === 'in_progress') {
			const m: Record<string, string> = { extraction: 'Prepping', parsing: 'Simmering', uploading: 'Plating' };
			return m[item.currentPhase ?? 'extraction'] ?? 'Cooking';
		}
		return 'Pending';
	}

	function username(url: string) {
		const m = url.match(/instagram\.com\/([^/?#]+)/);
		return m ? '@' + m[1] : '@instagram';
	}

	const phases = [
		{ name: 'extraction', label: 'Prepping', desc: 'Grabbing post + media', Icon: PhasePrepping },
		{ name: 'parsing', label: 'Simmering', desc: 'LLM reads the caption', Icon: PhaseSimmering },
		{ name: 'uploading', label: 'Plating', desc: 'Saving to Tandoor', Icon: PhasePlating }
	];
</script>

{#if item}
	<!-- svelte-ignore a11y_click_events_have_key_events -->
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="overlay ic-fade" onclick={onClose} role="dialog" aria-modal="true">
		<div class="sheet ic-slide-up" onclick={(e) => e.stopPropagation()}>
			<!-- Handle -->
			<div class="handle-row">
				<div class="handle"></div>
			</div>

			<!-- Cover -->
			<div class="cover" style="background: linear-gradient(135deg, {sw[0]} 0%, {sw[1]} 100%)">
				<div class="cover-ring outer-ring"></div>
				<div class="cover-ring inner-ring"></div>

				<div class="cover-top">
					<Chip color="#fff" bg="rgba(255,255,255,0.22)" mono>
						{statusLabel(item).toUpperCase()}
					</Chip>
					<button class="ic-btn-reset close-btn" onclick={onClose} aria-label="Close">
						<Close size={16} color="#fff" />
					</button>
				</div>

				<h2 class="ic-display cover-title">
					{recipe?.name || (isPending ? 'Waiting in line' : isCooking ? statusLabel(item) + '…' : 'Untitled')}
				</h2>
				{#if recipe?.servings}
					<div class="cover-meta">Serves {recipe.servings} · from {username(item.url)}</div>
				{/if}
			</div>

			<!-- Body -->
			<div class="body">
				<!-- Keywords -->
				{#if recipe?.keywords?.length > 0}
					<div class="tags-row">
						{#each recipe.keywords as kw}
							<Chip bg="var(--surface-2)" color="var(--ink-2)" mono>#{kw}</Chip>
						{/each}
					</div>
				{/if}

				<!-- Phase progress (cooking) -->
				{#if isCooking}
					<div class="phase-card">
						<div class="phase-card-label">3-phase progress</div>
						{#each phases as p, i}
							{@const ph = item.phases.find((x) => x.name === p.name) || { status: 'pending' }}
							{@const done = ph.status === 'completed'}
							{@const active = ph.status === 'in_progress'}
							<div class="phase-row" style="opacity: {done || active ? 1 : 0.4}">
								<div class="phase-icon-wrap" class:phase-active={active}>
									<p.Icon size={32} animate={active} />
									{#if done}
										<div class="phase-done-badge">
											<Check size={10} strokeWidth={3.5} color="#fff" />
										</div>
									{/if}
								</div>
								<div class="phase-text">
									<div class="phase-title">{p.label}</div>
									<div class="phase-desc">{p.desc}</div>
								</div>
								{#if active}
									<span class="running-tag ic-pulse">RUNNING</span>
								{/if}
							</div>
						{/each}
					</div>
				{/if}

				<!-- Error detail -->
				{#if isError && item.error}
					<div class="error-card">
						<div class="error-title">
							<span class="error-badge">!</span>
							Failed during {item.error.phase}
						</div>
						<div class="error-msg">{item.error.message}</div>
						<button class="ic-btn-reset retry-btn" onclick={() => onRetry?.(item!.id)}>
							<Retry size={14} color="var(--status-error)" /> Try again
						</button>
					</div>
				{/if}

				<!-- Source URL -->
				<div class="source-card">
					<div class="source-icon">
						<Link size={16} color="#fff" />
					</div>
					<div class="source-info">
						<div class="source-label">SOURCE</div>
						<div class="source-url">{item.url}</div>
					</div>
				</div>

				<!-- Open in Tandoor -->
				{#if isSuccess && (item.results?.tandoorUrl ?? item.tandoorRecipeId)}
					{@const tandoorUrl =
						item.results?.tandoorUrl ??
						`/api/v1/recipe/${item.results?.tandoorRecipeId ?? item.tandoorRecipeId}/`}
					<a href={tandoorUrl} target="_blank" rel="noopener" class="ic-btn-reset tandoor-btn">
						Open in Tandoor <External size={16} color="#fff" />
					</a>
				{/if}
			</div>
		</div>
	</div>
{/if}

<style>
	.overlay {
		position: fixed;
		inset: 0;
		z-index: 60;
		display: flex;
		align-items: flex-end;
		background: rgba(0, 0, 0, 0.42);
	}
	.sheet {
		background: var(--bg);
		width: 100%;
		border-radius: 32px 32px 0 0;
		max-height: 94vh;
		overflow-y: auto;
		box-shadow: 0 -20px 60px rgba(0, 0, 0, 0.3);
		overscroll-behavior: contain;
	}
	.handle-row {
		display: flex;
		justify-content: center;
		padding: 10px 0 4px;
	}
	.handle {
		width: 44px;
		height: 5px;
		border-radius: 99px;
		background: var(--border-strong);
	}
	.cover {
		margin: 8px 16px 0;
		border-radius: 24px;
		padding: 24px 22px;
		position: relative;
		overflow: hidden;
		color: #fff;
		min-height: 180px;
	}
	.cover-ring {
		position: absolute;
		border-radius: 50%;
		pointer-events: none;
	}
	.outer-ring {
		right: -60px;
		bottom: -60px;
		width: 220px;
		height: 220px;
		border: 2px solid rgba(255, 255, 255, 0.25);
	}
	.inner-ring {
		right: -30px;
		bottom: -30px;
		width: 160px;
		height: 160px;
		background: rgba(255, 255, 255, 0.12);
	}
	.cover-top {
		display: flex;
		justify-content: space-between;
		align-items: flex-start;
		margin-bottom: 80px;
		position: relative;
	}
	.close-btn {
		width: 32px;
		height: 32px;
		border-radius: 99px;
		background: rgba(255, 255, 255, 0.22);
		display: flex;
		align-items: center;
		justify-content: center;
	}
	.cover-title {
		font-size: 32px;
		line-height: 1;
		margin: 0;
		letter-spacing: -0.01em;
		position: relative;
		text-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
	}
	.cover-meta {
		margin-top: 14px;
		font-size: 13px;
		font-family: var(--font-mono);
		opacity: 0.92;
		position: relative;
	}
	.body {
		padding: 22px 22px 44px;
	}
	.tags-row {
		display: flex;
		flex-wrap: wrap;
		gap: 6px;
		margin-bottom: 20px;
	}
	.phase-card {
		border-radius: 20px;
		padding: 18px;
		margin-bottom: 16px;
		background: var(--surface);
		border: 1px solid var(--border);
	}
	.phase-card-label {
		font-size: 11px;
		font-family: var(--font-mono);
		font-weight: 700;
		color: var(--muted);
		letter-spacing: 1.2px;
		text-transform: uppercase;
		margin-bottom: 14px;
	}
	.phase-row {
		display: flex;
		align-items: center;
		gap: 14px;
		padding: 8px 0;
		transition: opacity 0.3s;
	}
	.phase-icon-wrap {
		width: 44px;
		height: 44px;
		border-radius: 14px;
		background: var(--surface-2);
		display: flex;
		align-items: center;
		justify-content: center;
		position: relative;
		flex-shrink: 0;
	}
	.phase-active {
		background: var(--bg-tint);
	}
	.phase-done-badge {
		position: absolute;
		bottom: -2px;
		right: -2px;
		width: 18px;
		height: 18px;
		border-radius: 99px;
		background: var(--status-success);
		display: flex;
		align-items: center;
		justify-content: center;
		border: 2px solid var(--surface);
	}
	.phase-title {
		font-weight: 700;
		font-size: 14px;
		font-family: 'Lilita One', system-ui, sans-serif;
		color: var(--ink);
	}
	.phase-desc {
		font-size: 12px;
		color: var(--muted);
	}
	.running-tag {
		font-size: 10px;
		font-family: var(--font-mono);
		font-weight: 700;
		color: var(--pink);
		letter-spacing: 0.6px;
	}
	.error-card {
		border-radius: 20px;
		padding: 18px;
		background: #ffe9e9;
		border: 1px solid #f8c2c2;
		color: #7e1717;
		margin-bottom: 16px;
	}
	.error-title {
		font-weight: 700;
		font-size: 14px;
		margin-bottom: 6px;
		display: flex;
		align-items: center;
		gap: 6px;
	}
	.error-badge {
		width: 20px;
		height: 20px;
		border-radius: 99px;
		background: var(--status-error);
		color: #fff;
		display: inline-flex;
		align-items: center;
		justify-content: center;
		font-weight: 800;
		font-size: 13px;
	}
	.error-msg {
		font-size: 13px;
		line-height: 1.4;
	}
	.retry-btn {
		margin-top: 14px;
		padding: 10px 16px;
		border-radius: 99px;
		background: #fff;
		color: var(--status-error);
		font-weight: 700;
		font-size: 13px;
		display: inline-flex;
		align-items: center;
		gap: 6px;
		border: 1px solid #f8c2c2;
	}
	.source-card {
		border-radius: 20px;
		padding: 14px 16px;
		background: var(--surface);
		border: 1px solid var(--border);
		display: flex;
		align-items: center;
		gap: 10px;
		margin-bottom: 14px;
	}
	.source-icon {
		width: 36px;
		height: 36px;
		border-radius: 12px;
		background: var(--brand-gradient);
		display: flex;
		align-items: center;
		justify-content: center;
		flex-shrink: 0;
	}
	.source-info {
		flex: 1;
		min-width: 0;
	}
	.source-label {
		font-size: 11px;
		color: var(--muted);
		font-family: var(--font-mono);
		font-weight: 600;
		margin-bottom: 2px;
	}
	.source-url {
		font-size: 13px;
		font-family: var(--font-mono);
		color: var(--ink-2);
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
	.tandoor-btn {
		width: 100%;
		padding: 16px;
		background: var(--brand-gradient);
		color: #fff;
		border-radius: 99px;
		font-weight: 700;
		font-size: 14px;
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 8px;
		box-shadow: var(--shadow-lg);
		text-decoration: none;
	}
</style>
