<script lang="ts">
	import { page } from '$app/state';
	import { onMount } from 'svelte';
	import {
		BookOpen,
		Brain,
		CalendarDays,
		CircleDot,
		Compass,
		Download,
		Dumbbell,
		Headphones,
		Landmark,
		LibraryBig,
		Menu,
		Package2,
		MessageSquare,
		Search,
		Settings2,
		SquareCheckBig,
		Upload,
		X
	} from '@lucide/svelte';

	interface Props {
		children: any;
		userName?: string;
		visibleApps?: string[];
		onOpenCommand?: () => void;
	}

	let {
		children,
		userName = '',
		visibleApps = ['tasks', 'trips', 'fitness', 'inventory', 'budget', 'reader', 'media'],
		onOpenCommand
	}: Props = $props();

	const baseItems = [
		{ id: 'dashboard', href: '/', label: 'Overview', icon: CircleDot },
		{ id: 'tasks', href: '/tasks', label: 'Tasks', icon: SquareCheckBig },
		{ id: 'trips', href: '/trips', label: 'Trips', icon: Compass },
		{ id: 'fitness', href: '/fitness', label: 'Fitness', icon: Dumbbell },
		{ id: 'budget', href: '/budget', label: 'Budget', icon: Landmark },
		{ id: 'inventory', href: '/inventory', label: 'Inventory', icon: Package2 },
		{ id: 'reader', href: '/reader', label: 'Reader', icon: BookOpen },
		{ id: 'media', href: '/podcasts', label: 'Podcasts', icon: Headphones },
		{ id: 'downloads', href: '/downloads', label: 'Downloads', icon: Download },
		{ id: 'brain', href: '/brain', label: 'Brain', icon: Brain },
		{ id: 'settings', href: '/settings', label: 'Settings', icon: Settings2 }
	];

	const navItems = $derived(
		baseItems.filter((item) => item.id === 'dashboard' || item.id === 'settings' || visibleApps.includes(item.id))
	);

	let mobileNavOpen = $state(false);
	let uploadInput: HTMLInputElement;
	let feedbackOpen = $state(false);
	let feedbackText = $state('');
	let feedbackSending = $state(false);
	let feedbackSent = $state(false);

	async function sendFeedback() {
		if (!feedbackText.trim()) return;
		feedbackSending = true;
		try {
			const res = await fetch('/api/feedback', {
				method: 'POST',
				credentials: 'include',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ text: feedbackText.trim(), source: 'web' }),
			});
			if (res.ok) {
				feedbackSent = true;
				setTimeout(() => { feedbackOpen = false; feedbackSent = false; feedbackText = ''; }, 1500);
			}
		} catch {}
		feedbackSending = false;
	}
	let uploadStatus = $state<'' | 'uploading' | 'done'>('');

	async function handleUpload(file: File) {
		uploadStatus = 'uploading';
		const fd = new FormData();
		fd.append('file', file);
		try {
			const res = await fetch('/upload', { method: 'POST', body: fd, credentials: 'include' });
			const data = await res.json();
			console.log('Upload result:', data);
			uploadStatus = data.ok ? 'done' : '';
			if (data.ok) setTimeout(() => uploadStatus = '', 2000);
		} catch (e) {
			console.error('Upload error:', e);
			uploadStatus = '';
		}
	}

	function onUploadInput(e: Event) {
		const input = e.target as HTMLInputElement;
		if (input.files?.[0]) handleUpload(input.files[0]);
		input.value = '';
	}

	function onRailDrop(e: DragEvent) {
		e.preventDefault();
		const file = e.dataTransfer?.files[0];
		if (file) handleUpload(file);
	}

	function onPasteBox(e: ClipboardEvent) {
		const items = e.clipboardData?.items;
		if (!items) return;
		for (const item of items) {
			if (item.type.startsWith('image/')) {
				const file = item.getAsFile();
				if (file) {
					e.preventDefault();
					handleUpload(file);
				}
				break;
			}
		}
	}

	// Brain sidebar sub-items
	interface BrainFolder { id: string; name: string; item_count: number; }
	interface BrainTag { id: string; name: string; item_count: number; }
	let brainFolders = $state<BrainFolder[]>([]);
	let brainTags = $state<BrainTag[]>([]);
	let brainSubView = $state<'folders' | 'tags'>('folders');
	let brainExpanded = $derived(page.url.pathname.startsWith('/brain'));

	async function loadBrainSidebar() {
		try {
			const res = await fetch('/api/brain/taxonomy/sidebar', { credentials: 'include' });
			if (res.ok) {
				const data = await res.json();
				brainFolders = data.folders || [];
				brainTags = data.tags || [];
			}
		} catch { /* silent */ }
	}

	onMount(() => {
		if (brainExpanded) loadBrainSidebar();
	});

	$effect(() => {
		if (brainExpanded) loadBrainSidebar();
	});

	function isActive(href: string): boolean {
		if (href === '/') return page.url.pathname === '/';
		return page.url.pathname === href || page.url.pathname.startsWith(href + '/');
	}
</script>

<div class="shell">
	<div class="shell-glow shell-glow-a"></div>
	<div class="shell-glow shell-glow-b"></div>

	<aside class="shell-rail reveal">
		<div class="rail-top">
			<a class="brand" href="/">
				<div class="brand-mark">P</div>
				<div>
					<div class="brand-name">Platform</div>
					<div class="brand-sub">ops workspace</div>
				</div>
			</a>

			<button class="command-trigger" onclick={onOpenCommand}>
				<Search size={15} strokeWidth={1.8} />
				<span>Assistant</span>
				<kbd>Ctrl K</kbd>
			</button>

			<nav class="rail-nav">
				{#each navItems as item}
					<a href={item.href} class:active={isActive(item.href)}>
						<item.icon size={16} strokeWidth={1.8} />
						<span>{item.label}</span>
					</a>
				{/each}
			</nav>
		</div>

		<!-- svelte-ignore a11y_no_static_element_interactions -->
		<div class="rail-bottom" ondragover={(e) => e.preventDefault()} ondrop={onRailDrop}>
			<div class="rail-upload-row">
				<!-- svelte-ignore a11y_no_static_element_interactions -->
				<div class="paste-box" contenteditable="true" onpaste={onPasteBox} role="textbox" tabindex="0">
					{#if uploadStatus === 'uploading'}Uploading...{:else if uploadStatus === 'done'}Saved!{:else}Paste screenshot{/if}
				</div>
				<button class="upload-icon-btn" onclick={() => uploadInput?.click()} title="Browse files">
					<Upload size={13} strokeWidth={2} />
				</button>
			</div>
			<input bind:this={uploadInput} type="file" accept="image/*,.pdf" onchange={onUploadInput} hidden />
			<button class="rail-feedback-btn" onclick={() => feedbackOpen = true} title="Send feedback">
				<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="13" height="13"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
				Feedback
			</button>
			<div class="rail-date">
				<CalendarDays size={14} strokeWidth={1.8} />
				<span>{new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric' }).format(new Date())}</span>
			</div>
			<div class="rail-user">{userName || 'Platform user'}</div>
		</div>
	</aside>

	<div class="shell-main">
		<header class="mobile-bar">
			<button class="mobile-menu-btn" onclick={() => (mobileNavOpen = true)} aria-label="Open navigation">
				<Menu size={18} strokeWidth={1.9} />
			</button>

			<a class="mobile-brand" href="/">
				<div class="brand-mark">P</div>
				<div>
					<div class="brand-name">Platform</div>
					<div class="brand-sub">ops workspace</div>
				</div>
			</a>
			<button class="command-trigger mobile" onclick={onOpenCommand} aria-label="Open assistant">
				<MessageSquare size={15} strokeWidth={1.8} />
				<span>AI</span>
			</button>
		</header>

		{#if mobileNavOpen}
			<button class="mobile-nav-overlay" aria-label="Close navigation" onclick={() => (mobileNavOpen = false)}></button>
			<aside class="mobile-nav-sheet">
				<div class="mobile-nav-head">
					<div>
						<div class="brand-name">Platform</div>
						<div class="brand-sub">ops workspace</div>
					</div>
					<button class="mobile-menu-btn" onclick={() => (mobileNavOpen = false)} aria-label="Close navigation">
						<X size={18} strokeWidth={1.9} />
					</button>
				</div>

				<nav class="mobile-nav-list">
					{#each navItems as item}
						<a href={item.href} class:active={isActive(item.href)} onclick={() => (mobileNavOpen = false)}>
							<item.icon size={16} strokeWidth={1.8} />
							<span>{item.label}</span>
						</a>
					{/each}
				</nav>

				<!-- svelte-ignore a11y_no_static_element_interactions -->
				<div class="mobile-nav-upload" ondragover={(e) => e.preventDefault()} ondrop={onRailDrop}>
					<div class="rail-upload-row">
						<!-- svelte-ignore a11y_no_static_element_interactions -->
						<div class="paste-box" contenteditable="true" onpaste={onPasteBox} role="textbox" tabindex="0">
							{#if uploadStatus === 'uploading'}Uploading...{:else if uploadStatus === 'done'}Saved!{:else}Paste screenshot{/if}
						</div>
						<button class="upload-icon-btn" onclick={() => uploadInput?.click()} title="Browse files">
							<Upload size={13} strokeWidth={2} />
						</button>
					</div>
				</div>
			</aside>
		{/if}

		<main class="shell-content">
			{@render children()}
		</main>
	</div>
</div>

{#if feedbackOpen}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="feedback-overlay" onclick={() => feedbackOpen = false}>
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="feedback-modal" onclick={(e) => e.stopPropagation()}>
		{#if feedbackSent}
			<div class="feedback-success">
				<svg viewBox="0 0 24 24" fill="none" stroke="#059669" stroke-width="2.5" width="40" height="40"><path d="M20 6L9 17l-5-5"/></svg>
				<div>Sent!</div>
			</div>
		{:else}
			<div class="feedback-header">Feedback</div>
			<div class="feedback-sub">Bug report, feature request, or anything</div>
			<textarea class="feedback-input" bind:value={feedbackText} placeholder="What's on your mind?"></textarea>
			<button class="feedback-send" onclick={sendFeedback} disabled={!feedbackText.trim() || feedbackSending}>
				{feedbackSending ? 'Sending...' : 'Send'}
			</button>
		{/if}
	</div>
</div>
{/if}

<style>
	:global(body) {
		background:
			radial-gradient(circle at top left, rgba(214, 120, 58, 0.08), transparent 22%),
			radial-gradient(circle at 85% 10%, rgba(65, 91, 82, 0.12), transparent 20%),
			linear-gradient(180deg, #f5efe6 0%, #efe6da 48%, #ede7de 100%);
		background-color: #f5efe6;
	}

	.shell {
		--shell-ink: #1e1812;
		--shell-muted: #6b6256;
		--shell-line: rgba(35, 26, 17, 0.11);
		min-height: 100dvh;
		display: grid;
		grid-template-columns: 270px minmax(0, 1fr);
		position: relative;
	}

	.shell-glow {
		position: fixed;
		border-radius: 999px;
		filter: blur(80px);
		pointer-events: none;
		opacity: 0.4;
	}

	.shell-glow-a {
		width: 340px;
		height: 340px;
		top: -120px;
		right: 12%;
		background: rgba(179, 92, 50, 0.16);
	}

	.shell-glow-b {
		width: 260px;
		height: 260px;
		bottom: 10%;
		left: 4%;
		background: rgba(68, 95, 86, 0.14);
	}

	.shell-rail {
		position: sticky;
		top: 0;
		height: 100vh;
		padding: 28px 20px 24px;
		display: flex;
		flex-direction: column;
		justify-content: space-between;
		background: linear-gradient(180deg, rgba(250, 246, 239, 0.82), rgba(244, 237, 228, 0.66));
		border-right: 1px solid var(--shell-line);
		backdrop-filter: blur(20px);
	}

	.rail-top {
		display: grid;
		gap: 18px;
	}

	.brand,
	.mobile-brand {
		display: flex;
		align-items: center;
		gap: 14px;
	}

	.brand-mark {
		width: 42px;
		height: 42px;
		display: grid;
		place-items: center;
		border-radius: 14px;
		background: linear-gradient(135deg, #211912, #5d4c3f);
		color: white;
		font-size: 18px;
		font-weight: 700;
		letter-spacing: 0.06em;
	}

	.brand-name {
		font-size: 14px;
		font-weight: 700;
		text-transform: uppercase;
		letter-spacing: 0.05em;
		color: var(--shell-ink);
	}

	.brand-sub,
	.rail-user {
		font-size: 11px;
		text-transform: uppercase;
		letter-spacing: 0.12em;
		color: var(--shell-muted);
	}

	.command-trigger {
		display: flex;
		align-items: center;
		gap: 8px;
		padding: 10px 12px;
		border-radius: 999px;
		border: 1px solid rgba(35, 26, 17, 0.09);
		background: rgba(255, 255, 255, 0.56);
		color: var(--shell-muted);
		font-size: 13px;
	}

	.command-trigger kbd {
		margin-left: auto;
		font-family: var(--mono);
		font-size: 11px;
		color: var(--shell-muted);
	}

	.rail-nav {
		display: grid;
		gap: 8px;
	}

	.rail-nav a {
		display: flex;
		align-items: center;
		gap: 12px;
		padding: 12px 14px;
		border-radius: 999px;
		color: var(--shell-muted);
		transition: background 160ms ease, color 160ms ease, transform 160ms ease;
	}

	.rail-nav a:hover,
	.rail-nav a.active {
		background: rgba(255, 255, 255, 0.62);
		color: var(--shell-ink);
		transform: translateX(3px);
	}

	/* Brain sub-nav */
	.rail-sub {
		padding: 2px 0 6px 0;
		display: grid;
		gap: 1px;
	}
	.rail-sub-tabs {
		display: flex;
		gap: 2px;
		margin: 0 8px 6px;
		padding: 3px;
		background: rgba(0,0,0,0.04);
		border-radius: 999px;
	}
	.rail-sub-tab {
		flex: 1;
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 4px;
		padding: 5px 8px;
		border-radius: 999px;
		border: none;
		background: none;
		font-size: 0.72rem;
		font-weight: 600;
		color: var(--shell-muted);
		font-family: inherit;
		transition: all 140ms;
	}
	.rail-sub-tab.active {
		background: rgba(255,255,255,0.7);
		color: var(--shell-ink);
	}
	.rail-sub-item {
		display: flex;
		align-items: center;
		gap: 12px;
		padding: 9px 14px 9px 28px;
		border-radius: 999px;
		color: var(--shell-muted);
		font-size: 0.82rem;
		transition: background 160ms ease, color 160ms ease;
		text-decoration: none;
	}
	.rail-sub-item:hover {
		background: rgba(255,255,255,0.4);
		color: var(--shell-ink);
	}
	.rail-sub-item.active {
		background: rgba(255,255,255,0.62);
		color: var(--shell-ink);
		font-weight: 600;
	}
	.rail-sub-item span:first-child {
		flex: 1;
	}
	.rail-sub-count {
		font-size: 0.68rem;
		font-family: var(--mono, monospace);
		color: var(--shell-muted);
		opacity: 0.6;
		min-width: 18px;
		text-align: right;
	}

	.rail-bottom {
		display: grid;
		gap: 10px;
		padding-top: 18px;
		border-top: 1px solid var(--shell-line);
	}

	.rail-upload-row {
		display: flex;
		gap: 4px;
		align-items: stretch;
	}
	.paste-box {
		flex: 1;
		padding: 7px 10px;
		border-radius: 10px;
		border: 1px dashed var(--shell-line);
		background: none;
		color: var(--shell-muted);
		font-size: 0.72rem;
		font-family: inherit;
		cursor: text;
		transition: all 160ms;
		outline: none;
		min-height: 0;
		overflow: hidden;
		white-space: nowrap;
	}
	.paste-box:focus {
		border-color: var(--shell-ink);
		border-style: solid;
		color: var(--shell-ink);
		background: rgba(255,255,255,0.2);
	}
	.upload-icon-btn {
		width: 32px;
		flex-shrink: 0;
		border-radius: 10px;
		border: 1px solid var(--shell-line);
		background: none;
		color: var(--shell-muted);
		display: flex;
		align-items: center;
		justify-content: center;
		cursor: pointer;
		transition: all 160ms;
	}
	.upload-icon-btn:hover {
		background: rgba(255,255,255,0.3);
		color: var(--shell-ink);
	}

	.rail-date {
		display: inline-flex;
		align-items: center;
		gap: 8px;
		font-size: 13px;
		color: var(--shell-muted);
	}

	.shell-main {
		min-width: 0;
	}

	.mobile-bar {
		display: none;
		align-items: center;
		justify-content: space-between;
		padding: 16px;
		border-bottom: 1px solid var(--shell-line);
		background: rgba(250, 246, 239, 0.78);
		backdrop-filter: blur(20px);
		position: sticky;
		top: 0;
		z-index: 20;
	}

	.command-trigger.mobile {
		height: 40px;
		justify-content: center;
		padding: 0 12px;
		gap: 6px;
		font-weight: 700;
		color: var(--shell-ink);
	}

	.command-trigger.mobile span {
		font-size: 0.78rem;
		letter-spacing: 0.02em;
	}

	.mobile-menu-btn {
		display: none;
		width: 40px;
		height: 40px;
		border-radius: 12px;
		align-items: center;
		justify-content: center;
		border: 1px solid rgba(35, 26, 17, 0.09);
		background: rgba(255, 255, 255, 0.56);
		color: var(--shell-muted);
	}

	.mobile-nav-overlay {
		position: fixed;
		inset: 0;
		border: 0;
		background: rgba(17, 13, 10, 0.28);
		backdrop-filter: blur(4px);
		z-index: 39;
	}

	.mobile-nav-sheet {
		position: fixed;
		top: 0;
		left: 0;
		bottom: 0;
		width: min(320px, 86vw);
		padding: 18px 16px;
		background: linear-gradient(180deg, rgba(250, 246, 239, 0.96), rgba(244, 237, 228, 0.94));
		border-right: 1px solid var(--shell-line);
		backdrop-filter: blur(20px);
		z-index: 40;
		display: grid;
		align-content: start;
		gap: 18px;
	}

	.mobile-nav-head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 12px;
	}

	.mobile-nav-list {
		display: grid;
		gap: 8px;
	}

	.mobile-nav-list a {
		display: flex;
		align-items: center;
		gap: 12px;
		padding: 12px 14px;
		border-radius: 16px;
		color: var(--shell-muted);
		background: transparent;
		transition: background 160ms ease, color 160ms ease;
	}

	.mobile-nav-list a.active {
		background: rgba(255, 255, 255, 0.62);
		color: var(--shell-ink);
	}

	.shell-content {
		min-width: 0;
	}

	@media (max-width: 900px) {
		.shell {
			grid-template-columns: 1fr;
		}

		.shell-rail {
			display: none;
		}

		.mobile-bar {
			display: flex;
		}

		.mobile-menu-btn {
			display: inline-flex;
		}

		.mobile-nav-upload {
			margin-top: auto;
			padding-top: 16px;
			border-top: 1px solid var(--shell-line);
		}
	}

	.rail-feedback-btn {
		display: flex;
		align-items: center;
		gap: 6px;
		padding: 6px 10px;
		border-radius: 8px;
		border: 1px dashed rgba(35,26,17,0.12);
		background: none;
		color: #8c7b69;
		font-size: 0.72rem;
		font-family: var(--font);
		cursor: pointer;
		transition: all 160ms;
	}
	.rail-feedback-btn:hover { background: rgba(255,248,241,0.8); color: #1e1812; }

	.feedback-overlay {
		position: fixed; inset: 0; z-index: 90;
		background: rgba(18,12,8,0.34); backdrop-filter: blur(8px);
		display: flex; align-items: center; justify-content: center;
	}
	.feedback-modal {
		width: min(420px, calc(100vw - 32px));
		padding: 24px;
		border-radius: 22px;
		background: linear-gradient(180deg, rgba(255,250,242,0.98), rgba(247,239,229,0.98));
		box-shadow: 0 24px 60px rgba(35,24,15,0.2);
	}
	.feedback-header {
		font-size: 1.1rem; font-weight: 700; color: #1e1812; margin-bottom: 4px;
	}
	.feedback-sub {
		font-size: 0.78rem; color: #8c7b69; margin-bottom: 14px;
	}
	.feedback-input {
		width: 100%; min-height: 100px; padding: 12px;
		border-radius: 12px; border: 1px solid rgba(35,26,17,0.12);
		background: rgba(255,255,255,0.6); color: #1e1812;
		font-size: 0.92rem; font-family: var(--font); resize: vertical;
		outline: none; margin-bottom: 12px;
	}
	.feedback-input:focus { border-color: rgba(35,26,17,0.3); }
	.feedback-send {
		width: 100%; padding: 12px;
		border-radius: 12px; border: none;
		background: #5d4737; color: white;
		font-size: 0.92rem; font-weight: 600;
		font-family: var(--font); cursor: pointer;
		transition: opacity 160ms;
	}
	.feedback-send:hover { opacity: 0.9; }
	.feedback-send:disabled { opacity: 0.4; cursor: not-allowed; }
	.feedback-success {
		display: flex; flex-direction: column;
		align-items: center; gap: 10px;
		padding: 32px; font-size: 1.1rem;
		font-weight: 600; color: #059669;
	}
</style>
