<script lang="ts">
	import Navbar from '$lib/components/Navbar.svelte';
	import Footer from '$lib/components/Footer.svelte';

	// API Base - uses env var for local dev, defaults to cockpit for production
	const API_BASE = (import.meta.env.VITE_API_URL || 'https://cockpit.valuecurve.co') + '/api/v1';

	// ============================================
	// TRUE CLIENT-SIDE PII DETECTION (Browser-Only)
	// ============================================
	// These regex patterns are ported from backend - text never leaves browser
	// Base confidence values aligned with backend after context adjustment
	// Backend adjusts: +0.10 per context keyword, -0.30 for test data, range 0.3-0.99
	const PII_PATTERNS: Record<string, { pattern: RegExp; description: string; category: string; confidence: number }> = {
		EMAIL: {
			pattern: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/gi,
			description: "Email addresses",
			category: "pii",
			confidence: 0.75  // Backend base ~0.65-0.85 after context
		},
		EMAIL_OBFUSCATED: {
			pattern: /[A-Za-z0-9](?:[-\s]*[A-Za-z0-9]){2,}\s*(?:\[at\]|\(at\))\s*[A-Za-z0-9](?:[-\s]*[A-Za-z0-9]){2,}\s*(?:\[dot\]|\(dot\)|\s+dot\s+)\s*[A-Za-z]{2,}/gi,
			description: "Obfuscated email addresses",
			category: "pii",
			confidence: 0.85
		},
		PHONE_US: {
			pattern: /\b(?:\+?1[-.\s]?)?\(?[0-9]{3}\)?[-.\s]?[0-9]{3}[-.\s]?[0-9]{4}\b/g,
			description: "US Phone numbers",
			category: "pii",
			confidence: 0.65  // Backend returns ~0.65 for phones
		},
		PHONE_INTL: {
			pattern: /\+(?:49|44|33|39|34|31|32|43|41|48|351|353|358|47|46|45|420|36|40|359|385|386|421|370|371|372|352|356|357|30|55|52|54|56|57|51|81|82|86|91|61|64|65|852)\s?[0-9]{1,4}[\s-]?[0-9]{3,4}[\s-]?[0-9]{3,6}\b/g,
			description: "International Phone numbers",
			category: "pii",
			confidence: 0.65
		},
		SSN: {
			pattern: /\b\d{3}[-.\s_]\d{2}[-.\s_]\d{4}\b/g,
			description: "Social Security Numbers",
			category: "pii",
			confidence: 0.75  // Backend returns ~0.75 for SSN
		},
		CREDIT_CARD: {
			pattern: /\b(?:4[0-9]{3}[-\s]?[0-9]{4}[-\s]?[0-9]{4}[-\s]?[0-9]{4}|5[1-5][0-9]{2}[-\s]?[0-9]{4}[-\s]?[0-9]{4}[-\s]?[0-9]{4}|3[47][0-9]{2}[-\s]?[0-9]{6}[-\s]?[0-9]{5}|6(?:011|5[0-9]{2})[-\s]?[0-9]{4}[-\s]?[0-9]{4}[-\s]?[0-9]{4})\b/g,
			description: "Credit card numbers",
			category: "financial",
			confidence: 0.99  // Backend boosts valid Luhn to 0.99
		},
		IP_ADDRESS: {
			pattern: /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/g,
			description: "IP addresses",
			category: "pii",
			confidence: 0.65  // Backend returns ~0.65 for IPs
		},
		DATE_OF_BIRTH: {
			pattern: /\b(?:(?:0?[1-9]|1[0-2])[/-](?:0?[1-9]|[12][0-9]|3[01])[/-](?:19|20)\d{2}|(?:19|20)\d{2}[-/](?:0?[1-9]|1[0-2])[-/](?:0?[1-9]|[12][0-9]|3[01]))\b/g,
			description: "Dates",
			category: "pii",
			confidence: 0.65
		},
		US_ADDRESS: {
			pattern: /\b\d{1,5}\s+(?:[A-Za-z]+\s+){1,4}(?:Street|St|Avenue|Ave|Road|Rd|Boulevard|Blvd|Drive|Dr|Lane|Ln|Court|Ct|Way|Place|Pl)\.?/gi,
			description: "US addresses",
			category: "pii",
			confidence: 0.75
		},
		IBAN: {
			pattern: /\b(?:DE|GB|FR|ES|IT|NL|BE|AT|CH|PL|PT|IE|FI|NO|SE|DK)\d{2}[\s]?[A-Z0-9]{4}[\s]?[A-Z0-9]{4}[\s]?[A-Z0-9]{4}[\s]?[A-Z0-9]{0,18}\b/g,
			description: "IBAN",
			category: "financial",
			confidence: 0.90
		},
		INDIA_AADHAAR: {
			pattern: /\b[2-9]\d{3}[\s-]?\d{4}[\s-]?\d{4}\b/g,
			description: "India Aadhaar numbers",
			category: "pii",
			confidence: 0.75
		},
		AWS_ACCESS_KEY: {
			pattern: /\b(?:AKIA|ABIA|ACCA|ASIA)[A-Z0-9]{16}\b/g,
			description: "AWS Access Key IDs",
			category: "secret",
			confidence: 0.99
		},
		GITHUB_TOKEN: {
			pattern: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b/g,
			description: "GitHub Tokens",
			category: "secret",
			confidence: 0.99
		},
		SLACK_TOKEN: {
			pattern: /\bxox[baprs]-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9-]*\b/g,
			description: "Slack Tokens",
			category: "secret",
			confidence: 0.99
		},
		STRIPE_KEY: {
			pattern: /\b(?:sk|pk)_(?:test|live)_[A-Za-z0-9]{8,}\b/g,
			description: "Stripe API Keys",
			category: "secret",
			confidence: 0.99
		},
		GOOGLE_API_KEY: {
			pattern: /\bAIza[A-Za-z0-9_-]{35}\b/g,
			description: "Google API Keys",
			category: "secret",
			confidence: 0.99
		},
		JWT_TOKEN: {
			pattern: /\beyJ[A-Za-z0-9_-]*\.eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*\b/g,
			description: "JWT Tokens",
			category: "secret",
			confidence: 0.90
		},
		PRIVATE_KEY: {
			pattern: /-----BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY-----/g,
			description: "Private key headers",
			category: "secret",
			confidence: 0.99
		},
		PASSWORD_IN_URL: {
			pattern: /(?:password|passwd|pwd|pass)["']?\s*(?:[:=])\s*["']?([^\s"'&,]{6,})["']?/gi,
			description: "Passwords in plaintext",
			category: "secret",
			confidence: 0.85
		}
	};

	interface DetectedEntity {
		type: string;
		start: number;
		end: number;
		value: string;
		masked_value: string;
		confidence: number;
		length: number;
	}

	function detectPIIClientSide(text: string, options: {
		detectEmails: boolean;
		detectPhones: boolean;
		detectSSN: boolean;
		detectCreditCards: boolean;
		detectIPAddresses: boolean;
		detectDates: boolean;
		detectAddresses: boolean;
		detectIBAN: boolean;
		detectSecrets: boolean;
	}): DetectedEntity[] {
		const entities: DetectedEntity[] = [];

		// Map options to pattern types
		const enabledPatterns: string[] = [];
		if (options.detectEmails) enabledPatterns.push('EMAIL', 'EMAIL_OBFUSCATED');
		if (options.detectPhones) enabledPatterns.push('PHONE_US', 'PHONE_INTL');
		if (options.detectSSN) enabledPatterns.push('SSN', 'INDIA_AADHAAR');
		if (options.detectCreditCards) enabledPatterns.push('CREDIT_CARD');
		if (options.detectIPAddresses) enabledPatterns.push('IP_ADDRESS');
		if (options.detectDates) enabledPatterns.push('DATE_OF_BIRTH');
		if (options.detectAddresses) enabledPatterns.push('US_ADDRESS');
		if (options.detectIBAN) enabledPatterns.push('IBAN');
		if (options.detectSecrets) {
			enabledPatterns.push('AWS_ACCESS_KEY', 'GITHUB_TOKEN', 'SLACK_TOKEN',
				'STRIPE_KEY', 'GOOGLE_API_KEY', 'JWT_TOKEN', 'PRIVATE_KEY', 'PASSWORD_IN_URL');
		}

		for (const patternName of enabledPatterns) {
			const patternDef = PII_PATTERNS[patternName];
			if (!patternDef) continue;

			// Create new regex to reset lastIndex
			const regex = new RegExp(patternDef.pattern.source, patternDef.pattern.flags);
			let match;

			while ((match = regex.exec(text)) !== null) {
				const value = match[0];
				const maxLen = 35;
				entities.push({
					type: patternName,
					start: match.index,
					end: match.index + value.length,
					value: value.length > maxLen ? value.slice(0, maxLen) + '...' : value,
					masked_value: ('*'.repeat(value.length)).slice(0, maxLen) + (value.length > maxLen ? '...' : ''),
					confidence: patternDef.confidence,
					length: value.length
				});
			}
		}

		// Sort by confidence (highest first), then by length (longest first) for overlap resolution
		entities.sort((a, b) => {
			if (b.confidence !== a.confidence) return b.confidence - a.confidence;
			return b.length - a.length;
		});

		// Remove overlaps - keep highest confidence/longest matches
		const filtered: DetectedEntity[] = [];
		for (const entity of entities) {
			const overlaps = filtered.some(e =>
				(entity.start >= e.start && entity.start < e.end) ||
				(entity.end > e.start && entity.end <= e.end) ||
				(entity.start <= e.start && entity.end >= e.end)
			);
			if (!overlaps) {
				filtered.push(entity);
			}
		}

		// Re-sort by position for display
		filtered.sort((a, b) => a.start - b.start);

		return filtered;
	}
	// ============================================

	let inputMode: 'text' | 'file' = $state('text');
	let textInput = $state('');
	let file: File | null = $state(null);
	let fileName = $state('');
	let loading = $state(false);
	let error = $state('');
	let result: any = $state(null);
	let activeTab: 'overview' | 'entities' | 'redacted' = $state('overview');

	// Detection options
	let detectEmails = $state(true);
	let detectPhones = $state(true);
	let detectSSN = $state(true);
	let detectCreditCards = $state(true);
	let detectIPAddresses = $state(true);
	let detectDates = $state(true);
	let detectAddresses = $state(true);
	let detectIBAN = $state(true);
	let detectSecrets = $state(true);

	// Security option: Client-side redaction mode
	let coordinatesOnly = $state(false);

	function clientSideRedact(text: string, entities: Array<{start: number, end: number, type: string, length: number}>): string {
		if (!entities || entities.length === 0) return text;
		const sorted = [...entities].sort((a, b) => b.start - a.start);
		let resultText = text;
		for (const entity of sorted) {
			const masked = '*'.repeat(entity.length);
			resultText = resultText.slice(0, entity.start) + masked + resultText.slice(entity.end);
		}
		return resultText;
	}

	function handleFileSelect(event: Event) {
		const input = event.target as HTMLInputElement;
		if (input.files && input.files[0]) {
			file = input.files[0];
			fileName = file.name;
			result = null;
			error = '';
		}
	}

	function handleDrop(event: DragEvent) {
		event.preventDefault();
		if (event.dataTransfer?.files && event.dataTransfer.files[0]) {
			file = event.dataTransfer.files[0];
			fileName = file.name;
			result = null;
			error = '';
		}
	}

	function handleDragOver(event: DragEvent) {
		event.preventDefault();
	}

	async function scanForPII() {
		if (inputMode === 'text' && !textInput.trim()) {
			error = 'Please enter some text to scan';
			return;
		}
		if (inputMode === 'file' && !file) {
			error = 'Please select a file first';
			return;
		}

		loading = true;
		error = '';
		result = null;

		try {
			// ============================================
			// TRUE CLIENT-SIDE MODE: No network request!
			// ============================================
			if (coordinatesOnly && inputMode === 'text') {
				console.log('%c[Privacy Scanner] Browser-Only Mode: All detection running locally. ZERO network requests.', 'color: #22c55e; font-weight: bold;');
				const normalizedText = textInput.replace(/\r\n/g, '\n');

				const entities = detectPIIClientSide(normalizedText, {
					detectEmails, detectPhones, detectSSN, detectCreditCards,
					detectIPAddresses, detectDates, detectAddresses, detectIBAN, detectSecrets
				});

				// Build result object matching backend format
				const entitiesByType: Record<string, number> = {};
				for (const e of entities) {
					entitiesByType[e.type] = (entitiesByType[e.type] || 0) + 1;
				}

				// Calculate risk score (matches backend formula)
				const riskWeights: Record<string, number> = {
					SSN: 100, CREDIT_CARD: 95, PRIVATE_KEY: 100, INDIA_AADHAAR: 90,
					AWS_ACCESS_KEY: 100, GITHUB_TOKEN: 95,
					STRIPE_KEY: 95, PASSWORD_IN_URL: 90, JWT_TOKEN: 85,
					IBAN: 85, EMAIL: 40, EMAIL_OBFUSCATED: 40, PHONE_US: 35, PHONE_INTL: 35,
					IP_ADDRESS: 30, DATE_OF_BIRTH: 50, US_ADDRESS: 55,
					SLACK_TOKEN: 90, GOOGLE_API_KEY: 85
				};

				let totalScore = 0;
				for (const e of entities) {
					const weight = riskWeights[e.type] || 25;
					totalScore += weight * e.confidence;
				}
				// Backend formula: (average score) + (entity count * 5)
				const riskScore = Math.min(100, Math.floor(totalScore / Math.max(1, entities.length) + entities.length * 5));

				// Backend thresholds: 70=CRITICAL, 50=HIGH, 30=MEDIUM
				const riskLevel = riskScore >= 70 ? 'CRITICAL'
					: riskScore >= 50 ? 'HIGH'
					: riskScore >= 30 ? 'MEDIUM'
					: 'LOW';

				result = {
					total_entities: entities.length,
					entities_by_type: entitiesByType,
					entities: entities,
					risk_score: riskScore,
					risk_level: riskLevel,
					redacted_preview: clientSideRedact(normalizedText, entities),
					coordinates_only: true,
					client_side_only: true  // Flag to indicate true client-side
				};
			} else {
				// ============================================
				// BACKEND MODE: Send to server
				// ============================================
				let response;

				if (inputMode === 'text') {
					const normalizedText = textInput.replace(/\r\n/g, '\n');

					const formData = new FormData();
					formData.append('text', normalizedText);
					formData.append('detect_emails', String(detectEmails));
					formData.append('detect_phones', String(detectPhones));
					formData.append('detect_ssn', String(detectSSN));
					formData.append('detect_credit_cards', String(detectCreditCards));
					formData.append('detect_ip_addresses', String(detectIPAddresses));
					formData.append('detect_dates', String(detectDates));
					formData.append('detect_addresses', String(detectAddresses));
					formData.append('detect_iban', String(detectIBAN));
					formData.append('detect_secrets', String(detectSecrets));
					formData.append('coordinates_only', 'false');

					response = await fetch(`${API_BASE}/privacy/scan-text`, {
						method: 'POST',
						body: formData
					});
				} else {
					const formData = new FormData();
					formData.append('file', file!);

					response = await fetch(`${API_BASE}/privacy/scan-file`, {
						method: 'POST',
						body: formData
					});
				}

				if (!response.ok) {
					const errData = await response.json();
					throw new Error(errData.detail || 'Scan failed');
				}

				result = await response.json();
			}
		} catch (e) {
			error = e instanceof Error ? e.message : 'Failed to scan for PII';
		} finally {
			loading = false;
		}
	}

	function getRiskColor(level: string): string {
		switch (level) {
			case 'CRITICAL':
				return 'text-red-700 bg-red-50 border-red-200';
			case 'HIGH':
				return 'text-orange-700 bg-orange-50 border-orange-200';
			case 'MEDIUM':
				return 'text-yellow-700 bg-yellow-50 border-yellow-200';
			default:
				return 'text-green-700 bg-green-50 border-green-200';
		}
	}

	function getPIITypeIcon(type: string): string {
		switch (type) {
			case 'EMAIL': return '@';
			case 'PHONE_US':
			case 'PHONE_INTL': return '#';
			case 'SSN': return 'SSN';
			case 'CREDIT_CARD': return '$';
			case 'IP_ADDRESS': return 'IP';
			case 'DATE_OF_BIRTH': return 'DOB';
			case 'US_ADDRESS':
			case 'UK_ADDRESS':
			case 'EU_ADDRESS': return 'ADR';
			case 'IBAN':
			case 'BANK_ACCOUNT': return 'BNK';
			case 'AWS_ACCESS_KEY':
			case 'AWS_SECRET_KEY': return 'AWS';
			case 'GITHUB_TOKEN': return 'GH';
			case 'STRIPE_KEY': return 'STR';
			case 'GOOGLE_API_KEY': return 'GCP';
			case 'PASSWORD_IN_URL': return 'PWD';
			case 'PRIVATE_KEY': return 'KEY';
			case 'JWT_TOKEN': return 'JWT';
			case 'SLACK_TOKEN': return 'SLK';
			case 'GENERIC_API_KEY': return 'API';
			default: return '?';
		}
	}

	function getPIITypeColor(type: string): string {
		switch (type) {
			case 'SSN':
			case 'CREDIT_CARD':
			case 'IBAN':
			case 'BANK_ACCOUNT':
				return 'bg-red-100 text-red-700 border-red-200';
			case 'AWS_ACCESS_KEY':
			case 'AWS_SECRET_KEY':
			case 'PRIVATE_KEY':
			case 'PASSWORD_IN_URL':
			case 'GITHUB_TOKEN':
			case 'STRIPE_KEY':
				return 'bg-purple-100 text-purple-700 border-purple-200';
			case 'GOOGLE_API_KEY':
			case 'SLACK_TOKEN':
			case 'JWT_TOKEN':
			case 'GENERIC_API_KEY':
				return 'bg-orange-100 text-orange-700 border-orange-200';
			case 'EMAIL':
			case 'PHONE_US':
			case 'PHONE_INTL':
				return 'bg-yellow-100 text-yellow-700 border-yellow-200';
			case 'US_ADDRESS':
			case 'UK_ADDRESS':
			case 'EU_ADDRESS':
				return 'bg-amber-100 text-amber-700 border-amber-200';
			default:
				return 'bg-blue-100 text-blue-700 border-blue-200';
		}
	}

	let copySuccess = $state(false);
	async function copyToClipboard() {
		if (!result || !result.entities || result.entities.length === 0) return;
		const header = 'Type\tOriginal Value\tMasked Value\tConfidence';
		const rows = result.entities.map((e: any) =>
			`${e.type}\t${e.value}\t${e.masked_value}\t${Math.round(e.confidence * 100)}%`
		);
		const text = [header, ...rows].join('\n');
		try {
			await navigator.clipboard.writeText(text);
			copySuccess = true;
			setTimeout(() => copySuccess = false, 2000);
		} catch (err) {
			console.error('Failed to copy:', err);
		}
	}

	let copyRedactedSuccess = $state(false);
	async function copyRedactedToClipboard() {
		if (!result || !result.redacted_preview) return;
		try {
			await navigator.clipboard.writeText(result.redacted_preview);
			copyRedactedSuccess = true;
			setTimeout(() => copyRedactedSuccess = false, 2000);
		} catch (err) {
			console.error('Failed to copy:', err);
		}
	}

	function loadSampleText() {
		textInput = `Customer Record:
Name: John Smith
Email: john.smith@example.com
US Phone: (555) 123-4567
SSN: 123-45-6789
Credit Card: 4532 0151 1283 0366
IP Address: 192.168.1.100

--- CLOUD SECRETS ---
AWS Key: AKIAIOSFODNN7EXAMPLE
GitHub Token: ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Please contact support@company.org for assistance.`;
	}

	function clearAll() {
		textInput = '';
		file = null;
		fileName = '';
		result = null;
		error = '';
	}
</script>

<svelte:head>
	<title>Privacy Scanner | Build with AI</title>
	<meta name="description" content="Detect and redact personally identifiable information (PII) from text and files." />
</svelte:head>

<div class="min-h-screen bg-gradient-to-b from-slate-50 to-white">
	<Navbar />

	<main class="pt-20 pb-10 px-5">
		<div class="max-w-6xl mx-auto">
			<!-- Header -->
			<div class="mb-5 flex items-center justify-between">
				<div class="flex items-center gap-4">
					<a href="/tools/" class="text-sm text-primary-600 hover:text-primary-700">&larr; Tools</a>
					<h1 class="text-2xl font-bold text-gray-900">Privacy Scanner</h1>
					<span class="text-gray-400 text-sm hidden sm:inline">|</span>
					<p class="text-gray-500 text-sm hidden sm:inline">Detect & redact PII from text and files</p>
				</div>
			</div>

			<div class="grid grid-cols-1 lg:grid-cols-3 gap-5">
				<!-- Input Section -->
				<div class="bg-white rounded-xl border border-gray-100 shadow-sm p-5">
					<h2 class="text-base font-bold text-gray-900 mb-3">Input</h2>

					<!-- Mode Toggle -->
					<div class="flex gap-1 mb-3 p-1 bg-gray-100 rounded-lg">
						<button
							class="flex-1 py-2 px-3 text-sm font-medium rounded-md transition-all {inputMode === 'text'
								? 'bg-white text-primary-600 shadow-sm'
								: 'text-gray-500 hover:text-gray-700'}"
							onclick={() => (inputMode = 'text')}
						>
							Text
						</button>
						<button
							class="flex-1 py-2 px-3 text-sm font-medium rounded-md transition-all {inputMode === 'file'
								? 'bg-white text-primary-600 shadow-sm'
								: 'text-gray-500 hover:text-gray-700'}"
							onclick={() => (inputMode = 'file')}
						>
							File
						</button>
					</div>

					{#if inputMode === 'text'}
						<div class="space-y-3">
							<div class="flex justify-between items-center">
								<label for="text-input" class="text-sm font-medium text-gray-700">Text to Scan</label>
								<div class="flex gap-2">
									<button
										class="text-xs text-primary-600 hover:text-primary-700"
										onclick={loadSampleText}
									>
										Load Sample
									</button>
									{#if textInput || result}
										<span class="text-gray-300">|</span>
										<button
											class="text-xs text-gray-500 hover:text-red-600"
											onclick={clearAll}
										>
											Clear
										</button>
									{/if}
								</div>
							</div>
							<textarea
								id="text-input"
								bind:value={textInput}
								placeholder="Paste text containing potential PII here..."
								class="w-full px-3 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 min-h-[150px] resize-none font-mono text-xs"
							></textarea>
						</div>
					{:else}
						<!-- Drop Zone -->
						<div
							class="border-2 border-dashed border-gray-300 rounded-xl p-6 text-center hover:border-primary-400 transition-colors cursor-pointer"
							ondrop={handleDrop}
							ondragover={handleDragOver}
							role="button"
							tabindex="0"
						>
							<input
								type="file"
								accept=".csv,.txt,.json"
								onchange={handleFileSelect}
								class="hidden"
								id="file-input"
							/>
							<label for="file-input" class="cursor-pointer">
								<div class="w-12 h-12 rounded-xl bg-primary-100 flex items-center justify-center mx-auto mb-3">
									<svg class="w-6 h-6 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
										<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
									</svg>
								</div>
								<p class="text-sm text-gray-600">
									<span class="text-primary-600 font-medium">Click to upload</span> or drag and drop
								</p>
								<p class="text-xs text-gray-400 mt-1">CSV, TXT, or JSON files</p>
							</label>
						</div>

						{#if fileName}
							<div class="mt-3 flex items-center gap-2 p-2 bg-gray-50 rounded-lg">
								<svg class="w-4 h-4 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
									<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
								</svg>
								<span class="text-sm text-gray-700 truncate flex-1">{fileName}</span>
							</div>
						{/if}
					{/if}

					<!-- Detection Options -->
					<div class="mt-4 pt-3 border-t border-gray-200">
						<div class="flex items-center justify-between mb-2">
							<h3 class="text-xs font-semibold text-gray-500 uppercase">PII Detection</h3>
							<label class="flex items-center gap-1.5 cursor-pointer text-xs">
								<input type="checkbox" bind:checked={detectSecrets} class="rounded text-primary-600" />
								<span class="text-gray-600">Secrets</span>
							</label>
						</div>
						<div class="grid grid-cols-4 gap-1.5 text-xs">
							<label class="flex items-center gap-1.5 cursor-pointer">
								<input type="checkbox" bind:checked={detectEmails} class="rounded text-primary-600" />
								<span class="text-gray-700">Email</span>
							</label>
							<label class="flex items-center gap-1.5 cursor-pointer">
								<input type="checkbox" bind:checked={detectPhones} class="rounded text-primary-600" />
								<span class="text-gray-700">Phone</span>
							</label>
							<label class="flex items-center gap-1.5 cursor-pointer">
								<input type="checkbox" bind:checked={detectSSN} class="rounded text-primary-600" />
								<span class="text-gray-700">SSN</span>
							</label>
							<label class="flex items-center gap-1.5 cursor-pointer">
								<input type="checkbox" bind:checked={detectCreditCards} class="rounded text-primary-600" />
								<span class="text-gray-700">Cards</span>
							</label>
							<label class="flex items-center gap-1.5 cursor-pointer">
								<input type="checkbox" bind:checked={detectIPAddresses} class="rounded text-primary-600" />
								<span class="text-gray-700">IP</span>
							</label>
							<label class="flex items-center gap-1.5 cursor-pointer">
								<input type="checkbox" bind:checked={detectDates} class="rounded text-primary-600" />
								<span class="text-gray-700">Dates</span>
							</label>
							<label class="flex items-center gap-1.5 cursor-pointer">
								<input type="checkbox" bind:checked={detectAddresses} class="rounded text-primary-600" />
								<span class="text-gray-700">Addr</span>
							</label>
							<label class="flex items-center gap-1.5 cursor-pointer">
								<input type="checkbox" bind:checked={detectIBAN} class="rounded text-primary-600" />
								<span class="text-gray-700">IBAN</span>
							</label>
						</div>

						<!-- Security Mode - Inline -->
						<label class="flex items-center gap-2 cursor-pointer text-xs mt-2.5 pt-2.5 border-t border-gray-100" title="All detection runs in your browser - no data sent to server">
							<svg class="w-3.5 h-3.5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
								<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
							</svg>
							<input type="checkbox" bind:checked={coordinatesOnly} class="rounded text-green-600" disabled={inputMode === 'file'} />
							<span class="text-gray-600">Browser-Only Mode <span class="text-green-600 font-medium">(Zero Network)</span></span>
						</label>
					</div>

					<button
						onclick={scanForPII}
						disabled={loading || (inputMode === 'text' ? !textInput.trim() : !file)}
						class="w-full mt-4 px-5 py-2.5 bg-primary-600 text-white rounded-lg text-sm font-medium hover:bg-primary-700 transition-all shadow-sm disabled:opacity-50 disabled:cursor-not-allowed"
					>
						{loading ? 'Scanning...' : 'Scan for PII'}
					</button>

					{#if error}
						<div class="mt-3 p-3 bg-red-50 text-red-700 text-sm rounded-lg border border-red-100">
							{error}
						</div>
					{/if}
				</div>

				<!-- Results Section -->
				<div class="lg:col-span-2 bg-white rounded-xl border border-gray-100 shadow-sm p-5">
					<h2 class="text-base font-bold text-gray-900 mb-4">Scan Results</h2>

					{#if result}
						<!-- Risk Summary -->
						<div class="grid grid-cols-4 gap-3 mb-5">
							<div class="bg-gray-50 rounded-lg p-2.5 text-center border border-gray-100">
								<p class="text-xs text-gray-500">PII Found</p>
								<p class="text-xl font-bold {result.total_entities > 0 ? 'text-red-600' : 'text-green-600'}">
									{result.total_entities}
								</p>
							</div>
							<div class="bg-gray-50 rounded-lg p-2.5 text-center border border-gray-100">
								<p class="text-xs text-gray-500">Types</p>
								<p class="text-xl font-bold text-gray-800">
									{Object.keys(result.entities_by_type || {}).length}
								</p>
							</div>
							<div class="bg-gray-50 rounded-lg p-2.5 text-center border border-gray-100">
								<p class="text-xs text-gray-500">Risk Score</p>
								<p class="text-xl font-bold text-gray-800">{result.risk_score}</p>
							</div>
							<div class="rounded-lg p-2.5 text-center border {getRiskColor(result.risk_level)}">
								<p class="text-xs opacity-80">Risk Level</p>
								<p class="text-xl font-bold">{result.risk_level}</p>
							</div>
						</div>

						<!-- Tabs -->
						<div class="flex gap-1 mb-4 border-b border-gray-200">
							<button
								class="px-4 py-2 text-sm font-medium transition-colors {activeTab === 'overview'
									? 'text-primary-600 border-b-2 border-primary-600'
									: 'text-gray-500 hover:text-gray-700'}"
								onclick={() => (activeTab = 'overview')}
							>
								Overview
							</button>
							<button
								class="px-4 py-2 text-sm font-medium transition-colors {activeTab === 'entities'
									? 'text-primary-600 border-b-2 border-primary-600'
									: 'text-gray-500 hover:text-gray-700'}"
								onclick={() => (activeTab = 'entities')}
							>
								Entities ({result.total_entities})
							</button>
							<button
								class="px-4 py-2 text-sm font-medium transition-colors {activeTab === 'redacted'
									? 'text-primary-600 border-b-2 border-primary-600'
									: 'text-gray-500 hover:text-gray-700'}"
								onclick={() => (activeTab = 'redacted')}
							>
								Redacted Preview
							</button>
						</div>

						<!-- Tab Content -->
						{#if activeTab === 'overview'}
							<div class="space-y-4">
								{#if Object.keys(result.entities_by_type || {}).length > 0}
									<div class="bg-gray-50 rounded-lg p-4 border border-gray-100">
										<h3 class="text-sm font-semibold text-gray-700 mb-3">PII by Type</h3>
										<div class="grid grid-cols-2 gap-2">
											{#each Object.entries(result.entities_by_type) as [type, count]}
												<div class="flex items-center justify-between p-2 rounded-lg border {getPIITypeColor(type)}">
													<div class="flex items-center gap-2">
														<span class="text-xs font-bold w-6 h-6 rounded flex items-center justify-center bg-white/50">
															{getPIITypeIcon(type)}
														</span>
														<span class="text-sm font-medium">{type}</span>
													</div>
													<span class="text-sm font-bold">{count}</span>
												</div>
											{/each}
										</div>
									</div>
								{:else}
									<div class="bg-green-50 rounded-lg p-4 border border-green-200">
										<div class="flex items-center gap-2">
											<svg class="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
												<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
											</svg>
											<span class="text-sm text-green-700 font-medium">No PII detected in the input</span>
										</div>
									</div>
								{/if}

								<div class="rounded-lg p-4 border {getRiskColor(result.risk_level)}">
									<h3 class="text-sm font-semibold mb-2">Risk Assessment</h3>
									<p class="text-sm opacity-90">
										{#if result.risk_level === 'CRITICAL'}
											Critical risk! Highly sensitive PII (SSN, Credit Cards) detected. Immediate action required.
										{:else if result.risk_level === 'HIGH'}
											High risk! Multiple sensitive PII elements found. Consider redaction before sharing.
										{:else if result.risk_level === 'MEDIUM'}
											Medium risk. Some PII detected that may require attention.
										{:else}
											Low risk. Minimal or no PII detected.
										{/if}
									</p>
								</div>
							</div>
						{:else if activeTab === 'entities'}
							<div class="overflow-x-auto">
								{#if result.entities && result.entities.length > 0}
									<div class="flex justify-end mb-3">
										<button
											onclick={copyToClipboard}
											class="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg transition-all
												{copySuccess
													? 'bg-green-100 text-green-700 border border-green-300'
													: 'bg-gray-100 text-gray-600 hover:bg-gray-200 border border-gray-200'}"
										>
											{#if copySuccess}
												<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
													<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
												</svg>
												Copied!
											{:else}
												<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
													<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
												</svg>
												Copy
											{/if}
										</button>
									</div>
									<table class="w-full text-sm">
										<thead>
											<tr class="border-b border-gray-200">
												<th class="text-left py-2 px-3 font-medium text-gray-700">Type</th>
												<th class="text-left py-2 px-3 font-medium text-gray-700">Original Value</th>
												<th class="text-left py-2 px-3 font-medium text-gray-700">Masked Value</th>
												<th class="text-right py-2 px-3 font-medium text-gray-700">Confidence</th>
											</tr>
										</thead>
										<tbody>
											{#each result.entities as entity}
												<tr class="border-b border-gray-100">
													<td class="py-2 px-3">
														<span class="text-xs px-2 py-1 rounded border {getPIITypeColor(entity.type)}">
															{entity.type}
														</span>
													</td>
													<td class="py-2 px-3 font-mono text-xs text-red-600">{entity.value}</td>
													<td class="py-2 px-3 font-mono text-xs text-green-600">{entity.masked_value}</td>
													<td class="py-2 px-3 text-right">
														<span class="text-xs px-2 py-0.5 rounded {entity.confidence >= 0.9
															? 'bg-green-100 text-green-700'
															: entity.confidence >= 0.7
																? 'bg-yellow-100 text-yellow-700'
																: 'bg-red-100 text-red-700'}">
															{Math.round(entity.confidence * 100)}%
														</span>
													</td>
												</tr>
											{/each}
										</tbody>
									</table>
								{:else}
									<div class="text-center py-8 text-gray-500">
										No PII entities found
									</div>
								{/if}
							</div>
						{:else if activeTab === 'redacted'}
							<div class="space-y-3">
								<div class="bg-gray-50 rounded-lg p-4 border border-gray-200">
									<div class="flex justify-between items-center mb-2">
										<h3 class="text-sm font-semibold text-gray-700">Redacted Text Preview</h3>
										<button
											onclick={copyRedactedToClipboard}
											class="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg transition-all
												{copyRedactedSuccess
													? 'bg-green-100 text-green-700 border border-green-300'
													: 'bg-white text-gray-600 hover:bg-gray-100 border border-gray-200'}"
										>
											{#if copyRedactedSuccess}
												<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
													<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
												</svg>
												Copied!
											{:else}
												<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
													<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
												</svg>
												Copy
											{/if}
										</button>
									</div>
									<pre class="text-xs font-mono whitespace-pre-wrap text-gray-600 bg-white p-3 rounded-lg border border-gray-100 max-h-[300px] overflow-auto">{result.redacted_preview || 'No preview available'}</pre>
								</div>
								<p class="text-xs text-gray-500">
									This preview shows PII values masked for safe sharing.
								</p>
							</div>
						{/if}
					{:else}
						<div class="text-center py-12">
							<div class="w-16 h-16 rounded-2xl bg-gray-100 flex items-center justify-center mx-auto mb-4">
								<svg class="w-8 h-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
									<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
								</svg>
							</div>
							<p class="text-gray-500">Enter text or upload a file to scan for PII</p>
						</div>
					{/if}
				</div>
			</div>
		</div>
	</main>

	<Footer />
</div>
