<script lang="ts">
	import { PUBLIC_API_URL } from '$env/static/public';

	const API_BASE = (PUBLIC_API_URL || 'http://localhost:8000') + '/api/v1';

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

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

	// Security option: Client-side redaction mode
	// When enabled, backend only returns coordinates (start, end, type)
	// and the frontend performs masking locally - backend never sees actual PII values
	let coordinatesOnly = false;

	/**
	 * Client-side redaction using coordinates from backend.
	 * This ensures the backend never "sees" the actual PII values.
	 */
	function clientSideRedact(text: string, entities: Array<{start: number, end: number, type: string, length: number}>): string {
		if (!entities || entities.length === 0) return text;

		// Sort by position in reverse to not mess up indices
		const sorted = [...entities].sort((a, b) => b.start - a.start);

		let result = text;
		for (const entity of sorted) {
			const maskChar = '*';
			const masked = maskChar.repeat(entity.length);
			result = result.slice(0, entity.start) + masked + result.slice(entity.end);
		}
		return result;
	}

	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 {
			let response;

			if (inputMode === 'text') {
				const formData = new FormData();
				formData.append('text', textInput);
				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', String(coordinatesOnly));

				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();

			// If coordinates_only mode, perform client-side redaction
			if (result.coordinates_only && inputMode === 'text') {
				result.redacted_preview = clientSideRedact(textInput, result.entities);
			}
		} 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 '@';
			// Phone numbers (US and International)
			case 'PHONE_US':
			case 'PHONE_INTL':
				return '#';
			// Identity documents
			case 'SSN':
				return 'SSN';
			case 'MEDICARE_ID':
				return 'MED';
			case 'GERMAN_ID':
				return 'DEU';
			case 'CREDIT_CARD':
				return '$';
			case 'IP_ADDRESS':
				return 'IP';
			case 'DATE_OF_BIRTH':
				return 'DOB';
			// Addresses
			case 'US_ADDRESS':
			case 'UK_ADDRESS':
			case 'EU_ADDRESS':
			case 'INTERNATIONAL_ADDRESS':
				return 'ADR';
			case 'UK_POSTCODE':
				return 'ZIP';
			// Financial
			case 'IBAN':
			case 'BANK_ACCOUNT':
			case 'ROUTING_NUMBER':
			case 'SWIFT_BIC':
				return 'BNK';
			// Cloud providers
			case 'AWS_ACCESS_KEY':
			case 'AWS_SECRET_KEY':
				return 'AWS';
			case 'GITHUB_TOKEN':
			case 'GITHUB_TOKEN_CLASSIC':
				return 'GH';
			case 'STRIPE_KEY':
				return 'STR';
			case 'GOOGLE_API_KEY':
			case 'GCP_SERVICE_ACCOUNT':
			case 'GCP_PRIVATE_KEY_ID':
				return 'GCP';
			case 'AZURE_CLIENT_SECRET':
			case 'AZURE_CONNECTION_STRING':
			case 'AZURE_SAS_TOKEN':
				return 'AZR';
			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';
			// Medical records
			case 'MEDICAL_RECORD_NUMBER':
			case 'NPI_NUMBER':
			case 'DEA_NUMBER':
				return 'RX';
			// Possible patterns (failed validation)
			case 'POSSIBLE_CARD_PATTERN':
				return '?$';
			case 'POSSIBLE_IBAN_PATTERN':
				return '?BNK';
			// Advanced detection types
			case 'EU_VAT_NUMBER':
				return 'VAT';
			case 'SSN_SPELLED_OUT':
				return 'SSN';
			case 'BASE64_ENCODED_SECRET':
				return 'B64';
			// =========================================================================
			// NEW v1.1 PATTERNS
			// =========================================================================
			// International IDs
			case 'UK_NATIONAL_INSURANCE':
				return 'NI';
			case 'CANADIAN_SIN':
				return 'SIN';
			case 'INDIA_AADHAAR':
				return 'AAD';
			case 'INDIA_PAN':
				return 'PAN';
			case 'AUSTRALIA_TFN':
				return 'TFN';
			case 'BRAZIL_CPF':
				return 'CPF';
			case 'MEXICO_CURP':
				return 'CRP';
			case 'SOUTH_AFRICA_ID':
				return 'ZAF';
			// Additional cloud tokens
			case 'DISCORD_TOKEN':
			case 'DISCORD_WEBHOOK':
				return 'DIS';
			case 'TWILIO_API_KEY':
			case 'TWILIO_AUTH_TOKEN':
				return 'TWL';
			case 'SENDGRID_API_KEY':
				return 'SG';
			case 'OPENAI_API_KEY':
				return 'OAI';
			case 'ANTHROPIC_API_KEY':
				return 'ANT';
			case 'MAILCHIMP_API_KEY':
				return 'MC';
			case 'MAILGUN_API_KEY':
				return 'MG';
			case 'HEROKU_API_KEY':
				return 'HRK';
			case 'SHOPIFY_ACCESS_TOKEN':
			case 'SHOPIFY_SHARED_SECRET':
				return 'SHP';
			case 'NPM_TOKEN':
				return 'NPM';
			case 'PYPI_TOKEN':
				return 'PIP';
			case 'DOCKER_AUTH':
				return 'DKR';
			// Crypto addresses
			case 'BITCOIN_ADDRESS':
				return 'BTC';
			case 'ETHEREUM_ADDRESS':
				return 'ETH';
			case 'MONERO_ADDRESS':
				return 'XMR';
			// Financial identifiers
			case 'CUSIP':
				return 'CUS';
			case 'ISIN':
				return 'ISN';
			case 'SEDOL':
				return 'SED';
			default:
				// Handle suffixes for nested/encoded detection
				if (type.includes('_IN_JSON')) return 'JSON';
				if (type.includes('_BASE64')) return 'B64';
				if (type.includes('_TRANSLITERATED')) return 'TRN';
				if (type.includes('_SPELLED_OUT')) return 'TXT';
				if (type.includes('_NORMALIZED')) return '*';
				return '?';
		}
	}

	function getPIITypeColor(type: string): string {
		switch (type) {
			// Critical - Identity
			case 'SSN':
			case 'CREDIT_CARD':
			case 'IBAN':
			case 'BANK_ACCOUNT':
			case 'ROUTING_NUMBER':
			case 'MEDICARE_ID':
			case 'GERMAN_ID':
				return 'bg-red-100 text-red-700 border-red-200';
			// Critical - Secrets (AWS/Azure/GCP)
			case 'AWS_ACCESS_KEY':
			case 'AWS_SECRET_KEY':
			case 'PRIVATE_KEY':
			case 'PASSWORD_IN_URL':
			case 'GITHUB_TOKEN':
			case 'GITHUB_TOKEN_CLASSIC':
			case 'STRIPE_KEY':
			case 'GCP_SERVICE_ACCOUNT':
			case 'GCP_PRIVATE_KEY_ID':
			case 'AZURE_CLIENT_SECRET':
			case 'AZURE_CONNECTION_STRING':
			case 'AZURE_SAS_TOKEN':
				return 'bg-purple-100 text-purple-700 border-purple-200';
			// High
			case 'GOOGLE_API_KEY':
			case 'SLACK_TOKEN':
			case 'JWT_TOKEN':
			case 'GENERIC_API_KEY':
				return 'bg-orange-100 text-orange-700 border-orange-200';
			// Medical (HIPAA)
			case 'MEDICAL_RECORD_NUMBER':
			case 'NPI_NUMBER':
			case 'DEA_NUMBER':
				return 'bg-pink-100 text-pink-700 border-pink-200';
			// Medium - Addresses
			case 'US_ADDRESS':
			case 'UK_ADDRESS':
			case 'EU_ADDRESS':
			case 'INTERNATIONAL_ADDRESS':
			case 'UK_POSTCODE':
				return 'bg-amber-100 text-amber-700 border-amber-200';
			// Medium - Contact
			case 'EMAIL':
			case 'PHONE_US':
			case 'PHONE_INTL':
				return 'bg-yellow-100 text-yellow-700 border-yellow-200';
			// Low - Possible patterns (failed validation)
			case 'POSSIBLE_CARD_PATTERN':
			case 'POSSIBLE_IBAN_PATTERN':
				return 'bg-gray-100 text-gray-600 border-gray-200';
			// Advanced detection - EU/International
			case 'EU_VAT_NUMBER':
				return 'bg-indigo-100 text-indigo-700 border-indigo-200';
			// Advanced detection - Evasion techniques (more suspicious)
			case 'SSN_SPELLED_OUT':
			case 'BASE64_ENCODED_SECRET':
				return 'bg-red-200 text-red-800 border-red-300';
			// =========================================================================
			// NEW v1.1 PATTERNS - Colors
			// =========================================================================
			// International IDs - Critical (identity theft)
			case 'UK_NATIONAL_INSURANCE':
			case 'CANADIAN_SIN':
			case 'INDIA_AADHAAR':
			case 'INDIA_PAN':
			case 'AUSTRALIA_TFN':
			case 'BRAZIL_CPF':
			case 'MEXICO_CURP':
			case 'SOUTH_AFRICA_ID':
				return 'bg-red-100 text-red-700 border-red-200';
			// Additional cloud tokens - Critical
			case 'DISCORD_TOKEN':
			case 'DISCORD_WEBHOOK':
			case 'TWILIO_API_KEY':
			case 'TWILIO_AUTH_TOKEN':
			case 'SENDGRID_API_KEY':
			case 'OPENAI_API_KEY':
			case 'ANTHROPIC_API_KEY':
			case 'MAILCHIMP_API_KEY':
			case 'MAILGUN_API_KEY':
			case 'HEROKU_API_KEY':
			case 'SHOPIFY_ACCESS_TOKEN':
			case 'SHOPIFY_SHARED_SECRET':
			case 'NPM_TOKEN':
			case 'PYPI_TOKEN':
			case 'DOCKER_AUTH':
				return 'bg-purple-100 text-purple-700 border-purple-200';
			// Crypto addresses - High (financial)
			case 'BITCOIN_ADDRESS':
			case 'ETHEREUM_ADDRESS':
			case 'MONERO_ADDRESS':
				return 'bg-orange-100 text-orange-700 border-orange-200';
			// Financial identifiers - Medium
			case 'CUSIP':
			case 'ISIN':
			case 'SEDOL':
				return 'bg-amber-100 text-amber-700 border-amber-200';
			default:
				// Handle suffixes for nested/encoded detection - these are MORE suspicious
				if (type.includes('_IN_JSON')) return 'bg-rose-100 text-rose-700 border-rose-200';
				if (type.includes('_BASE64')) return 'bg-rose-100 text-rose-700 border-rose-200';
				if (type.includes('_TRANSLITERATED')) return 'bg-violet-100 text-violet-700 border-violet-200';
				if (type.includes('_SPELLED_OUT')) return 'bg-rose-100 text-rose-700 border-rose-200';
				if (type.includes('_NORMALIZED')) return 'bg-amber-100 text-amber-700 border-amber-200';
				return 'bg-blue-100 text-blue-700 border-blue-200';
		}
	}

	// Copy results to clipboard
	let copySuccess = false;
	async function copyToClipboard() {
		if (!result || !result.entities || result.entities.length === 0) return;

		// Format entities as a table-like string
		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);
		}
	}

	// Copy redacted text to clipboard
	let copyRedactedSuccess = 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);
		}
	}

	// Sample text with PII for testing
	function loadSampleText() {
		textInput = `Customer Record:
Name: John Smith
Email: john.smith@example.com
US Phone: (555) 123-4567
German Phone: +49 30 1234567
SSN: 123-45-6789
Date of Birth: 03/15/1985
IP Address: 192.168.1.100
Credit Card: 4532 0151 1283 0366

--- ADDRESSES ---
US Address: 123 Main Street, New York, NY 10001
UK Address: 10 Downing Street, London, SW1A 2AA
EU Address: 25 rue Victor Hugo, 75016 Paris
German Address: Hauptstrasse 42, 10115 Berlin

--- BANKING INFO ---
IBAN: DE89370400440532013000
Bank Account: Account: 12345678901234

--- MEDICAL RECORDS ---
MRN: ABC123456
NPI: 1234567890

--- CLOUD SECRETS (DO NOT SHARE) ---
AWS Key: AKIAIOSFODNN7EXAMPLE
GCP Service Account: my-service@my-project.iam.gserviceaccount.com
Azure Key: AccountKey=abcd1234efgh5678ijkl9012mnop3456
GitHub Token: ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Password: password=MySecretPass123!

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

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

<div class="max-w-6xl mx-auto animate-fade-in">
	<!-- Header -->
	<div class="mb-6">
		<h1 class="text-2xl font-bold text-surface-800">Privacy Scanner</h1>
		<p class="text-surface-600 mt-1">Detect and redact personally identifiable information (PII) from text and files</p>
	</div>

	<div class="grid grid-cols-1 lg:grid-cols-3 gap-4">
		<!-- Input Section -->
		<div class="card p-4">
			<h2 class="text-base font-bold text-surface-800 mb-3">Input</h2>

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

			{#if inputMode === 'text'}
				<div class="space-y-3">
					<div class="flex justify-between items-center">
						<label class="label">Text to Scan</label>
						<div class="flex gap-2">
							<button
								class="text-xs text-primary-600 hover:text-primary-700"
								on:click={loadSampleText}
							>
								Load Sample
							</button>
							{#if textInput || result}
								<span class="text-surface-300">|</span>
								<button
									class="text-xs text-surface-500 hover:text-red-600"
									on:click={clearAll}
								>
									Clear
								</button>
							{/if}
						</div>
					</div>
					<textarea
						bind:value={textInput}
						placeholder="Paste text containing potential PII here..."
						class="input min-h-[150px] resize-none font-mono text-xs"
					/>
				</div>
			{:else}
				<!-- Drop Zone -->
				<div
					class="border-2 border-dashed border-surface-300 rounded-xl p-6 text-center hover:border-primary-400 transition-colors cursor-pointer"
					on:drop={handleDrop}
					on:dragover={handleDragOver}
					role="button"
					tabindex="0"
				>
					<input
						type="file"
						accept=".csv,.txt,.json"
						on:change={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-surface-600">
							<span class="text-primary-600 font-medium">Click to upload</span> or drag and drop
						</p>
						<p class="text-xs text-surface-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-surface-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-surface-700 truncate flex-1">{fileName}</span>
					</div>
				{/if}
			{/if}

			<!-- Detection Options -->
			<div class="mt-3 pt-3 border-t border-surface-200">
				<h3 class="text-xs font-semibold text-surface-600 mb-1.5">PII Detection</h3>
				<div class="grid grid-cols-2 gap-1 text-xs">
					<label class="flex items-center gap-2 cursor-pointer">
						<input type="checkbox" bind:checked={detectEmails} class="rounded text-primary-600" />
						<span class="text-surface-700">Emails</span>
					</label>
					<label class="flex items-center gap-2 cursor-pointer">
						<input type="checkbox" bind:checked={detectPhones} class="rounded text-primary-600" />
						<span class="text-surface-700">Phones</span>
					</label>
					<label class="flex items-center gap-2 cursor-pointer">
						<input type="checkbox" bind:checked={detectSSN} class="rounded text-primary-600" />
						<span class="text-surface-700">SSN</span>
					</label>
					<label class="flex items-center gap-2 cursor-pointer">
						<input type="checkbox" bind:checked={detectCreditCards} class="rounded text-primary-600" />
						<span class="text-surface-700">Credit Cards</span>
					</label>
					<label class="flex items-center gap-2 cursor-pointer">
						<input type="checkbox" bind:checked={detectIPAddresses} class="rounded text-primary-600" />
						<span class="text-surface-700">IP Addresses</span>
					</label>
					<label class="flex items-center gap-2 cursor-pointer">
						<input type="checkbox" bind:checked={detectDates} class="rounded text-primary-600" />
						<span class="text-surface-700">Dates</span>
					</label>
					<label class="flex items-center gap-2 cursor-pointer">
						<input type="checkbox" bind:checked={detectAddresses} class="rounded text-primary-600" />
						<span class="text-surface-700">Addresses</span>
					</label>
					<label class="flex items-center gap-2 cursor-pointer">
						<input type="checkbox" bind:checked={detectIBAN} class="rounded text-primary-600" />
						<span class="text-surface-700">IBAN</span>
					</label>
				</div>
				<h3 class="text-xs font-semibold text-surface-600 mt-2 mb-1">Secrets Detection</h3>
				<div class="grid grid-cols-1 gap-1 text-xs">
					<label class="flex items-center gap-2 cursor-pointer">
						<input type="checkbox" bind:checked={detectSecrets} class="rounded text-primary-600" />
						<span class="text-surface-700">API Keys & Secrets (AWS, GitHub, Stripe, etc.)</span>
					</label>
				</div>

				<!-- Security Mode -->
				<h3 class="text-xs font-semibold text-surface-600 mt-2 mb-1 flex items-center gap-1">
					<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>
					Security Mode
				</h3>
				<div class="grid grid-cols-1 gap-1 text-xs">
					<label class="flex items-center gap-2 cursor-pointer group" title="When enabled, backend only returns coordinates (start, end, type) - actual PII values never leave your browser">
						<input type="checkbox" bind:checked={coordinatesOnly} class="rounded text-green-600" disabled={inputMode === 'file'} />
						<span class="text-surface-700 group-hover:text-surface-900">
							Client-Side Redaction
							<span class="text-surface-400 text-[10px] ml-1">(Ultra-secure: backend sees only coordinates)</span>
						</span>
					</label>
				</div>
				{#if coordinatesOnly && inputMode === 'text'}
					<div class="mt-2 p-2 bg-green-50 border border-green-200 rounded text-[10px] text-green-700">
						<strong>Enhanced Privacy Mode:</strong> PII values will be masked client-side. The backend will only receive position coordinates (start/end) - it never sees your actual sensitive data.
					</div>
				{/if}
				{#if inputMode === 'file'}
					<div class="mt-2 text-[10px] text-surface-400">
						Note: Client-side redaction is only available for text mode.
					</div>
				{/if}
			</div>

			<button
				on:click={scanForPII}
				disabled={loading || (inputMode === 'text' ? !textInput.trim() : !file)}
				class="btn-primary w-full mt-3 disabled:opacity-50"
			>
				{loading ? 'Scanning...' : 'Scan for PII'}
			</button>

			{#if error}
				<div class="mt-3 p-2 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 card p-4">
			<h2 class="text-base font-bold text-surface-800 mb-3">Scan Results</h2>

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

				<!-- Tabs -->
				<div class="flex gap-1 mb-4 border-b border-surface-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-surface-500 hover:text-surface-700'}"
						on:click={() => (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-surface-500 hover:text-surface-700'}"
						on:click={() => (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-surface-500 hover:text-surface-700'}"
						on:click={() => (activeTab = 'redacted')}
					>
						Redacted Preview
					</button>
				</div>

				<!-- Tab Content -->
				{#if activeTab === 'overview'}
					<div class="space-y-3">
						<!-- PII by Type -->
						{#if Object.keys(result.entities_by_type || {}).length > 0}
							<div class="bg-surface-50 rounded-lg p-4 border border-surface-100">
								<h3 class="text-sm font-semibold text-surface-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}

						<!-- Risk Assessment -->
						<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}
							<!-- Copy to Clipboard Button -->
							<div class="flex justify-end mb-3">
								<button
									on:click={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-surface-100 text-surface-600 hover:bg-surface-200 border border-surface-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="table-modern">
								<thead>
									<tr>
										<th>Type</th>
										<th>Original Value</th>
										<th>Masked Value</th>
										<th class="text-right">Confidence</th>
									</tr>
								</thead>
								<tbody>
									{#each result.entities as entity}
										<tr>
											<td>
												<span class="text-xs px-2 py-1 rounded border {getPIITypeColor(entity.type)}">
													{entity.type}
												</span>
											</td>
											<td class="font-mono text-xs text-red-600">{entity.value}</td>
											<td class="font-mono text-xs text-green-600">{entity.masked_value}</td>
											<td class="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-surface-500">
								No PII entities found
							</div>
						{/if}
					</div>
				{:else if activeTab === 'redacted'}
					<div class="space-y-3">
						<div class="bg-surface-50 rounded-lg p-4 border border-surface-200">
							<div class="flex justify-between items-center mb-2">
								<h3 class="text-sm font-semibold text-surface-700">Redacted Text Preview</h3>
								<button
									on:click={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-surface-600 hover:bg-surface-100 border border-surface-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-surface-600 bg-white p-3 rounded-lg border border-surface-100 max-h-[300px] overflow-auto">{result.redacted_preview || 'No preview available'}</pre>
						</div>
						<p class="text-xs text-surface-500">
							This preview shows PII values masked for safe sharing. Original sensitive data is replaced with masked versions.
						</p>
					</div>
				{/if}
			{:else}
				<div class="text-center py-12">
					<div class="w-16 h-16 rounded-2xl bg-surface-100 flex items-center justify-center mx-auto mb-4">
						<svg class="w-8 h-8 text-surface-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-surface-500">Enter text or upload a file to scan for PII</p>
				</div>
			{/if}
		</div>
	</div>
</div>
