<script lang="ts">
	import { t } from 'svelte-i18n';
	import { SvelteSet } from 'svelte/reactivity';

	interface DiscoveredService {
		name: string;
		url: string;
		source: 'docker' | 'traefik';
		icon?: string;
		description?: string;
		alreadyRegistered: boolean;
	}

	let {
		dockerSocketPath = $bindable('/var/run/docker.sock'),
		traefikApiUrl = $bindable('')
	}: {
		dockerSocketPath?: string;
		traefikApiUrl?: string;
	} = $props();

	let scanning = $state(false);
	let approving = $state(false);
	let services = $state<DiscoveredService[]>([]);
	let scanErrors = $state<string[]>([]);
	let selected = new SvelteSet<number>();
	let statusMessage = $state('');
	let statusType: 'success' | 'error' | '' = $state('');

	function clearStatus() {
		statusMessage = '';
		statusType = '';
	}

	async function handleScan() {
		clearStatus();
		scanning = true;
		services = [];
		scanErrors = [];
		selected.clear();

		try {
			const response = await fetch('/api/admin/discover', {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({
					dockerSocketPath: dockerSocketPath || undefined,
					traefikApiUrl: traefikApiUrl || undefined
				})
			});

			const result = await response.json();

			if (!response.ok || !result.success) {
				throw new Error(result.error || 'Discovery scan failed');
			}

			services = result.data.services;
			scanErrors = result.data.errors;

			if (services.length === 0) {
				statusMessage = $t('admin.discovery_no_results');
				statusType = 'error';
			}
		} catch (err) {
			statusMessage = err instanceof Error ? err.message : 'Scan failed';
			statusType = 'error';
		} finally {
			scanning = false;
		}
	}

	function toggleSelect(index: number) {
		if (selected.has(index)) {
			selected.delete(index);
		} else {
			selected.add(index);
		}
	}

	function toggleSelectAll() {
		const selectableIndices = services
			.map((s, i) => (s.alreadyRegistered ? -1 : i))
			.filter((i) => i >= 0);

		const allSelected = selected.size === selectableIndices.length;
		selected.clear();
		if (!allSelected) {
			for (const idx of selectableIndices) {
				selected.add(idx);
			}
		}
	}

	async function handleApprove() {
		if (selected.size === 0) return;

		clearStatus();
		approving = true;

		const toApprove = Array.from(selected).map((i) => services[i]);

		try {
			const response = await fetch('/api/admin/discover/approve', {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ services: toApprove })
			});

			const result = await response.json();

			if (!response.ok || !result.success) {
				throw new Error(result.error || 'Approval failed');
			}

			const { created, errors: approveErrors } = result.data;
			const parts: string[] = [];
			if (created > 0) parts.push(`${created} app(s) created`);
			if (approveErrors.length > 0) parts.push(approveErrors.join('; '));

			statusMessage = `${$t('admin.discovery_approve')}: ${parts.join('. ')}`;
			statusType = approveErrors.length > 0 ? 'error' : 'success';

			// Mark approved services as registered
			services = services.map((s, i) =>
				selected.has(i) ? { ...s, alreadyRegistered: true } : s
			);
			selected.clear();
		} catch (err) {
			statusMessage = err instanceof Error ? err.message : 'Approval failed';
			statusType = 'error';
		} finally {
			approving = false;
		}
	}

	const selectableCount = $derived(services.filter((s) => !s.alreadyRegistered).length);
</script>

<section class="rounded-lg border border-border bg-card p-6">
	<h2 class="mb-4 text-lg font-semibold text-card-foreground">{$t('admin.discovery_title')}</h2>
	<p class="mb-6 text-xs text-muted-foreground">{$t('admin.discovery_description')}</p>

	<!-- Scan Button -->
	<div class="mb-6">
		<button
			type="button"
			onclick={handleScan}
			disabled={scanning || (!dockerSocketPath && !traefikApiUrl)}
			class="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
		>
			{scanning ? $t('admin.discovery_scanning') : $t('admin.discovery_scan')}
		</button>
	</div>

	<!-- Scan Errors -->
	{#if scanErrors.length > 0}
		<div class="mb-4 rounded-md bg-yellow-100 p-3 text-sm text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400">
			{#each scanErrors as scanError, idx (idx)}
				<p>{scanError}</p>
			{/each}
		</div>
	{/if}

	<!-- Results Table -->
	{#if services.length > 0}
		<div class="overflow-x-auto">
			<table class="w-full text-sm">
				<thead>
					<tr class="border-b border-border">
						<th class="px-2 py-2 text-left">
							<input
								type="checkbox"
								checked={selected.size === selectableCount && selectableCount > 0}
								onchange={toggleSelectAll}
								disabled={selectableCount === 0}
								class="h-4 w-4 rounded border-input"
							/>
						</th>
						<th class="px-2 py-2 text-left font-medium text-muted-foreground">{$t('common.name')}</th>
						<th class="px-2 py-2 text-left font-medium text-muted-foreground">URL</th>
						<th class="px-2 py-2 text-left font-medium text-muted-foreground">{$t('admin.discovery_source')}</th>
						<th class="px-2 py-2 text-left font-medium text-muted-foreground">{$t('admin.discovery_status')}</th>
					</tr>
				</thead>
				<tbody>
					{#each services as service, i (service.url)}
						<tr class="border-b border-border/50 hover:bg-muted/50">
							<td class="px-2 py-2">
								<input
									type="checkbox"
									checked={selected.has(i)}
									onchange={() => toggleSelect(i)}
									disabled={service.alreadyRegistered}
									class="h-4 w-4 rounded border-input"
								/>
							</td>
							<td class="px-2 py-2 font-medium text-foreground">{service.name}</td>
							<td class="px-2 py-2">
								<a href={service.url} target="_blank" rel="noopener noreferrer" class="text-primary hover:underline">
									{service.url}
								</a>
							</td>
							<td class="px-2 py-2">
								<span class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium
									{service.source === 'docker'
										? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'
										: 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400'
									}"
								>
									{service.source === 'docker' ? $t('admin.discovery_source_docker') : $t('admin.discovery_source_traefik')}
								</span>
							</td>
							<td class="px-2 py-2">
								{#if service.alreadyRegistered}
									<span class="text-xs text-muted-foreground">{$t('admin.discovery_already_registered')}</span>
								{:else}
									<span class="text-xs font-medium text-green-600 dark:text-green-400">{$t('admin.discovery_new')}</span>
								{/if}
							</td>
						</tr>
					{/each}
				</tbody>
			</table>
		</div>

		<!-- Approve button -->
		{#if selectableCount > 0}
			<div class="mt-4">
				<button
					type="button"
					onclick={handleApprove}
					disabled={approving || selected.size === 0}
					class="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
				>
					{approving ? $t('admin.discovery_approving') : $t('admin.discovery_approve')} ({selected.size})
				</button>
			</div>
		{/if}
	{/if}

	<!-- Status Message -->
	{#if statusMessage}
		<div class="mt-4 rounded-md p-3 text-sm {statusType === 'success' ? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400' : 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400'}">
			{statusMessage}
		</div>
	{/if}
</section>
