import { Badge } from '@public/components/ui/badge'
import { Button } from '@public/components/ui/button'
import { Checkbox } from '@public/components/ui/checkbox'
import { Input } from '@public/components/ui/input'
import { Label } from '@public/components/ui/label'
import { SkeletonShimmer } from '@public/components/ui/skeleton'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@public/components/ui/table'
import {
	CheckCircle2,
	ChevronDown,
	ChevronsUpDown,
	ChevronUp,
	Copy,
	ExternalLink,
	KeyRound,
	Loader2,
	Plus,
	RefreshCw,
	RotateCcw,
	Trash2,
	Webhook,
	X,
} from 'lucide-react'
import { type ChangeEvent, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import type { SecretMeta } from '../hooks/useSecretData'
import type { WebhookEventLog, WebhookRecord } from '../hooks/useWebhookData'
import { canUseLocalLoopbackWebhookHttp, validateEditorWebhookEndpointUrl } from '../webhook-url-policy'

const APPS = [
	{ id: 'bluesky', label: 'Bluesky', path: 'app.bsky.*' },
	{ id: 'tangled', label: 'Tangled', path: 'sh.tangled.*' },
	{ id: 'leaflet', label: 'Leaflet', path: 'pub.leaflet.*' },
	{ id: 'wisp', label: 'wisp', path: 'place.wisp.*' },
	{ id: 'blento', label: 'Blento', path: 'blue.blento.*' },
] as const

type AppId = (typeof APPS)[number]['id'] | 'other'
type OtherMode = 'all' | 'collection' | 'rkey'

interface WebhooksTabProps {
	webhooks: WebhookRecord[]
	webhooksLoading: boolean
	eventLogs: WebhookEventLog[]
	eventLogsLoading: boolean
	isCreating: boolean
	userDid?: string
	secrets: SecretMeta[]
	secretsLoading: boolean
	isCreatingSecret: boolean
	onCreateWebhook: (data: {
		scopeAturi: string
		url: string
		backlinks: boolean
		events: string[]
		secret?: string
		secretId?: string
		enabled: boolean
	}) => Promise<any>
	onDeleteWebhook: (rkey: string) => Promise<void>
	onRefreshEvents: () => Promise<void>
	onCreateSecret: (name: string) => Promise<{ token: string }>
	onDeleteSecret: (name: string) => Promise<void>
	onRotateSecret: (name: string) => Promise<{ token: string }>
}

function buildScope(
	did: string,
	selectedApp: AppId | null,
	scopePath: string,
	otherMode: OtherMode,
	otherCollection: string,
	otherRkey: string,
): string {
	if (!did) return ''
	if (!selectedApp) return ''
	if (selectedApp === 'other') {
		if (otherMode === 'all') return `at://${did}`
		if (otherMode === 'collection') return otherCollection ? `at://${did}/${otherCollection}` : ''
		return otherCollection && otherRkey ? `at://${did}/${otherCollection}/${otherRkey}` : ''
	}
	return scopePath ? `at://${did}/${scopePath}` : `at://${did}`
}

function formatTimeAgo(dateStr: string): string {
	const diff = Date.now() - new Date(dateStr).getTime()
	const seconds = Math.floor(diff / 1000)
	if (seconds < 60) return `${seconds}s ago`
	const minutes = Math.floor(seconds / 60)
	if (minutes < 60) return `${minutes}m ago`
	const hours = Math.floor(minutes / 60)
	if (hours < 24) return `${hours}h ago`
	return new Date(dateStr).toLocaleDateString()
}

export const WebhooksTab = memo(function WebhooksTab({
	webhooks,
	webhooksLoading,
	eventLogs,
	eventLogsLoading,
	isCreating,
	userDid = '',
	secrets,
	secretsLoading,
	isCreatingSecret,
	onCreateWebhook,
	onDeleteWebhook,
	onRefreshEvents,
	onCreateSecret,
	onDeleteSecret,
	onRotateSecret,
}: WebhooksTabProps) {
	const [url, setUrl] = useState('')
	const [selectedApp, setSelectedApp] = useState<AppId | null>(null)
	const [scopePath, setScopePath] = useState('')
	const [otherMode, setOtherMode] = useState<OtherMode>('all')
	const [otherCollection, setOtherCollection] = useState('')
	const [otherRkey, setOtherRkey] = useState('')
	const [customDid, setCustomDid] = useState('')
	const [useCustomDid, setUseCustomDid] = useState(false)
	const [selectedSecretId, setSelectedSecretId] = useState('')
	const [backlinks, setBacklinks] = useState(false)
	const [eventCreate, setEventCreate] = useState(true)
	const [eventUpdate, setEventUpdate] = useState(true)
	const [eventDelete, setEventDelete] = useState(true)
	const [error, setError] = useState<string | null>(null)
	const [success, setSuccess] = useState<string | null>(null)
	const [deletingRkey, setDeletingRkey] = useState<string | null>(null)
	const [showCreateForm, setShowCreateForm] = useState(false)
	const [focusedWebhook, setFocusedWebhook] = useState(0)
	const containerRef = useRef<HTMLDivElement>(null)
	const itemRefs = useRef<(HTMLDivElement | null)[]>([])

	// Secrets panel state
	const [showSecretsPanel, setShowSecretsPanel] = useState(false)
	const [newSecretName, setNewSecretName] = useState('')
	const [secretError, setSecretError] = useState<string | null>(null)
	const [revealedToken, setRevealedToken] = useState<{ name: string; token: string } | null>(null)
	const [deletingSecret, setDeletingSecret] = useState<string | null>(null)
	const [rotatingSecret, setRotatingSecret] = useState<string | null>(null)
	const [copiedToken, setCopiedToken] = useState(false)

	useEffect(() => {
		const id = setInterval(onRefreshEvents, 60_000)
		return () => clearInterval(id)
	}, [onRefreshEvents])

	// Auto-focus container when webhooks are loaded (fires on mount if data ready)
	useEffect(() => {
		if (!webhooksLoading && containerRef.current) {
			const timer = setTimeout(() => containerRef.current?.focus(), 100)
			return () => clearTimeout(timer)
		}
	}, [webhooksLoading])

	// Clamp focused index
	useEffect(() => {
		if (webhooks.length > 0 && focusedWebhook >= webhooks.length) {
			setFocusedWebhook(webhooks.length - 1)
		}
	}, [webhooks.length, focusedWebhook])

	const handleDelete = useCallback(
		async (rkey: string) => {
			setDeletingRkey(rkey)
			try {
				await onDeleteWebhook(rkey)
			} catch (err) {
				alert(err instanceof Error ? err.message : 'Failed to delete webhook')
			} finally {
				setDeletingRkey(null)
			}
		},
		[onDeleteWebhook],
	)

	// Keyboard navigation
	useEffect(() => {
		const handleKeyDown = (e: KeyboardEvent) => {
			const target = e.target as HTMLElement
			const isTyping = target.tagName === 'INPUT' || target.tagName === 'TEXTAREA'
			const hasFocus = containerRef.current?.contains(document.activeElement)

			if (isTyping || !hasFocus || webhooks.length === 0 || showCreateForm) return

			switch (e.key) {
				case 'ArrowUp':
					e.preventDefault()
					setFocusedWebhook((prev) => Math.max(0, prev - 1))
					break
				case 'ArrowDown':
					e.preventDefault()
					setFocusedWebhook((prev) => Math.min(webhooks.length - 1, prev + 1))
					break
				case 'd':
					e.preventDefault()
					handleDelete(webhooks[focusedWebhook].rkey)
					break
				case 'n':
					e.preventDefault()
					setShowCreateForm(true)
					break
			}
		}

		window.addEventListener('keydown', handleKeyDown)
		return () => window.removeEventListener('keydown', handleKeyDown)
	}, [webhooks, focusedWebhook, showCreateForm, handleDelete])

	// Scroll focused item into view
	useEffect(() => {
		const element = itemRefs.current[focusedWebhook]
		if (element) {
			element.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
		}
	}, [focusedWebhook])

	const selectApp = (id: AppId) => {
		setSelectedApp(id)
		if (id !== 'other') {
			const app = APPS.find((a) => a.id === id)
			setScopePath(app?.path ?? '')
		}
		setError(null)
	}

	const effectiveDid = useCustomDid && customDid.trim() ? customDid.trim() : userDid
	const scopeAturi = buildScope(effectiveDid, selectedApp, scopePath, otherMode, otherCollection, otherRkey)

	const handleCreate = async (e: React.FormEvent) => {
		e.preventDefault()
		setError(null)
		setSuccess(null)

		const pageUrl = typeof window === 'undefined' ? '' : window.location.href
		const endpointValidation = validateEditorWebhookEndpointUrl(url, {
			allowLoopbackDev: canUseLocalLoopbackWebhookHttp(pageUrl),
		})
		if (!endpointValidation.ok) {
			setError(endpointValidation.error)
			return
		}
		if (!scopeAturi?.startsWith('at://')) {
			setError('Please select an app scope above')
			return
		}

		const events: string[] = []
		if (eventCreate) events.push('create')
		if (eventUpdate) events.push('update')
		if (eventDelete) events.push('delete')

		try {
			await onCreateWebhook({
				url,
				scopeAturi,
				backlinks,
				events: events.length === 3 ? [] : events,
				...(selectedSecretId ? { secretId: selectedSecretId } : {}),
				enabled: true,
			})
			setSuccess('Webhook created successfully')
			setUrl('')
			setSelectedApp(null)
			setScopePath('')
			setOtherMode('all')
			setOtherCollection('')
			setOtherRkey('')
			setCustomDid('')
			setUseCustomDid(false)
			setSelectedSecretId('')
			setBacklinks(false)
			setEventCreate(true)
			setEventUpdate(true)
			setEventDelete(true)
			setTimeout(() => {
				setSuccess(null)
				setShowCreateForm(false)
			}, 1500)
		} catch (err) {
			setError(err instanceof Error ? err.message : 'Failed to create webhook')
		}
	}

	// ── Delivery-table state ──────────────────────────────────────────────────
	type DeliveryColumn = 'status' | 'eventKind' | 'eventCollection' | 'url' | 'deliveredAt'
	const [sortCol, setSortCol] = useState<DeliveryColumn>('deliveredAt')
	const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc')
	const [filterScope, setFilterScope] = useState('')
	const [filterStatus, setFilterStatus] = useState<'all' | 'ok' | 'failed'>('all')
	const [filterKind, setFilterKind] = useState<string>('all')

	const handleSortCol = (col: DeliveryColumn) => {
		if (sortCol === col) {
			setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'))
		} else {
			setSortCol(col)
			setSortDir(col === 'deliveredAt' ? 'desc' : 'asc')
		}
	}

	const filteredLogs = useMemo(() => {
		let list = [...eventLogs]
		if (filterStatus !== 'all') list = list.filter((l) => l.status === filterStatus)
		if (filterKind !== 'all') list = list.filter((l) => l.eventKind === filterKind)
		if (filterScope.trim()) {
			const q = filterScope.trim().toLowerCase()
			list = list.filter((l) => l.eventCollection.toLowerCase().includes(q) || l.url.toLowerCase().includes(q))
		}
		list.sort((a, b) => {
			let valA: string
			let valB: string
			switch (sortCol) {
				case 'status':
					valA = a.status
					valB = b.status
					break
				case 'eventKind':
					valA = a.eventKind
					valB = b.eventKind
					break
				case 'eventCollection':
					valA = a.eventCollection
					valB = b.eventCollection
					break
				case 'url':
					valA = a.url
					valB = b.url
					break
				default:
					valA = a.deliveredAt
					valB = b.deliveredAt
					break
			}
			const cmp = valA < valB ? -1 : valA > valB ? 1 : 0
			return sortDir === 'asc' ? cmp : -cmp
		})
		return list
	}, [eventLogs, filterStatus, filterKind, filterScope, sortCol, sortDir])

	const uniqueKinds = useMemo(() => Array.from(new Set(eventLogs.map((l) => l.eventKind))).sort(), [eventLogs])

	const SortIcon = ({ col }: { col: DeliveryColumn }) => {
		if (sortCol !== col) return <ChevronsUpDown className="inline w-3 h-3 ml-1 opacity-30" />
		return sortDir === 'asc' ? (
			<ChevronUp className="inline w-3 h-3 ml-1" />
		) : (
			<ChevronDown className="inline w-3 h-3 ml-1" />
		)
	}
	// ─────────────────────────────────────────────────────────────────────────

	const Kbd = ({ children }: { children: React.ReactNode }) => (
		<kbd className="px-2 py-1 bg-muted/50 rounded border border-border/50">{children}</kbd>
	)

	return (
		// biome-ignore lint/a11y/noStaticElementInteractions: keyboard navigation container, interaction handled via window keydown listener
		// biome-ignore lint/a11y/useKeyWithClickEvents: onClick only focuses container, keyboard nav handled via useEffect
		<div
			ref={containerRef}
			className="h-full flex flex-col border border-border/30 bg-card/50 font-mono outline-none"
			tabIndex={-1}
			onClick={(e) => {
				const t = e.target as HTMLElement
				if (!t.closest('input, textarea, button, select, a, label')) {
					containerRef.current?.focus()
				}
			}}
		>
			{/* Header with keyboard hints */}
			<div className="flex flex-wrap items-center gap-3 text-xs text-muted-foreground p-4 pb-3 border-b border-border/30 flex-shrink-0">
				{webhooks.length > 0 && !showCreateForm ? (
					<>
						<div className="flex items-center gap-2">
							<Kbd>↑</Kbd>
							<Kbd>↓</Kbd>
							<span>navigate</span>
						</div>
						<span>•</span>
						<div className="flex items-center gap-2">
							<Kbd>d</Kbd>
							<span className="text-red-400">delete</span>
						</div>
						<span>•</span>
						<div className="flex items-center gap-2">
							<Kbd>n</Kbd>
							<span>new</span>
						</div>
					</>
				) : (
					<>
						<Webhook className="w-3.5 h-3.5" />
						<span>Receive HTTP callbacks for changes to your ATProto collections as well as references</span>
					</>
				)}
			</div>

			<div className="flex-1 min-h-0 overflow-y-auto">
				{/* Your Webhooks */}
				<div className="p-4 space-y-2">
					<div className="flex items-center justify-between mb-3">
						<p className="text-xs uppercase tracking-wider text-muted-foreground">Your Webhooks</p>
						<Button
							variant="outline"
							size="sm"
							className="h-7 text-xs px-3"
							onClick={() => setShowCreateForm(!showCreateForm)}
						>
							{showCreateForm ? (
								<>
									<ChevronUp className="w-3 h-3 mr-1.5" />
									Cancel
								</>
							) : (
								<>
									<Plus className="w-3 h-3 mr-1.5" />
									New Webhook
								</>
							)}
						</Button>
					</div>

					{/* Create form (collapsible) */}
					{showCreateForm && (
						<div className="border border-dashed border-border/50 p-4 space-y-4 mb-4">
							<form onSubmit={handleCreate} className="space-y-4">
								{/* URL */}
								<div className="space-y-1.5">
									<Label htmlFor="wh-url" className="text-xs text-muted-foreground">
										Endpoint URL
									</Label>
									<Input
										id="wh-url"
										value={url}
										onChange={(e: ChangeEvent<HTMLInputElement>) => setUrl(e.target.value)}
										placeholder="https://example.com/webhook"
										maxLength={2048}
										required
										className="h-8 text-sm font-mono"
										autoFocus
									/>
									<p className="text-[10px] text-muted-foreground">
										HTTPS is required. HTTP is allowed only for a local loopback development endpoint.
									</p>
								</div>

								{/* App picker */}
								<div className="space-y-2">
									<Label className="text-xs text-muted-foreground">Scope</Label>
									<div className="flex flex-wrap gap-1.5">
										{APPS.map((app) => (
											<button
												key={app.id}
												type="button"
												onClick={() => selectApp(app.id)}
												className={`px-3 py-1.5 text-xs border rounded-sm transition-all ${
													selectedApp === app.id
														? 'border-accent bg-accent/15 text-foreground shadow-sm'
														: 'border-border text-muted-foreground hover:border-foreground/40 hover:text-foreground hover:bg-muted/30'
												}`}
											>
												{app.label}
											</button>
										))}
										<button
											type="button"
											onClick={() => selectApp('other')}
											className={`px-3 py-1.5 text-xs border rounded-sm transition-all ${
												selectedApp === 'other'
													? 'border-accent bg-accent/15 text-foreground shadow-sm'
													: 'border-border text-muted-foreground hover:border-foreground/40 hover:text-foreground hover:bg-muted/30'
											}`}
										>
											Other
										</button>
									</div>
								</div>

								{/* Scope detail — known app */}
								{selectedApp && selectedApp !== 'other' && (
									<div className="space-y-1.5">
										<Label htmlFor="wh-path" className="text-xs text-muted-foreground">
											Collection / glob
										</Label>
										<div className="flex items-center gap-0 border border-border rounded-sm focus-within:border-accent transition-colors">
											<span className="px-2.5 py-1.5 text-xs text-muted-foreground bg-muted/40 border-r border-border whitespace-nowrap select-none">
												at://{effectiveDid ? `${effectiveDid.slice(0, 16)}...` : 'did'}/
											</span>
											<input
												id="wh-path"
												value={scopePath}
												onChange={(e: ChangeEvent<HTMLInputElement>) => setScopePath(e.target.value)}
												placeholder="app.bsky.*"
												className="flex-1 px-2.5 py-1.5 text-xs bg-transparent outline-none font-mono"
											/>
										</div>
									</div>
								)}

								{/* Scope detail — other */}
								{selectedApp === 'other' && (
									<div className="space-y-2">
										<Label className="text-xs text-muted-foreground">Scope Level</Label>
										<div className="space-y-1.5">
											{(
												[
													['all', 'All my records'],
													['collection', 'Specific collection'],
													['rkey', 'Specific record'],
												] as const
											).map(([mode, label]) => (
												<label key={mode} className="flex items-center gap-2 cursor-pointer group">
													<input
														type="radio"
														name="other-mode"
														checked={otherMode === mode}
														onChange={() => setOtherMode(mode)}
														className="accent-accent"
													/>
													<span className="text-xs group-hover:text-foreground transition-colors">{label}</span>
												</label>
											))}
										</div>
										{otherMode === 'collection' && (
											<Input
												value={otherCollection}
												onChange={(e: ChangeEvent<HTMLInputElement>) => setOtherCollection(e.target.value)}
												placeholder="app.bsky.feed.post"
												className="h-8 text-xs font-mono"
											/>
										)}
										{otherMode === 'rkey' && (
											<div className="flex gap-2">
												<Input
													value={otherCollection}
													onChange={(e: ChangeEvent<HTMLInputElement>) => setOtherCollection(e.target.value)}
													placeholder="collection"
													className="h-8 text-xs flex-1 font-mono"
												/>
												<Input
													value={otherRkey}
													onChange={(e: ChangeEvent<HTMLInputElement>) => setOtherRkey(e.target.value)}
													placeholder="rkey"
													className="h-8 text-xs flex-1 font-mono"
												/>
											</div>
										)}
									</div>
								)}

								{/* Scope preview */}
								{scopeAturi && (
									<div className="p-2.5 bg-muted/20 border border-border/20 rounded-sm">
										<p className="text-[10px] uppercase tracking-wider text-muted-foreground mb-1">Scope Preview</p>
										<p className="text-xs font-mono break-all">{scopeAturi}</p>
									</div>
								)}

								{/* Wildcard hint */}
								{scopeAturi.includes('*') && (
									<p className="text-xs text-muted-foreground">
										<code className="bg-muted/50 px-1.5 py-0.5 rounded-sm border border-border/20">*</code> matches any
										collection name at that level
									</p>
								)}

								{/* Custom DID override */}
								<div className="space-y-1.5">
									<div className="flex items-center gap-2">
										<Checkbox
											id="wh-custom-did"
											checked={useCustomDid}
											onCheckedChange={(v: boolean | 'indeterminate') => setUseCustomDid(!!v)}
										/>
										<Label htmlFor="wh-custom-did" className="cursor-pointer text-xs">
											Custom scope DID (default: your DID)
										</Label>
									</div>
									{useCustomDid && (
										<Input
											value={customDid}
											onChange={(e: ChangeEvent<HTMLInputElement>) => setCustomDid(e.target.value)}
											placeholder="did:plc:..."
											className="h-8 text-xs font-mono"
										/>
									)}
								</div>

								{/* Options row */}
								{selectedApp && (
									<div className="flex flex-col sm:flex-row sm:items-start gap-4 pt-1">
										{/* Backlinks */}
										<div className="flex items-center gap-2">
											<Checkbox
												id="wh-backlinks"
												checked={backlinks}
												onCheckedChange={(v: boolean | 'indeterminate') => setBacklinks(!!v)}
											/>
											<Label htmlFor="wh-backlinks" className="cursor-pointer text-xs">
												Backlinks
											</Label>
										</div>

										{/* Events */}
										<div className="flex items-center gap-3">
											<span className="text-xs text-muted-foreground">Events:</span>
											{(
												[
													['create', eventCreate, setEventCreate],
													['update', eventUpdate, setEventUpdate],
													['delete', eventDelete, setEventDelete],
												] as const
											).map(([name, val, set]) => (
												<div key={name} className="flex items-center gap-1.5">
													<Checkbox
														id={`wh-event-${name}`}
														checked={val}
														onCheckedChange={(v: boolean | 'indeterminate') => set(!!v)}
													/>
													<Label htmlFor={`wh-event-${name}`} className="cursor-pointer text-xs capitalize">
														{name}
													</Label>
												</div>
											))}
										</div>
									</div>
								)}

								{/* Signing secret */}
								<div className="space-y-1.5">
									<Label className="text-xs text-muted-foreground">Signing Secret (optional)</Label>
									<select
										value={selectedSecretId}
										onChange={(e) => setSelectedSecretId(e.target.value)}
										className="h-8 w-full text-xs font-mono bg-background border border-border rounded-sm px-2.5 outline-none focus:border-accent transition-colors"
									>
										<option value="">— none —</option>
										{secrets.map((s) => (
											<option key={s.name} value={s.name}>
												{s.name}
											</option>
										))}
									</select>
									{secrets.length === 0 && (
										<p className="text-[10px] text-muted-foreground">
											No secrets yet — create one in the Secrets section below.
										</p>
									)}
								</div>

								{error && (
									<div className="p-2.5 bg-destructive/10 border border-destructive/20 rounded-sm">
										<p className="text-xs text-destructive">{error}</p>
									</div>
								)}
								{success && (
									<div className="p-2.5 bg-green-500/10 border border-green-500/20 rounded-sm flex items-center gap-2">
										<CheckCircle2 className="w-3 h-3 text-green-500" />
										<p className="text-xs text-green-500">{success}</p>
									</div>
								)}

								{selectedApp && (
									<Button type="submit" disabled={isCreating || !scopeAturi} size="sm" className="w-full sm:w-auto">
										{isCreating ? (
											<>
												<Loader2 className="w-3 h-3 mr-2 animate-spin" />
												Creating...
											</>
										) : (
											'Create Webhook'
										)}
									</Button>
								)}
							</form>
						</div>
					)}

					{/* Webhook list */}
					{webhooksLoading ? (
						<div className="space-y-2">
							{['a', 'b'].map((id) => (
								<SkeletonShimmer key={id} className="h-16 w-full" />
							))}
						</div>
					) : webhooks.length === 0 ? (
						<div className="py-8 text-center space-y-3">
							<Webhook className="w-6 h-6 text-muted-foreground/50 mx-auto" />
							<div>
								<p className="text-sm text-muted-foreground">No webhooks configured</p>
								<p className="text-xs text-muted-foreground/70 mt-1 max-w-xs mx-auto">
									Create one to receive HTTP callbacks for changes to your ATProto collections
								</p>
							</div>
							{!showCreateForm && (
								<Button variant="outline" size="sm" className="text-xs" onClick={() => setShowCreateForm(true)}>
									<Plus className="w-3 h-3 mr-1.5" />
									Create your first webhook
								</Button>
							)}
						</div>
					) : (
						<div className="space-y-1.5">
							{webhooks.map((wh, idx) => {
								const isFocused = idx === focusedWebhook
								// Extract the collection/path from the AT-URI for display
								const scopeParts = wh.scopeAturi.replace('at://', '').split('/')
								const scopeDisplay = scopeParts.slice(1).join('/') || 'all records'

								return (
									<div
										key={wh.rkey}
										ref={(el) => {
											itemRefs.current[idx] = el
										}}
										className={`flex items-start justify-between p-3 border transition-colors ${
											isFocused ? 'border-accent bg-accent/10' : 'border-border/30 hover:bg-muted/10'
										}`}
									>
										<div className="space-y-1.5 min-w-0 flex-1">
											<div className="flex items-center gap-2">
												<div
													className={`w-1.5 h-1.5 rounded-full flex-shrink-0 ${wh.enabled ? 'bg-green-500' : 'bg-muted-foreground/30'}`}
												/>
												<p className="text-xs font-medium truncate">{wh.url}</p>
												<a
													href={wh.url}
													target="_blank"
													rel="noopener noreferrer"
													className="text-muted-foreground hover:text-foreground transition-colors flex-shrink-0"
													onClick={(e) => e.stopPropagation()}
												>
													<ExternalLink className="w-2.5 h-2.5" />
												</a>
											</div>
											<p className="text-xs text-muted-foreground truncate ml-3.5 font-mono">{scopeDisplay}</p>
											<div className="flex gap-1 flex-wrap ml-3.5">
												{!wh.enabled && (
													<Badge variant="secondary" className="text-[10px]">
														disabled
													</Badge>
												)}
												{wh.backlinks && (
													<Badge variant="outline" className="text-[10px]">
														backlinks
													</Badge>
												)}
												{wh.secretId && (
													<Badge variant="outline" className="text-[10px] gap-1">
														<KeyRound className="w-2.5 h-2.5" />
														{wh.secretId}
													</Badge>
												)}
												{wh.events.length > 0 ? (
													wh.events.map((e) => (
														<Badge key={e} variant="outline" className="text-[10px]">
															{e}
														</Badge>
													))
												) : (
													<Badge variant="outline" className="text-[10px]">
														all events
													</Badge>
												)}
											</div>
										</div>
										<Button
											variant="ghost"
											size="sm"
											onClick={() => handleDelete(wh.rkey)}
											disabled={deletingRkey === wh.rkey}
											className="flex-shrink-0 h-7 w-7 p-0 text-muted-foreground hover:text-destructive"
										>
											{deletingRkey === wh.rkey ? (
												<Loader2 className="w-3 h-3 animate-spin" />
											) : (
												<Trash2 className="w-3 h-3" />
											)}
										</Button>
									</div>
								)
							})}
						</div>
					)}
				</div>

				{/* Signing Secrets */}
				<div className="p-4 border-t border-border/30 space-y-3">
					<div className="flex items-center justify-between">
						<div className="flex items-center gap-2">
							<KeyRound className="w-3.5 h-3.5 text-muted-foreground" />
							<p className="text-xs uppercase tracking-wider text-muted-foreground">Signing Secrets</p>
						</div>
						<Button
							variant="outline"
							size="sm"
							className="h-7 text-xs px-3"
							onClick={() => {
								setShowSecretsPanel((v) => !v)
								setSecretError(null)
								setRevealedToken(null)
							}}
						>
							{showSecretsPanel ? (
								<>
									<ChevronUp className="w-3 h-3 mr-1.5" />
									Hide
								</>
							) : (
								<>
									<ChevronDown className="w-3 h-3 mr-1.5" />
									Manage
								</>
							)}
						</Button>
					</div>

					{showSecretsPanel && (
						<div className="space-y-3">
							{/* Create new secret */}
							<div className="flex gap-2">
								<Input
									value={newSecretName}
									onChange={(e: ChangeEvent<HTMLInputElement>) => setNewSecretName(e.target.value)}
									placeholder="secret name (e.g. my-server)"
									maxLength={64}
									pattern="[A-Za-z0-9._-]+"
									title="Use 1–64 ASCII letters, digits, dots, underscores, or hyphens"
									className="h-8 text-xs font-mono flex-1"
								/>
								<Button
									size="sm"
									className="h-8 text-xs px-3 flex-shrink-0"
									disabled={isCreatingSecret || !newSecretName.trim()}
									onClick={async () => {
										setSecretError(null)
										setRevealedToken(null)
										try {
											const { token } = await onCreateSecret(newSecretName.trim())
											setRevealedToken({ name: newSecretName.trim(), token })
											setNewSecretName('')
										} catch (err) {
											setSecretError(err instanceof Error ? err.message : 'Failed to create secret')
										}
									}}
								>
									{isCreatingSecret ? <Loader2 className="w-3 h-3 animate-spin" /> : <Plus className="w-3 h-3 mr-1" />}
									Create
								</Button>
							</div>

							{secretError && <p className="text-xs text-destructive">{secretError}</p>}

							{/* Revealed token — show once */}
							{revealedToken && (
								<div className="p-3 bg-green-500/10 border border-green-500/20 rounded-sm space-y-2">
									<p className="text-[10px] uppercase tracking-wider text-green-500">
										New token for <strong>{revealedToken.name}</strong> — copy it now, it won't be shown again
									</p>
									<div className="flex items-center gap-2">
										<code className="text-xs font-mono break-all flex-1 text-green-400">{revealedToken.token}</code>
										<button
											type="button"
											onClick={() => {
												navigator.clipboard.writeText(revealedToken.token)
												setCopiedToken(true)
												setTimeout(() => setCopiedToken(false), 2000)
											}}
											className="flex-shrink-0 text-green-400 hover:text-green-300"
										>
											{copiedToken ? <CheckCircle2 className="w-3.5 h-3.5" /> : <Copy className="w-3.5 h-3.5" />}
										</button>
									</div>
								</div>
							)}

							{/* Secret list */}
							{secretsLoading ? (
								<SkeletonShimmer className="h-8 w-full" />
							) : secrets.length === 0 ? (
								<p className="text-xs text-muted-foreground py-2 text-center">No secrets yet</p>
							) : (
								<div className="space-y-1">
									{secrets.map((s) => (
										<div
											key={s.name}
											className="flex items-center justify-between p-2.5 border border-border/30 rounded-sm"
										>
											<div className="space-y-0.5 min-w-0 flex-1">
												<p className="text-xs font-mono font-medium">{s.name}</p>
												<p className="text-[10px] text-muted-foreground">
													Created {new Date(s.createdAt).toLocaleDateString()}
													{s.lastRotatedAt && ` · rotated ${new Date(s.lastRotatedAt).toLocaleDateString()}`}
												</p>
											</div>
											<div className="flex items-center gap-1 flex-shrink-0">
												<Button
													variant="ghost"
													size="sm"
													className="h-7 w-7 p-0 text-muted-foreground hover:text-foreground"
													disabled={rotatingSecret === s.name}
													title="Rotate"
													onClick={async () => {
														setSecretError(null)
														setRevealedToken(null)
														setRotatingSecret(s.name)
														try {
															const { token } = await onRotateSecret(s.name)
															setRevealedToken({ name: s.name, token })
														} catch (err) {
															setSecretError(err instanceof Error ? err.message : 'Failed to rotate secret')
														} finally {
															setRotatingSecret(null)
														}
													}}
												>
													{rotatingSecret === s.name ? (
														<Loader2 className="w-3 h-3 animate-spin" />
													) : (
														<RotateCcw className="w-3 h-3" />
													)}
												</Button>
												<Button
													variant="ghost"
													size="sm"
													className="h-7 w-7 p-0 text-muted-foreground hover:text-destructive"
													disabled={deletingSecret === s.name}
													title="Delete"
													onClick={async () => {
														setSecretError(null)
														setDeletingSecret(s.name)
														try {
															await onDeleteSecret(s.name)
														} catch (err) {
															setSecretError(err instanceof Error ? err.message : 'Failed to delete secret')
														} finally {
															setDeletingSecret(null)
														}
													}}
												>
													{deletingSecret === s.name ? (
														<Loader2 className="w-3 h-3 animate-spin" />
													) : (
														<Trash2 className="w-3 h-3" />
													)}
												</Button>
											</div>
										</div>
									))}
								</div>
							)}
						</div>
					)}
				</div>

				{/* Event Logs — table */}
				<div className="p-4 border-t border-border/30 space-y-3">
					{/* Section header */}
					<div className="flex items-center justify-between">
						<p className="text-xs uppercase tracking-wider text-muted-foreground">Recent Deliveries</p>
						<Button
							variant="outline"
							size="sm"
							onClick={onRefreshEvents}
							disabled={eventLogsLoading}
							className="h-7 px-2 gap-1.5 text-xs"
						>
							<RefreshCw className={`w-3 h-3 ${eventLogsLoading ? 'animate-spin' : ''}`} />
							Refresh
						</Button>
					</div>

					{/* Filter bar — only show when there's data */}
					{!eventLogsLoading && eventLogs.length > 0 && (
						<div className="flex flex-wrap gap-2 items-center">
							{/* Scope / URL search */}
							<div className="relative">
								<Input
									value={filterScope}
									onChange={(e: ChangeEvent<HTMLInputElement>) => setFilterScope(e.target.value)}
									placeholder="Filter by collection or URL…"
									className="h-7 text-xs pr-7 w-72 font-mono"
								/>
								{filterScope && (
									<button
										type="button"
										onClick={() => setFilterScope('')}
										className="absolute right-1.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
									>
										<X className="w-3 h-3" />
									</button>
								)}
							</div>

							{/* Status filter */}
							<div className="flex items-center gap-1 border border-border/30 rounded-sm overflow-hidden">
								{(['all', 'ok', 'failed'] as const).map((s) => (
									<button
										key={s}
										type="button"
										onClick={() => setFilterStatus(s)}
										className={`px-2.5 py-1 text-[10px] uppercase tracking-wider transition-colors ${
											filterStatus === s
												? s === 'failed'
													? 'bg-destructive/20 text-destructive'
													: s === 'ok'
														? 'bg-green-500/20 text-green-500'
														: 'bg-accent/20 text-foreground'
												: 'text-muted-foreground hover:text-foreground hover:bg-muted/20'
										}`}
									>
										{s}
									</button>
								))}
							</div>

							{/* Event-kind filter */}
							{uniqueKinds.length > 0 && (
								<div className="flex items-center gap-1 border border-border/30 rounded-sm overflow-hidden">
									<button
										type="button"
										onClick={() => setFilterKind('all')}
										className={`px-2.5 py-1 text-[10px] uppercase tracking-wider transition-colors ${
											filterKind === 'all'
												? 'bg-accent/20 text-foreground'
												: 'text-muted-foreground hover:text-foreground hover:bg-muted/20'
										}`}
									>
										all
									</button>
									{uniqueKinds.map((k) => (
										<button
											key={k}
											type="button"
											onClick={() => setFilterKind(k)}
											className={`px-2.5 py-1 text-[10px] uppercase tracking-wider capitalize transition-colors ${
												filterKind === k
													? 'bg-accent/20 text-foreground'
													: 'text-muted-foreground hover:text-foreground hover:bg-muted/20'
											}`}
										>
											{k}
										</button>
									))}
								</div>
							)}

							{/* Active-filter count badge */}
							{filteredLogs.length !== eventLogs.length && (
								<span className="text-[10px] text-muted-foreground">
									{filteredLogs.length} / {eventLogs.length}
								</span>
							)}
						</div>
					)}

					{/* Table */}
					{eventLogsLoading ? (
						<div className="space-y-1.5">
							{['a', 'b', 'c'].map((id) => (
								<SkeletonShimmer key={id} className="h-9 w-full" />
							))}
						</div>
					) : eventLogs.length === 0 ? (
						<p className="text-xs text-muted-foreground py-4 text-center">No delivery events yet</p>
					) : filteredLogs.length === 0 ? (
						<p className="text-xs text-muted-foreground py-4 text-center">No deliveries match the current filters</p>
					) : (
						<div className="border border-border/30 rounded-sm overflow-hidden">
							<Table>
								<TableHeader>
									<TableRow className="hover:bg-transparent">
										{/* Status */}
										<TableHead className="cursor-pointer select-none w-16" onClick={() => handleSortCol('status')}>
											Status <SortIcon col="status" />
										</TableHead>
										{/* Event kind */}
										<TableHead className="cursor-pointer select-none w-24" onClick={() => handleSortCol('eventKind')}>
											Event <SortIcon col="eventKind" />
										</TableHead>
										{/* Collection / scope */}
										<TableHead className="cursor-pointer select-none" onClick={() => handleSortCol('eventCollection')}>
											Collection <SortIcon col="eventCollection" />
										</TableHead>
										{/* URL */}
										<TableHead
											className="cursor-pointer select-none hidden md:table-cell"
											onClick={() => handleSortCol('url')}
										>
											Endpoint <SortIcon col="url" />
										</TableHead>
										{/* Time */}
										<TableHead
											className="cursor-pointer select-none w-24 text-right"
											onClick={() => handleSortCol('deliveredAt')}
										>
											Time <SortIcon col="deliveredAt" />
										</TableHead>
									</TableRow>
								</TableHeader>
								<TableBody>
									{filteredLogs.map((log) => (
										<TableRow key={`${log.rkey}-${log.deliveredAt}`}>
											{/* Status */}
											<TableCell>
												<Badge
													variant={log.status === 'ok' ? 'default' : 'destructive'}
													className="text-[10px] tabular-nums"
												>
													{log.status === 'ok' ? '200' : 'ERR'}
												</Badge>
											</TableCell>

											{/* Event kind */}
											<TableCell>
												<span className="text-xs capitalize font-medium">{log.eventKind}</span>
											</TableCell>

											{/* Collection */}
											<TableCell>
												<span
													className="text-xs font-mono text-muted-foreground truncate block max-w-[16rem]"
													title={log.eventCollection}
												>
													{log.eventCollection || '—'}
												</span>
											</TableCell>

											{/* URL */}
											<TableCell className="hidden md:table-cell">
												<a
													href={log.url}
													target="_blank"
													rel="noopener noreferrer"
													className="text-xs text-muted-foreground hover:text-foreground inline-flex items-center gap-1 max-w-[14rem] truncate transition-colors"
													title={log.url}
												>
													<span className="truncate">{log.url}</span>
													<ExternalLink className="w-2.5 h-2.5 flex-shrink-0" />
												</a>
											</TableCell>

											{/* Time */}
											<TableCell className="text-right">
												<span className="text-[10px] text-muted-foreground whitespace-nowrap">
													{formatTimeAgo(log.deliveredAt)}
												</span>
											</TableCell>
										</TableRow>
									))}
								</TableBody>
							</Table>
						</div>
					)}
				</div>
			</div>
		</div>
	)
})
