<script lang="ts">
	import { onMount } from 'svelte';
	import { fetchTools, runTool } from '$lib/api';
	import type { ToolInfo, ToolParam } from '$lib/types';

	// ── Frontend-only form niceties, keyed by backend param name ──
	// The backend tool schema carries name/type/default/required; labels,
	// placeholders, select options, and the input widget live here so the
	// API stays presentation-free.
	interface ParamUi {
		label?: string;
		input?: 'date' | 'select';
		options?: string[];
		placeholder?: string;
		fallbackDefault?: string;
	}
	const PARAM_UI: Record<string, ParamUi> = {
		team_name: { label: 'Team Name', placeholder: 'e.g. Arsenal, Toronto FC', fallbackDefault: 'Toronto FC' },
		player_name: { label: 'Player Name', placeholder: 'e.g. Federico Bernardeschi' },
		status: { label: 'Status Filter', input: 'select', options: ['all', 'upcoming', 'past'] },
		match_date: { label: 'Date', input: 'date' },
		event_id: { label: 'Event ID', placeholder: 'Get from get_fixtures first' },
		league: { label: 'League', placeholder: 'e.g. English Premier League' },
		season: { label: 'Season', placeholder: 'e.g. 2026 or 2025-2026' },
	};

	function uiFor(p: ToolParam): ParamUi {
		return PARAM_UI[p.name] ?? {};
	}
	function labelFor(p: ToolParam) {
		return uiFor(p).label ?? p.name;
	}
	function inputType(p: ToolParam): 'text' | 'number' | 'date' {
		const ui = uiFor(p);
		if (ui.input === 'date') return 'date';
		return p.type === 'integer' ? 'number' : 'text';
	}
	function initialValue(p: ToolParam): string {
		if (p.default != null) return String(p.default);
		return uiFor(p).fallbackDefault ?? '';
	}

	// ── State ────────────────────────────────────────────────

	let tools = $state<ToolInfo[]>([]);
	let selectedTool = $state<ToolInfo | null>(null);
	let paramValues = $state<Record<string, string>>({});
	let running = $state(false);
	let result = $state<string | null>(null);
	let resultError = $state<string | null>(null);

	interface HistoryEntry {
		tool: string;
		args: Record<string, string>;
		output: string;
		ok: boolean;
		ts: Date;
	}
	let history = $state<HistoryEntry[]>([]);

	function selectTool(tool: ToolInfo) {
		selectedTool = tool;
		result = null;
		resultError = null;
		paramValues = Object.fromEntries(tool.params.map((p) => [p.name, initialValue(p)]));
	}

	onMount(async () => {
		const r = await fetchTools();
		tools = r.tools;
		if (tools.length > 0) selectTool(tools[0]);
	});

	async function submit() {
		if (!selectedTool) return;
		running = true;
		result = null;
		resultError = null;

		const args: Record<string, unknown> = {};
		for (const p of selectedTool.params) {
			const val = paramValues[p.name];
			if (val === '') continue;
			args[p.name] = p.type === 'integer' ? Number(val) : val;
		}

		const snapshot = { ...paramValues };
		try {
			const r = await runTool(selectedTool.name, args);
			if (r.ok) {
				result = r.result ?? '';
			} else {
				resultError = r.error ?? 'Unknown error';
			}
			history = [
				{ tool: selectedTool.name, args: snapshot, output: r.ok ? (r.result ?? '') : (r.error ?? ''), ok: r.ok, ts: new Date() },
				...history,
			].slice(0, 25);
		} catch (e) {
			resultError = String(e);
		} finally {
			running = false;
		}
	}

	function loadHistory(entry: HistoryEntry) {
		const tool = tools.find((t) => t.name === entry.tool);
		if (!tool) return;
		selectTool(tool);
		// selectTool resets paramValues, restore after microtask
		setTimeout(() => {
			paramValues = { ...entry.args };
			if (entry.ok) {
				result = entry.output;
				resultError = null;
			} else {
				result = null;
				resultError = entry.output;
			}
		}, 0);
	}

	function fmtTime(d: Date) {
		return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
	}
</script>

<div class="space-y-5">
	<div>
		<h1 class="text-lg font-semibold">Tool Runner</h1>
		<p class="text-sm text-base-content/60 mt-1">
			Run MCP tools interactively and inspect raw API responses. Useful for spotting strange API
			results.
		</p>
	</div>

	{#if !selectedTool}
		<div class="flex items-center gap-2 text-base-content/60 text-sm">
			<span class="loading loading-spinner loading-sm"></span> Loading tools…
		</div>
	{:else}
		<div class="grid grid-cols-1 lg:grid-cols-3 gap-4 items-start">
			<!-- Left: selector + form + result -->
			<div class="lg:col-span-2 space-y-4">
				<!-- Tool selector -->
				<div class="card bg-base-100 border border-base-300">
					<div class="card-body p-4">
						<h2 class="text-xs font-medium text-base-content/60 uppercase tracking-wider mb-1">Select Tool</h2>
						<div class="flex flex-wrap gap-2">
							{#each tools as tool}
								<button
									onclick={() => selectTool(tool)}
									class="btn btn-sm {selectedTool.name === tool.name ? 'btn-primary' : 'btn-soft'}"
								>
									{tool.name}
									{#if tool.premium}
										<span
											class="tooltip cursor-help text-warning"
											data-tip="Requires a premium TheSportsDB key"
										>
											★
										</span>
									{/if}
								</button>
							{/each}
						</div>
					</div>
				</div>

				<!-- Parameter form -->
				<div class="card bg-base-100 border border-base-300">
					<div class="card-body p-4 gap-4">
						<div>
							<div class="flex items-center gap-2">
								<h2 class="text-sm font-semibold font-mono">{selectedTool.name}</h2>
								{#if selectedTool.premium}
									<span class="badge badge-warning badge-sm">Premium</span>
								{/if}
							</div>
							<p class="text-xs text-base-content/60 mt-1 whitespace-pre-line">{selectedTool.description}</p>
						</div>

						{#if selectedTool.params.length > 0}
							<div class="space-y-3">
								{#each selectedTool.params as param}
									<div>
										<label class="label text-xs font-medium mb-1" for={param.name}>
											{labelFor(param)}
										</label>
										{#if uiFor(param).input === 'select'}
											<select
												id={param.name}
												bind:value={paramValues[param.name]}
												class="select select-sm w-full"
											>
												{#each uiFor(param).options ?? [] as opt}
													<option value={opt}>{opt}</option>
												{/each}
											</select>
										{:else}
											<input
												id={param.name}
												type={inputType(param)}
												placeholder={uiFor(param).placeholder ?? ''}
												bind:value={paramValues[param.name]}
												class="input input-sm w-full"
											/>
										{/if}
									</div>
								{/each}
							</div>
						{:else}
							<p class="text-xs text-base-content/60 italic">No parameters — just click Run.</p>
						{/if}

						<button onclick={submit} disabled={running} class="btn btn-primary btn-sm self-start">
							{#if running}
								<span class="loading loading-spinner loading-xs"></span>
								Running…
							{:else}
								Run Tool
							{/if}
						</button>
					</div>
				</div>

				<!-- Result -->
				{#if result !== null || resultError !== null}
					<div class="card bg-base-100 border {resultError ? 'border-error' : 'border-base-300'}">
						<div
							class="px-4 py-2.5 border-b {resultError ? 'border-error' : 'border-base-300'} flex items-center gap-2"
						>
							<span class="text-xs font-medium {resultError ? 'text-error' : 'text-success'}">
								{resultError ? 'Error' : 'Result'}
							</span>
							{#if result}
								<span class="text-xs text-base-content/60">
									{result.split('\n').length} lines
								</span>
							{/if}
						</div>
						<pre
							class="px-4 py-4 text-sm font-mono whitespace-pre-wrap overflow-x-auto
								   max-h-[520px] overflow-y-auto leading-relaxed"
						>{resultError ?? result}</pre>
					</div>
				{/if}
			</div>

			<!-- Right: session history -->
			<div class="card bg-base-100 border border-base-300 sticky top-20">
				<div class="px-4 py-3 border-b border-base-300">
					<h2 class="text-xs font-medium text-base-content/60 uppercase tracking-wider">Session History</h2>
				</div>
				{#if history.length === 0}
					<p class="px-4 py-5 text-sm text-base-content/60">No queries yet.</p>
				{:else}
					<ul class="divide-y divide-base-300 max-h-[600px] overflow-y-auto">
						{#each history as entry}
							<li>
								<button
									onclick={() => loadHistory(entry)}
									class="w-full text-left px-4 py-3 hover:bg-base-200 transition-colors"
								>
									<div class="flex items-center justify-between gap-2">
										<code class="text-xs {entry.ok ? 'text-primary' : 'text-error'} truncate">
											{entry.tool}
										</code>
										<span class="text-xs text-base-content/60 shrink-0">{fmtTime(entry.ts)}</span>
									</div>
									{#each Object.entries(entry.args) as [k, v]}
										{#if v}
											<div class="text-xs text-base-content/60 truncate mt-0.5">
												{k}: <span class="text-base-content/80">{v}</span>
											</div>
										{/if}
									{/each}
									{#if !entry.ok}
										<div class="text-xs text-error mt-0.5 truncate">{entry.output}</div>
									{/if}
								</button>
							</li>
						{/each}
					</ul>
				{/if}
			</div>
		</div>
	{/if}
</div>
