<script lang="ts">
	import { onMount } from 'svelte';
	import { savedQueries } from '$lib/stores/savedQueries';
	import { activeConnectionId, connections } from '$lib/stores/connections';
	import { tabs } from '$lib/stores/tabs';
	import type { SavedQuery } from '$lib/types';
	import Icon from '$lib/icons/Icon.svelte';

	interface Props {
		onClose: () => void;
		onEditQuery?: (query: SavedQuery) => void;
	}

	let { onClose, onEditQuery }: Props = $props();

	let filterMode = $state<'all' | 'current'>('all');
	let searchQuery = $state('');
	let isLoading = $state(true);

	onMount(async () => {
		await savedQueries.load();
		isLoading = false;
	});

	// Get connection name by ID
	function getConnectionName(connectionId: string | undefined): string | null {
		if (!connectionId) return null;
		const conn = $connections.find((c) => c.id === connectionId);
		return conn?.name || 'Unknown';
	}

	// Filter queries based on mode and search
	let filteredQueries = $derived.by(() => {
		let queries = $savedQueries;

		// Filter by connection
		if (filterMode === 'current' && $activeConnectionId) {
			queries = queries.filter(
				(q) => !q.connectionId || q.connectionId === $activeConnectionId
			);
		}

		// Filter by search
		if (searchQuery.trim()) {
			const query = searchQuery.toLowerCase();
			queries = queries.filter(
				(q) =>
					q.name.toLowerCase().includes(query) ||
					q.sql.toLowerCase().includes(query) ||
					q.description?.toLowerCase().includes(query)
			);
		}

		// Sort by updatedAt descending
		return [...queries].sort(
			(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
		);
	});

	function formatDate(isoString: string): string {
		const date = new Date(isoString);
		return date.toLocaleDateString(undefined, {
			year: 'numeric',
			month: 'short',
			day: 'numeric'
		});
	}

	function truncateSql(sql: string, maxLength: number = 100): string {
		const oneLine = sql.replace(/\s+/g, ' ').trim();
		if (oneLine.length <= maxLength) return oneLine;
		return oneLine.substring(0, maxLength) + '...';
	}

	function handleQueryClick(query: SavedQuery) {
		tabs.openQuery({ title: query.name, initialSql: query.sql });
		onClose();
	}

	function handleEdit(e: MouseEvent, query: SavedQuery) {
		e.stopPropagation();
		onEditQuery?.(query);
	}

	async function handleDelete(e: MouseEvent, query: SavedQuery) {
		e.stopPropagation();
		if (!confirm(`Delete "${query.name}"?`)) return;

		try {
			await savedQueries.remove(query.id);
		} catch (err) {
			console.error('Failed to delete query:', err);
		}
	}

	function handleBackdropClick(e: MouseEvent) {
		if (e.target === e.currentTarget) {
			onClose();
		}
	}
</script>

<!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
<div class="panel-backdrop" onclick={handleBackdropClick}>
	<div class="panel">
		<div class="panel-header">
			<h2>
				<Icon name="save" size={18} />
				Saved Queries
			</h2>
			<button class="panel-close" onclick={onClose} title="Close">
				<Icon name="x" size={18} />
			</button>
		</div>

		<div class="panel-toolbar">
			<div class="search-wrapper">
				<Icon name="search" size={14} />
				<input
					type="text"
					placeholder="Search saved queries..."
					bind:value={searchQuery}
				/>
			</div>
			<div class="filter-buttons">
				<button
					class="filter-btn"
					class:active={filterMode === 'current'}
					onclick={() => (filterMode = 'current')}
					disabled={!$activeConnectionId}
				>
					Current DB
				</button>
				<button
					class="filter-btn"
					class:active={filterMode === 'all'}
					onclick={() => (filterMode = 'all')}
				>
					All
				</button>
			</div>
		</div>

		<div class="panel-content">
			{#if isLoading}
				<div class="empty-state">
					<Icon name="refresh" size={20} class="spinning" />
					Loading...
				</div>
			{:else if filteredQueries.length === 0}
				<div class="empty-state">
					<Icon name="save" size={32} strokeWidth={1.5} />
					<p>No saved queries</p>
					<span class="hint">Save queries from the query editor (Ctrl+S)</span>
				</div>
			{:else}
				<div class="queries-list">
					{#each filteredQueries as query}
						<!-- svelte-ignore a11y_no_static_element_interactions -->
						<div
							class="query-item"
							onclick={() => handleQueryClick(query)}
							onkeydown={(e) => e.key === 'Enter' && handleQueryClick(query)}
							role="button"
							tabindex="0"
						>
							<div class="query-item-main">
								<div class="query-name">{query.name}</div>
								{#if query.description}
									<div class="query-description">{query.description}</div>
								{/if}
								<div class="query-sql">{truncateSql(query.sql)}</div>
								<div class="query-meta">
									<span class="query-date">{formatDate(query.updatedAt)}</span>
									{#if query.connectionId}
										<span class="query-db" title="Bound to specific connection">
											{getConnectionName(query.connectionId)}
										</span>
									{/if}
								</div>
							</div>
							<div class="query-actions">
								<button
									class="action-btn"
									onclick={(e) => handleEdit(e, query)}
									title="Edit"
								>
									<Icon name="edit" size={14} />
								</button>
								<button
									class="action-btn danger"
									onclick={(e) => handleDelete(e, query)}
									title="Delete"
								>
									<Icon name="trash" size={14} />
								</button>
							</div>
						</div>
					{/each}
				</div>
			{/if}
		</div>

		<div class="panel-footer">
			<span class="queries-count">{filteredQueries.length} saved queries</span>
		</div>
	</div>
</div>

<style>
	.panel-backdrop {
		position: fixed;
		inset: 0;
		background: rgba(0, 0, 0, 0.5);
		display: flex;
		align-items: center;
		justify-content: center;
		z-index: 1000;
	}

	.panel {
		background: var(--color-bg);
		border-radius: var(--radius-lg);
		box-shadow: 0 16px 64px rgba(0, 0, 0, 0.4);
		width: 100%;
		max-width: 650px;
		max-height: 80vh;
		display: flex;
		flex-direction: column;
		overflow: hidden;
	}

	.panel-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 16px 20px;
		border-bottom: 1px solid var(--color-border);
	}

	.panel-header h2 {
		display: flex;
		align-items: center;
		gap: 8px;
		font-size: 18px;
		font-weight: 600;
	}

	.panel-header h2 svg {
		color: var(--color-primary);
	}

	.panel-close {
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 4px;
		border-radius: var(--radius-sm);
		opacity: 0.5;
		transition: all var(--transition-fast);
	}

	.panel-close:hover {
		opacity: 1;
		background: var(--color-surface);
	}

	.panel-toolbar {
		display: flex;
		align-items: center;
		gap: 12px;
		padding: 12px 20px;
		background: var(--color-bg-secondary);
		border-bottom: 1px solid var(--color-border);
	}

	.search-wrapper {
		flex: 1;
		display: flex;
		align-items: center;
		gap: 8px;
		padding: 6px 12px;
		background: var(--color-surface);
		border: 1px solid var(--color-border);
		border-radius: var(--radius-sm);
	}

	.search-wrapper svg {
		color: var(--color-text-muted);
		flex-shrink: 0;
	}

	.search-wrapper input {
		flex: 1;
		border: none;
		background: transparent;
		font-size: 13px;
		padding: 0;
	}

	.search-wrapper input:focus {
		outline: none;
	}

	.filter-buttons {
		display: flex;
		gap: 4px;
	}

	.filter-btn {
		padding: 6px 12px;
		font-size: 12px;
		border-radius: var(--radius-sm);
		color: var(--color-text-muted);
		transition: all var(--transition-fast);
	}

	.filter-btn:hover:not(:disabled) {
		background: var(--color-surface);
		color: var(--color-text);
	}

	.filter-btn.active {
		background: var(--color-primary);
		color: white;
	}

	.filter-btn:disabled {
		opacity: 0.5;
		cursor: not-allowed;
	}

	.panel-content {
		flex: 1;
		overflow-y: auto;
		min-height: 200px;
	}

	.empty-state {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		padding: 48px 24px;
		color: var(--color-text-muted);
		text-align: center;
	}

	.empty-state svg {
		margin-bottom: 12px;
		opacity: 0.5;
	}

	.empty-state p {
		font-size: 14px;
	}

	.empty-state .hint {
		font-size: 12px;
		color: var(--color-text-dim);
		margin-top: 4px;
	}

	.spinning {
		animation: spin 1s linear infinite;
	}

	@keyframes spin {
		from { transform: rotate(0deg); }
		to { transform: rotate(360deg); }
	}

	.queries-list {
		display: flex;
		flex-direction: column;
	}

	.query-item {
		display: flex;
		align-items: flex-start;
		gap: 12px;
		padding: 14px 20px;
		border-bottom: 1px solid var(--color-border);
		text-align: left;
		transition: background var(--transition-fast);
	}

	.query-item:hover {
		background: var(--color-surface);
	}

	.query-item:last-child {
		border-bottom: none;
	}

	.query-item-main {
		flex: 1;
		min-width: 0;
	}

	.query-name {
		font-size: 14px;
		font-weight: 500;
		color: var(--color-text);
		margin-bottom: 4px;
	}

	.query-description {
		font-size: 12px;
		color: var(--color-text-muted);
		margin-bottom: 6px;
	}

	.query-sql {
		font-family: var(--font-mono);
		font-size: 12px;
		color: var(--color-text-dim);
		margin-bottom: 8px;
		word-break: break-all;
	}

	.query-meta {
		display: flex;
		align-items: center;
		gap: 12px;
		font-size: 11px;
		color: var(--color-text-muted);
	}

	.query-db {
		padding: 2px 6px;
		background: var(--color-surface);
		border-radius: var(--radius-sm);
	}

	.query-actions {
		display: flex;
		gap: 4px;
		opacity: 0;
		transition: opacity var(--transition-fast);
	}

	.query-item:hover .query-actions {
		opacity: 1;
	}

	.action-btn {
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 6px;
		border-radius: var(--radius-sm);
		color: var(--color-text-muted);
		transition: all var(--transition-fast);
	}

	.action-btn:hover {
		color: var(--color-text);
		background: var(--color-bg-tertiary);
	}

	.action-btn.danger:hover {
		color: var(--color-error);
		background: rgba(243, 139, 168, 0.1);
	}

	.panel-footer {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 12px 20px;
		border-top: 1px solid var(--color-border);
		background: var(--color-bg-secondary);
	}

	.queries-count {
		font-size: 12px;
		color: var(--color-text-muted);
	}
</style>
