<script lang="ts">
	/**
	 * Admin — AI Gateway-konfigurasjon (oppgave 15.4 + 061)
	 *
	 * Modelloversikt, API-nøkler (kryptert), ruting-regler per jobbtype,
	 * fallback-kjeder, forbruksoversikt per samling, nivå-konfigurasjon.
	 * Ref: docs/infra/ai_gateway.md, docs/oppdrag/admin-komplett.md
	 */
	import { page } from '$app/stores';
	import {
		fetchAiOverview,
		fetchAiUsage,
		fetchAiTierCosts,
		testAiPrompt,
		updateAiAlias,
		createAiAlias,
		updateAiProvider,
		createAiProvider,
		deleteAiProvider,
		updateAiRouting,
		deleteAiRouting,
		type AiOverviewResponse,
		type AiModelAlias,
		type AiModelProvider,
		type AiJobRouting,
		type AiUsageSummary,
		type ApiKeyStatus,
		type TierCostInfo,
		type AiTestPromptResponse
	} from '$lib/api';

	const session = $derived($page.data.session as Record<string, unknown> | undefined);
	const accessToken = $derived(session?.accessToken as string | undefined);

	let data = $state<AiOverviewResponse | null>(null);
	let tierCosts = $state<TierCostInfo[]>([]);
	let loading = $state(false);
	let error = $state<string | null>(null);
	let actionLoading = $state<string | null>(null);

	// Tabs
	let activeTab = $state<'tiers' | 'aliases' | 'routing' | 'usage' | 'keys'>('tiers');

	// Forbruksperiode
	let usageDays = $state(30);

	// Nytt alias-skjema
	let showNewAlias = $state(false);
	let newAliasName = $state('');
	let newAliasDesc = $state('');

	// Ny provider-skjema
	let showNewProvider = $state<string | null>(null); // alias_id
	let newProviderName = $state('');
	let newProviderModel = $state('');
	let newProviderKeyEnv = $state('');
	let newProviderPriority = $state(10);

	// Ny ruting-skjema
	let showNewRouting = $state(false);
	let newRoutingJobType = $state('');
	let newRoutingAlias = $state('');
	let newRoutingDesc = $state('');

	// Test-prompt state
	let testResults = $state<Record<string, AiTestPromptResponse | null>>({});
	let testLoading = $state<Record<string, boolean>>({});
	let testErrors = $state<Record<string, string | null>>({});

	// Tier ordering
	const TIER_ORDER = ['synops/low', 'synops/medium', 'synops/high', 'synops/extreme'];
	const TIER_LABELS: Record<string, string> = {
		'synops/low': 'Low',
		'synops/medium': 'Medium',
		'synops/high': 'High',
		'synops/extreme': 'Extreme'
	};
	const TIER_COLORS: Record<string, string> = {
		'synops/low': 'bg-emerald-500',
		'synops/medium': 'bg-blue-500',
		'synops/high': 'bg-amber-500',
		'synops/extreme': 'bg-red-500'
	};
	const TIER_BORDERS: Record<string, string> = {
		'synops/low': 'border-emerald-200',
		'synops/medium': 'border-blue-200',
		'synops/high': 'border-amber-200',
		'synops/extreme': 'border-red-200'
	};

	// Kjente AI-kontekster med kategorier og beskrivelser
	const KNOWN_CONTEXTS: { category: string; contexts: { job_type: string; description: string }[] }[] = [
		{
			category: 'Orkestrering',
			contexts: [
				{ job_type: 'orchestration_script', description: 'LLM-kall i orkestreringsskript (SPØR/TRANSFORMER-steg)' },
				{ job_type: 'orchestration_dream', description: 'Kreativ/utforskende orkestrering — drømmemodus' }
			]
		},
		{
			category: 'Bot & chat',
			contexts: [
				{ job_type: 'bot_chat', description: 'Bot-svar i chat (Claude-agent og andre bots)' },
				{ job_type: 'bot_triage', description: 'Triagering og klassifisering av innkommende meldinger' },
				{ job_type: 'agent_respond', description: 'Claude chat-agent svar (legacy)' }
			]
		},
		{
			category: 'Analyse & klassifisering',
			contexts: [
				{ job_type: 'suggest_edges', description: 'AI-foreslåtte topics og mentions ved ny node' },
				{ job_type: 'summarize', description: 'Oppsummering av kommunikasjonsnoder og innhold' },
				{ job_type: 'classify', description: 'Klassifisering av innhold (node_kind, tags, prioritet)' }
			]
		},
		{
			category: 'Prosessering',
			contexts: [
				{ job_type: 'ai_text_process', description: 'Tekstvasking og behandling, høyt volum' },
				{ job_type: 'whisper_postprocess', description: 'Transkripsjonsvasking etter Whisper' },
				{ job_type: 'research_clip', description: 'Research-oppsummering' },
				{ job_type: 'simple_prompt', description: 'Standard LLM-kall via synops-ai prompt' },
				{ job_type: 'live_factoid_eval', description: 'Faktoid-vurdering under live sending' }
			]
		}
	];

	// Alle kjente job_types som flat liste
	const allKnownJobTypes = KNOWN_CONTEXTS.flatMap((c) => c.contexts.map((ctx) => ctx.job_type));

	function routingForContext(jobType: string): AiJobRouting | undefined {
		return data?.routing.find((r) => r.job_type === jobType);
	}

	function unknownRoutingRules(): AiJobRouting[] {
		if (!data) return [];
		return data.routing.filter((r) => !allKnownJobTypes.includes(r.job_type));
	}

	// Poll hvert 10. sekund
	$effect(() => {
		if (!accessToken) return;
		loadData();
		const interval = setInterval(loadData, 10000);
		return () => clearInterval(interval);
	});

	async function loadData() {
		if (!accessToken) return;
		try {
			const [overview, costs] = await Promise.all([
				fetchAiOverview(accessToken),
				fetchAiTierCosts(accessToken)
			]);
			data = overview;
			tierCosts = costs;
			error = null;
		} catch (e) {
			error = String(e);
		}
	}

	// Hjelpefunksjoner
	function providersForAlias(alias: AiModelAlias): AiModelProvider[] {
		if (!data) return [];
		return data.providers
			.filter((p) => p.alias_id === alias.id)
			.sort((a, b) => a.priority - b.priority);
	}

	function keyStatus(envVar: string): boolean {
		if (!data) return false;
		return data.api_key_status.find((k) => k.env_var === envVar)?.is_set ?? false;
	}

	function formatTokens(n: number): string {
		if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
		if (n >= 1_000) return `${(n / 1_000).toFixed(1)}k`;
		return String(n);
	}

	function formatCost(cost: number): string {
		if (cost < 0.01) return `$${cost.toFixed(4)}`;
		return `$${cost.toFixed(2)}`;
	}

	function tierAlias(tierName: string): AiModelAlias | undefined {
		return data?.aliases.find((a) => a.alias === tierName);
	}

	// Antall routing-regler som peker til dette aliaset
	function routingCountForAlias(alias: string): number {
		if (!data) return 0;
		return data.routing.filter((r) => r.alias === alias).length;
	}

	// Handlinger
	async function toggleAlias(alias: AiModelAlias) {
		if (!accessToken) return;
		actionLoading = `alias-${alias.id}`;
		try {
			await updateAiAlias(accessToken, {
				id: alias.id,
				description: alias.description,
				is_active: !alias.is_active
			});
			await loadData();
		} catch (e) {
			error = String(e);
		}
		actionLoading = null;
	}

	async function toggleProvider(provider: AiModelProvider) {
		if (!accessToken) return;
		actionLoading = `provider-${provider.id}`;
		try {
			await updateAiProvider(accessToken, {
				id: provider.id,
				is_active: !provider.is_active
			});
			await loadData();
		} catch (e) {
			error = String(e);
		}
		actionLoading = null;
	}

	async function changeProviderPriority(provider: AiModelProvider, newPriority: number) {
		if (!accessToken) return;
		actionLoading = `priority-${provider.id}`;
		try {
			await updateAiProvider(accessToken, {
				id: provider.id,
				priority: newPriority
			});
			await loadData();
		} catch (e) {
			error = String(e);
		}
		actionLoading = null;
	}

	async function removeProvider(provider: AiModelProvider) {
		if (!accessToken) return;
		actionLoading = `delete-${provider.id}`;
		try {
			await deleteAiProvider(accessToken, provider.id);
			await loadData();
		} catch (e) {
			error = String(e);
		}
		actionLoading = null;
	}

	async function handleCreateAlias() {
		if (!accessToken || !newAliasName.trim()) return;
		actionLoading = 'create-alias';
		try {
			await createAiAlias(accessToken, {
				alias: newAliasName.trim(),
				description: newAliasDesc.trim() || null
			});
			newAliasName = '';
			newAliasDesc = '';
			showNewAlias = false;
			await loadData();
		} catch (e) {
			error = String(e);
		}
		actionLoading = null;
	}

	async function handleCreateProvider() {
		if (!accessToken || !showNewProvider || !newProviderModel.trim()) return;
		actionLoading = 'create-provider';
		try {
			await createAiProvider(accessToken, {
				alias_id: showNewProvider,
				provider: newProviderName.trim(),
				model: newProviderModel.trim(),
				api_key_env: newProviderKeyEnv.trim(),
				priority: newProviderPriority
			});
			newProviderName = '';
			newProviderModel = '';
			newProviderKeyEnv = '';
			newProviderPriority = 10;
			showNewProvider = null;
			await loadData();
		} catch (e) {
			error = String(e);
		}
		actionLoading = null;
	}

	async function handleUpdateRouting(routing: AiJobRouting, newAlias: string) {
		if (!accessToken) return;
		actionLoading = `routing-${routing.job_type}`;
		try {
			await updateAiRouting(accessToken, {
				job_type: routing.job_type,
				alias: newAlias,
				description: routing.description
			});
			await loadData();
		} catch (e) {
			error = String(e);
		}
		actionLoading = null;
	}

	async function handleCreateRouting() {
		if (!accessToken || !newRoutingJobType.trim() || !newRoutingAlias.trim()) return;
		actionLoading = 'create-routing';
		try {
			await updateAiRouting(accessToken, {
				job_type: newRoutingJobType.trim(),
				alias: newRoutingAlias.trim(),
				description: newRoutingDesc.trim() || null
			});
			newRoutingJobType = '';
			newRoutingAlias = '';
			newRoutingDesc = '';
			showNewRouting = false;
			await loadData();
		} catch (e) {
			error = String(e);
		}
		actionLoading = null;
	}

	async function handleDeleteRouting(jobType: string) {
		if (!accessToken) return;
		actionLoading = `delete-routing-${jobType}`;
		try {
			await deleteAiRouting(accessToken, jobType);
			await loadData();
		} catch (e) {
			error = String(e);
		}
		actionLoading = null;
	}

	async function handleTestPrompt(alias: string) {
		if (!accessToken) return;
		testLoading[alias] = true;
		testErrors[alias] = null;
		testResults[alias] = null;
		try {
			testResults[alias] = await testAiPrompt(accessToken, alias);
		} catch (e) {
			testErrors[alias] = String(e);
		}
		testLoading[alias] = false;
	}
</script>

<div class="min-h-screen bg-gray-50">
	<header class="border-b border-gray-200 bg-white">
		<div class="mx-auto flex max-w-5xl items-center justify-between px-4 py-3">
			<div class="flex items-center gap-3">
				<a href="/admin" class="text-sm text-gray-500 hover:text-gray-700">Admin</a>
				<span class="text-gray-300">/</span>
				<h1 class="text-lg font-semibold text-gray-900">AI Gateway</h1>
			</div>
		</div>
	</header>

	<main class="mx-auto max-w-5xl px-4 py-6">
		{#if !accessToken}
			<p class="text-sm text-gray-400">Logg inn for tilgang.</p>
		{:else if !data}
			<p class="text-sm text-gray-400">Laster AI-konfigurasjon...</p>
		{:else}
			<!-- Feilmelding -->
			{#if error}
				<div class="mb-4 rounded-lg border border-red-200 bg-red-50 p-3 text-sm text-red-700">
					{error}
				</div>
			{/if}

			<!-- Tabs -->
			<div class="mb-6 flex gap-1 overflow-x-auto rounded-lg bg-gray-100 p-1">
				{#each [
					{ key: 'tiers', label: 'Nivåer' },
					{ key: 'aliases', label: 'Modeller & fallback' },
					{ key: 'routing', label: 'Ruting' },
					{ key: 'usage', label: 'Forbruk' },
					{ key: 'keys', label: 'API-nøkler' }
				] as tab}
					<button
						class="flex-1 whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium transition-colors {activeTab === tab.key ? 'bg-white text-gray-900 shadow-sm' : 'text-gray-600 hover:text-gray-800'}"
						onclick={() => (activeTab = tab.key as typeof activeTab)}
					>
						{tab.label}
					</button>
				{/each}
			</div>

			<!-- === TAB: Nivåer === -->
			{#if activeTab === 'tiers'}
				<div class="space-y-4">
					<div class="rounded-lg border border-gray-200 bg-white px-5 py-3 shadow-sm">
						<h2 class="text-sm font-semibold text-gray-800">Synops AI-nivåer</h2>
						<p class="mt-1 text-xs text-gray-500">
							Fire kvalitetsnivåer med fallback-kjeder. Jobbtyper rutes til et nivå i Ruting-fanen.
						</p>
					</div>

					{#each TIER_ORDER as tierName}
						{@const alias = tierAlias(tierName)}
						{@const costs = tierCosts.find((t) => t.alias === tierName)}
						{@const providers = alias ? providersForAlias(alias) : []}
						{@const routingCount = routingCountForAlias(tierName)}
						{@const result = testResults[tierName]}
						{@const testing = testLoading[tierName]}
						{@const testError = testErrors[tierName]}
						<section class="overflow-hidden rounded-lg border bg-white shadow-sm {TIER_BORDERS[tierName] ?? 'border-gray-200'}">
							<!-- Tier header -->
							<div class="flex items-center justify-between border-b border-gray-100 px-5 py-3">
								<div class="flex items-center gap-3">
									<span class="h-3 w-3 rounded-full {TIER_COLORS[tierName] ?? 'bg-gray-400'}"></span>
									<div>
										<div class="flex items-center gap-2">
											<span class="font-mono text-sm font-semibold text-gray-900">{tierName}</span>
											{#if alias}
												<span class="rounded-full px-2 py-0.5 text-[10px] font-medium {alias.is_active ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'}">
													{alias.is_active ? 'Aktiv' : 'Inaktiv'}
												</span>
											{:else}
												<span class="rounded bg-red-100 px-1.5 py-0.5 text-[10px] text-red-600">
													Ikke opprettet
												</span>
											{/if}
										</div>
										{#if alias?.description}
											<p class="mt-0.5 text-xs text-gray-500">{alias.description}</p>
										{/if}
									</div>
								</div>
								<div class="flex items-center gap-3">
									<span class="text-xs text-gray-400">{routingCount} ruting{routingCount !== 1 ? 'er' : ''}</span>
									{#if alias}
										<button
											class="rounded px-2 py-1 text-xs {alias.is_active ? 'text-amber-600 hover:bg-amber-50' : 'text-green-600 hover:bg-green-50'}"
											disabled={actionLoading === `alias-${alias.id}`}
											onclick={() => toggleAlias(alias)}
										>
											{alias.is_active ? 'Deaktiver' : 'Aktiver'}
										</button>
									{/if}
								</div>
							</div>

							<div class="grid gap-0 divide-y divide-gray-100 sm:grid-cols-2 sm:divide-x sm:divide-y-0">
								<!-- Fallback-kjede -->
								<div class="px-5 py-3">
									<div class="mb-2 text-xs font-medium uppercase tracking-wide text-gray-500">
										Fallback-kjede
									</div>
									{#if providers.length === 0}
										<p class="text-xs text-gray-400 italic">Ingen providers konfigurert</p>
									{:else}
										<div class="space-y-1.5">
											{#each providers as provider, idx}
												<div class="flex items-center gap-2 text-sm {!provider.is_active ? 'opacity-50' : ''}">
													<span class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-gray-200 text-[10px] font-medium text-gray-600">
														{provider.priority}
													</span>
													<div class="min-w-0 flex-1">
														<span class="font-mono text-xs text-gray-800">{provider.model}</span>
													</div>
													<span class="inline-flex items-center gap-1 text-[10px] {keyStatus(provider.api_key_env) ? 'text-green-600' : 'text-red-500'}">
														<span class="h-1.5 w-1.5 rounded-full {keyStatus(provider.api_key_env) ? 'bg-green-500' : 'bg-red-400'}"></span>
													</span>
													<!-- Prioritet-knapper -->
													<div class="flex gap-0.5">
														{#if idx > 0}
															<button
																class="rounded px-1 py-0.5 text-[10px] text-gray-400 hover:bg-gray-100"
																onclick={() => changeProviderPriority(provider, provider.priority - 1)}
															>&uarr;</button>
														{/if}
														{#if idx < providers.length - 1}
															<button
																class="rounded px-1 py-0.5 text-[10px] text-gray-400 hover:bg-gray-100"
																onclick={() => changeProviderPriority(provider, provider.priority + 1)}
															>&darr;</button>
														{/if}
													</div>
													<button
														class="rounded px-1 py-0.5 text-[10px] {provider.is_active ? 'text-amber-600 hover:bg-amber-50' : 'text-green-600 hover:bg-green-50'}"
														onclick={() => toggleProvider(provider)}
													>{provider.is_active ? 'Av' : 'På'}</button>
													<button
														class="rounded px-1 py-0.5 text-[10px] text-red-500 hover:bg-red-50"
														onclick={() => removeProvider(provider)}
													>Slett</button>
												</div>
											{/each}
										</div>
									{/if}

									<!-- Legg til provider -->
									{#if alias && showNewProvider === alias.id}
										<div class="mt-2 rounded-md border border-blue-200 bg-blue-50 p-2">
											<div class="grid grid-cols-2 gap-1.5">
												<input
													bind:value={newProviderName}
													placeholder="Leverandør"
													class="rounded border border-gray-300 px-2 py-1 text-xs"
												/>
												<input
													bind:value={newProviderModel}
													placeholder="Modell"
													class="rounded border border-gray-300 px-2 py-1 text-xs"
												/>
												<input
													bind:value={newProviderKeyEnv}
													placeholder="Env-variabel"
													class="rounded border border-gray-300 px-2 py-1 text-xs"
												/>
												<input
													bind:value={newProviderPriority}
													type="number"
													min="1"
													max="99"
													placeholder="Prioritet"
													class="rounded border border-gray-300 px-2 py-1 text-xs"
												/>
											</div>
											<div class="mt-1.5 flex gap-1.5">
												<button
													class="rounded bg-blue-600 px-2 py-0.5 text-xs text-white hover:bg-blue-700 disabled:opacity-50"
													onclick={handleCreateProvider}
													disabled={actionLoading === 'create-provider' || !newProviderModel.trim()}
												>Legg til</button>
												<button
													class="rounded px-2 py-0.5 text-xs text-gray-600 hover:bg-gray-100"
													onclick={() => (showNewProvider = null)}
												>Avbryt</button>
											</div>
										</div>
									{:else if alias}
										<button
											class="mt-2 text-[10px] text-blue-600 hover:text-blue-800"
											onclick={() => (showNewProvider = alias.id)}
										>+ Legg til modell</button>
									{/if}
								</div>

								<!-- Kostnadsestimat + test -->
								<div class="px-5 py-3">
									<div class="mb-2 text-xs font-medium uppercase tracking-wide text-gray-500">
										Kostnadsestimat
									</div>
									{#if costs && costs.providers.length > 0}
										<div class="space-y-1">
											{#each costs.providers as cp}
												<div class="flex items-center justify-between text-xs">
													<span class="font-mono text-gray-600">{cp.model.split('/').pop()}</span>
													<div class="flex items-center gap-3">
														<span class="text-gray-400" title="Input/output per million tokens">
															${cp.input_cost_per_mtok}/{cp.output_cost_per_mtok}
														</span>
														<span class="font-medium text-gray-700" title="Estimert kostnad per 1000 tokens (70% input, 30% output)">
															~{formatCost(cp.estimated_cost_1k_tokens)}/1k
														</span>
													</div>
												</div>
											{/each}
										</div>
									{:else}
										<p class="text-xs text-gray-400 italic">Ingen data</p>
									{/if}

									<!-- Test-knapp -->
									<div class="mt-3 border-t border-gray-100 pt-3">
										<button
											class="rounded-md bg-gray-800 px-3 py-1.5 text-xs font-medium text-white hover:bg-gray-700 disabled:opacity-50"
											disabled={testing || !alias}
											onclick={() => handleTestPrompt(tierName)}
										>
											{#if testing}
												Tester...
											{:else}
												Test-prompt
											{/if}
										</button>

										{#if result}
											<div class="mt-2 rounded-md border border-green-200 bg-green-50 p-2">
												<p class="text-xs text-green-800">{result.response_text}</p>
												<div class="mt-1.5 flex flex-wrap gap-x-3 gap-y-0.5 text-[10px] text-green-600">
													<span>Modell: {result.model_used ?? '?'}</span>
													<span>{result.latency_ms}ms</span>
													<span>{result.prompt_tokens}+{result.completion_tokens} tokens</span>
													<span>{formatCost(result.estimated_cost)}</span>
												</div>
											</div>
										{/if}
										{#if testError}
											<div class="mt-2 rounded-md border border-red-200 bg-red-50 p-2 text-xs text-red-700">
												{testError}
											</div>
										{/if}
									</div>
								</div>
							</div>
						</section>
					{/each}
				</div>

			<!-- === TAB: Modeller & fallback === -->
			{:else if activeTab === 'aliases'}
				<div class="space-y-4">
					{#each data.aliases as alias}
						<section class="rounded-lg border border-gray-200 bg-white shadow-sm">
							<!-- Alias header -->
							<div class="flex items-center justify-between border-b border-gray-100 px-5 py-3">
								<div class="flex items-center gap-3">
									<span
										class="h-2 w-2 rounded-full {alias.is_active ? 'bg-green-500' : 'bg-gray-300'}"
									></span>
									<span class="font-mono text-sm font-semibold text-gray-900"
										>{alias.alias}</span
									>
									{#if alias.description}
										<span class="text-xs text-gray-500">— {alias.description}</span>
									{/if}
								</div>
								<button
									class="rounded px-2 py-1 text-xs {alias.is_active ? 'text-amber-600 hover:bg-amber-50' : 'text-green-600 hover:bg-green-50'}"
									disabled={actionLoading === `alias-${alias.id}`}
									onclick={() => toggleAlias(alias)}
								>
									{alias.is_active ? 'Deaktiver' : 'Aktiver'}
								</button>
							</div>

							<!-- Providers (fallback-kjede) -->
							<div class="px-5 py-3">
								<div class="mb-2 text-xs font-medium uppercase tracking-wide text-gray-500">
									Fallback-kjede (prioritet)
								</div>
								<div class="space-y-2">
									{#each providersForAlias(alias) as provider, idx}
										<div
											class="flex items-center gap-3 rounded-md border px-3 py-2 text-sm {provider.is_active ? 'border-gray-200 bg-gray-50' : 'border-gray-100 bg-gray-50/50 opacity-60'}"
										>
											<span
												class="flex h-5 w-5 items-center justify-center rounded-full bg-gray-200 text-xs font-medium text-gray-600"
												>{provider.priority}</span
											>
											<div class="flex-1">
												<span class="font-mono text-xs text-gray-800">{provider.model}</span>
												<span class="ml-2 text-xs text-gray-400">({provider.provider})</span>
											</div>
											<span
												class="inline-flex items-center gap-1 text-xs {keyStatus(provider.api_key_env) ? 'text-green-600' : 'text-red-500'}"
											>
												<span
													class="h-1.5 w-1.5 rounded-full {keyStatus(provider.api_key_env) ? 'bg-green-500' : 'bg-red-400'}"
												></span>
												{provider.api_key_env}
											</span>

											<!-- Prioritet-knapper -->
											<div class="flex gap-1">
												{#if idx > 0}
													<button
														class="rounded px-1.5 py-0.5 text-xs text-gray-500 hover:bg-gray-200"
														title="Flytt opp"
														onclick={() => changeProviderPriority(provider, provider.priority - 1)}
													>
														&uarr;
													</button>
												{/if}
												{#if idx < providersForAlias(alias).length - 1}
													<button
														class="rounded px-1.5 py-0.5 text-xs text-gray-500 hover:bg-gray-200"
														title="Flytt ned"
														onclick={() => changeProviderPriority(provider, provider.priority + 1)}
													>
														&darr;
													</button>
												{/if}
											</div>

											<button
												class="rounded px-2 py-0.5 text-xs {provider.is_active ? 'text-amber-600 hover:bg-amber-50' : 'text-green-600 hover:bg-green-50'}"
												onclick={() => toggleProvider(provider)}
												disabled={actionLoading === `provider-${provider.id}`}
											>
												{provider.is_active ? 'Av' : 'På'}
											</button>
											<button
												class="rounded px-2 py-0.5 text-xs text-red-500 hover:bg-red-50"
												onclick={() => removeProvider(provider)}
												disabled={actionLoading === `delete-${provider.id}`}
											>
												Slett
											</button>
										</div>
									{/each}
								</div>

								<!-- Legg til provider -->
								{#if showNewProvider === alias.id}
									<div class="mt-3 rounded-md border border-blue-200 bg-blue-50 p-3">
										<div class="grid grid-cols-2 gap-2 sm:grid-cols-4">
											<input
												bind:value={newProviderName}
												placeholder="Leverandør (f.eks. gemini)"
												class="rounded border border-gray-300 px-2 py-1 text-sm"
											/>
											<input
												bind:value={newProviderModel}
												placeholder="Modell (f.eks. gemini/gemini-2.5-flash)"
												class="rounded border border-gray-300 px-2 py-1 text-sm"
											/>
											<input
												bind:value={newProviderKeyEnv}
												placeholder="Env-variabel (f.eks. GEMINI_API_KEY)"
												class="rounded border border-gray-300 px-2 py-1 text-sm"
											/>
											<input
												bind:value={newProviderPriority}
												type="number"
												min="1"
												max="99"
												placeholder="Prioritet"
												class="rounded border border-gray-300 px-2 py-1 text-sm"
											/>
										</div>
										<div class="mt-2 flex gap-2">
											<button
												class="rounded-lg bg-blue-600 px-3 py-1 text-sm text-white hover:bg-blue-700 disabled:opacity-50"
												onclick={handleCreateProvider}
												disabled={actionLoading === 'create-provider' || !newProviderModel.trim()}
											>
												Legg til
											</button>
											<button
												class="rounded-lg px-3 py-1 text-sm text-gray-600 hover:bg-gray-100"
												onclick={() => (showNewProvider = null)}
											>
												Avbryt
											</button>
										</div>
									</div>
								{:else}
									<button
										class="mt-2 text-xs text-blue-600 hover:text-blue-800"
										onclick={() => (showNewProvider = alias.id)}
									>
										+ Legg til modell
									</button>
								{/if}
							</div>
						</section>
					{/each}

					<!-- Nytt alias -->
					{#if showNewAlias}
						<section class="rounded-lg border border-blue-200 bg-blue-50 p-5 shadow-sm">
							<h3 class="mb-3 text-sm font-semibold text-gray-800">Nytt modellalias</h3>
							<div class="flex gap-3">
								<input
									bind:value={newAliasName}
									placeholder="Alias (f.eks. sidelinja/lokal)"
									class="flex-1 rounded border border-gray-300 px-3 py-1.5 text-sm"
								/>
								<input
									bind:value={newAliasDesc}
									placeholder="Beskrivelse"
									class="flex-1 rounded border border-gray-300 px-3 py-1.5 text-sm"
								/>
							</div>
							<div class="mt-3 flex gap-2">
								<button
									class="rounded-lg bg-blue-600 px-4 py-1.5 text-sm text-white hover:bg-blue-700 disabled:opacity-50"
									onclick={handleCreateAlias}
									disabled={actionLoading === 'create-alias' || !newAliasName.trim()}
								>
									Opprett
								</button>
								<button
									class="rounded-lg px-4 py-1.5 text-sm text-gray-600 hover:bg-gray-100"
									onclick={() => (showNewAlias = false)}
								>
									Avbryt
								</button>
							</div>
						</section>
					{:else}
						<button
							class="rounded-lg border border-dashed border-gray-300 px-4 py-2 text-sm text-gray-500 hover:border-gray-400 hover:text-gray-700"
							onclick={() => (showNewAlias = true)}
						>
							+ Nytt modellalias
						</button>
					{/if}
				</div>

			<!-- === TAB: Ruting === -->
			{:else if activeTab === 'routing'}
				<div class="space-y-4">
					<div class="rounded-lg border border-gray-200 bg-white px-5 py-3 shadow-sm">
						<h2 class="text-sm font-semibold text-gray-800">AI-kontekster → Modellalias</h2>
						<p class="mt-1 text-xs text-gray-500">
							Hvilken modellalias brukes i hvilken kontekst. Endringer trer i kraft umiddelbart uten redeploy.
						</p>
					</div>

					{#each KNOWN_CONTEXTS as group}
						<section class="rounded-lg border border-gray-200 bg-white shadow-sm">
							<div class="border-b border-gray-100 px-5 py-2.5">
								<h3 class="text-xs font-semibold uppercase tracking-wide text-gray-500">
									{group.category}
								</h3>
							</div>
							<div class="divide-y divide-gray-100">
								{#each group.contexts as ctx}
									{@const routing = routingForContext(ctx.job_type)}
									<div class="flex items-center gap-3 px-5 py-3">
										<div class="flex-1">
											<div class="flex items-center gap-2">
												<span class="font-mono text-sm text-gray-800">{ctx.job_type}</span>
												{#if !routing}
													<span class="rounded bg-gray-100 px-1.5 py-0.5 text-[10px] text-gray-400">
														ikke konfigurert
													</span>
												{/if}
											</div>
											<p class="mt-0.5 text-xs text-gray-400">{ctx.description}</p>
										</div>
										<select
											class="rounded border border-gray-300 px-2 py-1 text-sm {!routing ? 'text-gray-400' : ''}"
											value={routing?.alias ?? ''}
											onchange={(e) => {
												const val = (e.target as HTMLSelectElement).value;
												if (val) {
													const r = routing ?? { job_type: ctx.job_type, alias: val, description: ctx.description };
													handleUpdateRouting(r, val);
												}
											}}
											disabled={actionLoading === `routing-${ctx.job_type}`}
										>
											{#if !routing}
												<option value="">Velg alias...</option>
											{/if}
											{#each data.aliases as alias}
												<option value={alias.alias}>{alias.alias}</option>
											{/each}
										</select>
										{#if routing}
											<button
												class="rounded px-2 py-1 text-xs text-red-500 hover:bg-red-50"
												onclick={() => handleDeleteRouting(ctx.job_type)}
												disabled={actionLoading === `delete-routing-${ctx.job_type}`}
											>
												Fjern
											</button>
										{/if}
									</div>
								{/each}
							</div>
						</section>
					{/each}

					<!-- Egendefinerte regler (ikke i kjente kontekster) -->
					{#if unknownRoutingRules().length > 0}
						<section class="rounded-lg border border-gray-200 bg-white shadow-sm">
							<div class="border-b border-gray-100 px-5 py-2.5">
								<h3 class="text-xs font-semibold uppercase tracking-wide text-gray-500">
									Egendefinerte
								</h3>
							</div>
							<div class="divide-y divide-gray-100">
								{#each unknownRoutingRules() as routing}
									<div class="flex items-center gap-3 px-5 py-3">
										<div class="flex-1">
											<span class="font-mono text-sm text-gray-800">{routing.job_type}</span>
											{#if routing.description}
												<p class="mt-0.5 text-xs text-gray-400">{routing.description}</p>
											{/if}
										</div>
										<select
											class="rounded border border-gray-300 px-2 py-1 text-sm"
											value={routing.alias}
											onchange={(e) => handleUpdateRouting(routing, (e.target as HTMLSelectElement).value)}
											disabled={actionLoading === `routing-${routing.job_type}`}
										>
											{#each data.aliases as alias}
												<option value={alias.alias}>{alias.alias}</option>
											{/each}
										</select>
										<button
											class="rounded px-2 py-1 text-xs text-red-500 hover:bg-red-50"
											onclick={() => handleDeleteRouting(routing.job_type)}
											disabled={actionLoading === `delete-routing-${routing.job_type}`}
										>
											Fjern
										</button>
									</div>
								{/each}
							</div>
						</section>
					{/if}

					<!-- Ny egendefinert ruting -->
					{#if showNewRouting}
						<section class="rounded-lg border border-blue-200 bg-blue-50 p-5 shadow-sm">
							<h3 class="mb-3 text-sm font-semibold text-gray-800">Ny egendefinert rutingregel</h3>
							<div class="flex gap-2">
								<input
									bind:value={newRoutingJobType}
									placeholder="Jobbtype (f.eks. min_jobb)"
									class="flex-1 rounded border border-gray-300 px-2 py-1 text-sm"
								/>
								<select
									bind:value={newRoutingAlias}
									class="rounded border border-gray-300 px-2 py-1 text-sm"
								>
									<option value="">Velg alias...</option>
									{#each data.aliases as alias}
										<option value={alias.alias}>{alias.alias}</option>
									{/each}
								</select>
								<input
									bind:value={newRoutingDesc}
									placeholder="Beskrivelse (valgfri)"
									class="flex-1 rounded border border-gray-300 px-2 py-1 text-sm"
								/>
							</div>
							<div class="mt-2 flex gap-2">
								<button
									class="rounded-lg bg-blue-600 px-3 py-1 text-sm text-white hover:bg-blue-700 disabled:opacity-50"
									onclick={handleCreateRouting}
									disabled={actionLoading === 'create-routing' ||
										!newRoutingJobType.trim() ||
										!newRoutingAlias.trim()}
								>
									Legg til
								</button>
								<button
									class="rounded-lg px-3 py-1 text-sm text-gray-600 hover:bg-gray-100"
									onclick={() => (showNewRouting = false)}
								>
									Avbryt
								</button>
							</div>
						</section>
					{:else}
						<button
							class="rounded-lg border border-dashed border-gray-300 px-4 py-2 text-sm text-gray-500 hover:border-gray-400 hover:text-gray-700"
							onclick={() => (showNewRouting = true)}
						>
							+ Ny egendefinert rutingregel
						</button>
					{/if}
				</div>

			<!-- === TAB: Forbruk === -->
			{:else if activeTab === 'usage'}
				<section class="rounded-lg border border-gray-200 bg-white shadow-sm">
					<div class="flex items-center justify-between border-b border-gray-100 px-5 py-3">
						<h2 class="text-sm font-semibold text-gray-800">Forbruksoversikt</h2>
						<select
							class="rounded border border-gray-300 px-2 py-1 text-sm"
							bind:value={usageDays}
						>
							<option value={7}>Siste 7 dager</option>
							<option value={30}>Siste 30 dager</option>
							<option value={90}>Siste 90 dager</option>
						</select>
					</div>

					{#if data.usage.length === 0}
						<p class="px-5 py-8 text-center text-sm text-gray-400">Ingen AI-forbruk registrert.</p>
					{:else}
						<!-- Totaler -->
						{@const totalTokens = data.usage.reduce((s, u) => s + u.total_tokens, 0)}
						{@const totalCost = data.usage.reduce((s, u) => s + u.estimated_cost, 0)}
						{@const totalCalls = data.usage.reduce((s, u) => s + u.call_count, 0)}
						<div class="grid grid-cols-3 gap-3 border-b border-gray-100 px-5 py-4">
							<div>
								<div class="text-xs text-gray-500">Totalt tokens</div>
								<div class="text-lg font-semibold text-gray-900">{formatTokens(totalTokens)}</div>
							</div>
							<div>
								<div class="text-xs text-gray-500">Estimert kostnad</div>
								<div class="text-lg font-semibold text-gray-900">{formatCost(totalCost)}</div>
							</div>
							<div>
								<div class="text-xs text-gray-500">Antall kall</div>
								<div class="text-lg font-semibold text-gray-900">{totalCalls}</div>
							</div>
						</div>

						<!-- Tabell -->
						<div class="overflow-x-auto">
							<table class="w-full text-sm">
								<thead>
									<tr class="border-b border-gray-100 bg-gray-50 text-left text-xs text-gray-500">
										<th class="px-5 py-2">Samling</th>
										<th class="px-3 py-2">Alias</th>
										<th class="px-3 py-2">Jobbtype</th>
										<th class="px-3 py-2 text-right">Tokens</th>
										<th class="px-3 py-2 text-right">Kostnad</th>
										<th class="px-3 py-2 text-right">Kall</th>
									</tr>
								</thead>
								<tbody class="divide-y divide-gray-50">
									{#each data.usage as row}
										<tr class="hover:bg-gray-50">
											<td class="px-5 py-2 text-gray-700">
												{row.collection_title ?? '(ingen samling)'}
											</td>
											<td class="px-3 py-2 font-mono text-xs text-gray-600">
												{row.model_alias}
											</td>
											<td class="px-3 py-2 font-mono text-xs text-gray-600">
												{row.job_type ?? '—'}
											</td>
											<td class="px-3 py-2 text-right text-gray-700">
												{formatTokens(row.total_tokens)}
											</td>
											<td class="px-3 py-2 text-right text-gray-700">
												{formatCost(row.estimated_cost)}
											</td>
											<td class="px-3 py-2 text-right text-gray-700">{row.call_count}</td>
										</tr>
									{/each}
								</tbody>
							</table>
						</div>
					{/if}
				</section>

			<!-- === TAB: API-nøkler === -->
			{:else if activeTab === 'keys'}
				<section class="rounded-lg border border-gray-200 bg-white shadow-sm">
					<div class="border-b border-gray-100 px-5 py-3">
						<h2 class="text-sm font-semibold text-gray-800">API-nøkler</h2>
						<p class="mt-1 text-xs text-gray-500">
							Nøklene er lagret som miljøvariabler på serveren. Verdier vises aldri i admin-panelet.
						</p>
					</div>
					<div class="divide-y divide-gray-100">
						{#each data.api_key_status as key}
							<div class="flex items-center gap-3 px-5 py-3">
								<span
									class="h-2 w-2 rounded-full {key.is_set ? 'bg-green-500' : 'bg-red-400'}"
								></span>
								<span class="font-mono text-sm text-gray-800">{key.env_var}</span>
								<span class="text-xs {key.is_set ? 'text-green-600' : 'text-red-500'}">
									{key.is_set ? 'Satt' : 'Mangler'}
								</span>
							</div>
						{/each}

						{#if data.api_key_status.length === 0}
							<p class="px-5 py-4 text-sm text-gray-400">Ingen API-nøkler konfigurert.</p>
						{/if}
					</div>
					<div class="border-t border-gray-100 px-5 py-3">
						<p class="text-xs text-gray-400">
							For å endre API-nøkler, oppdater <code class="rounded bg-gray-100 px-1">/srv/synops/.env</code> og restart maskinrommet.
						</p>
					</div>
				</section>
			{/if}
		{/if}
	</main>
</div>
