/**
 * BYOK API Keys Modal - Uses vault for secure key storage
 * Tab 1: Add new keys (stores in vault with metadata.provider)
 * Tab 2: Manage existing keys with delete functionality
 */

import { useState, useEffect, useCallback } from 'react';
import { Key, Check, AlertCircle, Loader2, Plus, Settings, Trash2, Eye, Lock } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
import { Tabs } from '@cloudflare/kumo';
import {
	Dialog,
	DialogContent,
	DialogDescription,
	DialogFooter,
	DialogHeader,
	DialogTitle,
} from '@/components/ui/dialog';
import {
	AlertDialog,
	AlertDialogAction,
	AlertDialogCancel,
	AlertDialogContent,
	AlertDialogDescription,
	AlertDialogFooter,
	AlertDialogHeader,
	AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { apiClient } from '@/lib/api-client';
import { useVault, type SecretListItem } from '@/contexts/vault-context';
import { VaultUnlockModal } from '@/components/vault/VaultUnlockModal';
import { VaultSetupWizard } from '@/components/vault/VaultSetupWizard';
import { toast } from 'sonner';
import type { SecretTemplate } from '@/api-types';

// Import provider logos
import OpenAILogo from '@/assets/provider-logos/openai.svg?react';
import AnthropicLogo from '@/assets/provider-logos/anthropic.svg?react';
import GoogleLogo from '@/assets/provider-logos/google.svg?react';
import CerebrasLogo from '@/assets/provider-logos/cerebras.svg?react';
import CloudflareLogo from '@/assets/provider-logos/cloudflare.svg?react';

interface ByokApiKeysModalProps {
	isOpen: boolean;
	onClose: () => void;
	onKeyAdded?: () => void;
}

interface ManagedSecret {
	id: string;
	name: string;
	provider: string;
	envVarName?: string;
	createdAt: string;
	logo: React.ComponentType<{ className?: string }>;
}

// Logo mapping for dynamic provider support
const PROVIDER_LOGOS: Record<string, React.ComponentType<{ className?: string }>> = {
	openai: OpenAILogo,
	anthropic: AnthropicLogo,
	'google-ai-studio': GoogleLogo,
	cerebras: CerebrasLogo,
};

interface BYOKProvider {
	id: string;
	name: string;
	provider: string;
	envVarName: string;
	logo: React.ComponentType<{ className?: string }>;
	placeholder: string;
	validation: RegExp;
}

/**
 * Convert BYOK template to provider configuration
 */
function templateToBYOKProvider(template: SecretTemplate): BYOKProvider {
	const logo = PROVIDER_LOGOS[template.provider] || (() => <div className="w-4 h-4 bg-gray-300 rounded" />);

	return {
		id: template.id,
		name: template.displayName.replace(' (BYOK)', ''),
		provider: template.provider,
		envVarName: template.envVarName,
		logo,
		placeholder: template.placeholder,
		validation: new RegExp(template.validation),
	};
}

export function ByokApiKeysModal({ isOpen, onClose, onKeyAdded }: ByokApiKeysModalProps) {
	const { state, isUnlocked, encryptAndStoreSecret, listSecrets, deleteSecret } = useVault();

	// Tab management
	const [activeTab, setActiveTab] = useState<'add' | 'manage'>('add');

	// Add keys tab state
	const [selectedProvider, setSelectedProvider] = useState<string | null>(null);
	const [apiKey, setApiKey] = useState('');
	const [isSaving, setIsSaving] = useState(false);
	const [byokProviders, setBYOKProviders] = useState<BYOKProvider[]>([]);
	const [isLoading, setIsLoading] = useState(true);

	// Manage keys tab state
	const [managedSecrets, setManagedSecrets] = useState<ManagedSecret[]>([]);
	const [loadingSecrets, setLoadingSecrets] = useState(false);
	const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
	const [secretToDelete, setSecretToDelete] = useState<ManagedSecret | null>(null);
	const [isDeleting, setIsDeleting] = useState(false);

	// Vault modals
	const [showUnlockModal, setShowUnlockModal] = useState(false);
	const [showSetupModal, setShowSetupModal] = useState(false);

	// Get selected provider details
	const provider = byokProviders.find((p) => p.id === selectedProvider);

	const loadBYOKProviders = useCallback(async () => {
		try {
			setIsLoading(true);
			const response = await apiClient.getBYOKTemplates();

			if (response.success && response.data) {
				const providers = response.data.templates.map(templateToBYOKProvider);
				setBYOKProviders(providers);
			} else {
				toast.error('Failed to load BYOK providers');
			}
		} catch (error) {
			console.error('Error loading BYOK templates:', error);
			toast.error('Failed to load BYOK providers');
		} finally {
			setIsLoading(false);
		}
	}, []);

	const loadManagedSecrets = useCallback(async () => {
		if (!isUnlocked) return;

		try {
			setLoadingSecrets(true);
			const secrets = await listSecrets();

			// Filter secrets that have provider metadata (BYOK keys)
			const byokSecrets: ManagedSecret[] = secrets
				.filter((secret: SecretListItem) => secret.metadata?.provider)
				.map((secret: SecretListItem) => {
					const providerKey = secret.metadata?.provider as string;
					const logo =
						PROVIDER_LOGOS[providerKey] || (() => <div className="w-4 h-4 bg-gray-300 rounded" />);

					return {
						id: secret.id,
						name: secret.name,
						provider: providerKey,
						envVarName: secret.metadata?.envVarName as string | undefined,
						createdAt: secret.createdAt,
						logo,
					};
				});

			setManagedSecrets(byokSecrets);
		} catch (error) {
			console.error('Error loading managed secrets:', error);
			toast.error('Failed to load API keys');
		} finally {
			setLoadingSecrets(false);
		}
	}, [isUnlocked, listSecrets]);

	// Load BYOK templates when modal opens
	useEffect(() => {
		if (isOpen) {
			// Reset add keys tab
			setSelectedProvider(null);
			setApiKey('');
			setIsSaving(false);

			// Reset manage keys tab
			setDeleteDialogOpen(false);
			setSecretToDelete(null);
			setIsDeleting(false);

			// Load data
			loadBYOKProviders();
		}
	}, [isOpen, loadBYOKProviders]);

	// Load secrets when vault is unlocked
	useEffect(() => {
		if (isOpen && isUnlocked) {
			loadManagedSecrets();
		} else if (isOpen && !isUnlocked) {
			setManagedSecrets([]);
		}
	}, [isOpen, isUnlocked, loadManagedSecrets]);

	// Handle provider selection
	const handleProviderSelect = (providerId: string) => {
		setSelectedProvider(providerId);
		setApiKey('');
	};

	// Validate key format
	const isKeyFormatValid = provider && apiKey && provider.validation.test(apiKey);

	// Save API key to vault
	const handleSaveKey = async () => {
		if (!provider || !apiKey || !isKeyFormatValid) return;

		// Check vault status
		if (state.status === 'not_setup') {
			setShowSetupModal(true);
			return;
		}

		if (!isUnlocked) {
			setShowUnlockModal(true);
			return;
		}

		setIsSaving(true);

		try {
			// Store in vault with provider metadata
			const secretId = await encryptAndStoreSecret(provider.name, apiKey.trim(), {
				provider: provider.provider,
				envVarName: provider.envVarName,
			});

			if (secretId) {
				toast.success(`${provider.name} API key added successfully!`);
				onKeyAdded?.();

				// Reload managed secrets and switch to manage tab
				await loadManagedSecrets();
				setActiveTab('manage');

				// Reset add form
				setSelectedProvider(null);
				setApiKey('');
			} else {
				toast.error('Failed to save API key');
			}
		} catch (error) {
			console.error('Failed to save API key:', error);
			toast.error('Failed to save API key. Please try again.');
		} finally {
			setIsSaving(false);
		}
	};

	// Delete secret from vault
	const handleDeleteSecret = async () => {
		if (!secretToDelete) return;

		setIsDeleting(true);

		try {
			const success = await deleteSecret(secretToDelete.id);
			if (success) {
				toast.success(`${secretToDelete.name} API key deleted successfully`);

				// Remove from local state
				setManagedSecrets((prev) => prev.filter((secret) => secret.id !== secretToDelete.id));

				// Notify parent about key changes
				onKeyAdded?.();
			} else {
				toast.error('Failed to delete API key');
			}

			// Close dialog
			setDeleteDialogOpen(false);
			setSecretToDelete(null);
		} catch (error) {
			console.error('Error deleting secret:', error);
			toast.error('Failed to delete API key');
		} finally {
			setIsDeleting(false);
		}
	};

	const openDeleteDialog = (secret: ManagedSecret) => {
		setSecretToDelete(secret);
		setDeleteDialogOpen(true);
	};

	const formatDate = (dateString: string) => {
		const date = new Date(dateString);
		return date.toLocaleDateString('en-US', {
			year: 'numeric',
			month: 'short',
			day: 'numeric',
		});
	};

	// Handle vault setup complete
	const handleSetupComplete = () => {
		setShowSetupModal(false);
		// Secrets will reload via useEffect when isUnlocked changes
	};

	// Render vault locked state for manage tab
	const renderVaultLockedState = () => (
		<div className="text-center py-8 text-kumo-subtle">
			<Lock className="h-12 w-12 mx-auto mb-4 opacity-50" />
			<p className="text-lg font-medium mb-2">Vault is locked</p>
			<p className="text-sm mb-4">Unlock your vault to view and manage API keys</p>
			<Button onClick={() => setShowUnlockModal(true)}>
				<Lock className="h-4 w-4 mr-2" />
				Unlock Vault
			</Button>
		</div>
	);

	// Render vault not setup state
	const renderVaultNotSetupState = () => (
		<div className="text-center py-8 text-kumo-subtle">
			<Key className="h-12 w-12 mx-auto mb-4 opacity-50" />
			<p className="text-lg font-medium mb-2">Set up your secure vault</p>
			<p className="text-sm mb-4">Create a vault to securely store your API keys</p>
			<Button onClick={() => setShowSetupModal(true)}>
				<Key className="h-4 w-4 mr-2" />
				Set Up Vault
			</Button>
		</div>
	);

	return (
		<>
			<Dialog open={isOpen} onOpenChange={onClose}>
				<DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
					<DialogHeader>
						<DialogTitle className="flex items-center gap-2">
							<Key className="h-5 w-5" />
							Bring Your Own Key
							<span className="flex items-center gap-1 text-xs text-kumo-subtle font-normal">
								via <CloudflareLogo className="h-3 w-3" /> AI Gateway
							</span>
						</DialogTitle>
						<DialogDescription>
							Add your API keys to use your own provider accounts for billing, or manage existing keys
						</DialogDescription>
					</DialogHeader>

					<div className="space-y-6">
						<Tabs
							value={activeTab}
							onValueChange={(value) => setActiveTab(value as 'add' | 'manage')}
							tabs={[
								{
									value: 'add',
									label: (
										<span className="inline-flex items-center gap-2">
											<Plus className="h-4 w-4" />
											Add Keys
										</span>
									),
								},
								{
									value: 'manage',
									label: (
										<span className="inline-flex items-center gap-2">
											<Settings className="h-4 w-4" />
											Manage Keys
										</span>
									),
								},
							]}
						/>

						{/* Add Keys Tab */}
						{activeTab === 'add' && (
						<div className="space-y-6">
							{/* Provider Selection - Clean List */}
							<div className="space-y-3">
								<Label className="text-sm font-medium">Select Provider</Label>
								{isLoading ? (
									<div className="space-y-2">
										{[1, 2, 3, 4].map((i) => (
											<div
												key={i}
												className="w-full flex items-center gap-3 p-3 rounded-lg border-2 border-gray-200"
											>
												<div className="w-8 h-8 bg-gray-200 rounded-md animate-pulse" />
												<div className="h-4 bg-gray-200 rounded animate-pulse flex-1" />
											</div>
										))}
									</div>
								) : (
									<div className="space-y-2">
										{byokProviders.map((providerOption) => {
											const LogoComponent = providerOption.logo;
											const isSelected = selectedProvider === providerOption.id;
											return (
												<button
													key={providerOption.id}
													onClick={() => handleProviderSelect(providerOption.id)}
													className={`w-full flex items-center gap-3 p-3 rounded-lg border-2 transition-all duration-200 text-left ${
														isSelected
															? 'border-blue-500 bg-blue-50'
															: 'border-gray-200 hover:border-gray-300 hover:bg-gray-50'
													}`}
												>
													<div className="flex items-center justify-center w-8 h-8 bg-white rounded-md border shadow-sm">
														<LogoComponent className="h-5 w-5" />
													</div>
													<span className="font-medium">{providerOption.name}</span>
												</button>
											);
										})}
									</div>
								)}
							</div>

							{/* API Key Input - Smooth Expansion */}
							{selectedProvider && provider && (
								<div className="space-y-3 animate-in slide-in-from-top-2 duration-300">
									<Label htmlFor="apiKey" className="text-sm font-medium">
										Enter your {provider.name} API key
									</Label>
									<div className="relative">
										<Input
											id="apiKey"
											type="password"
											value={apiKey}
											onChange={(e) => setApiKey(e.target.value)}
											placeholder={provider.placeholder}
											className={`pr-10 ${
												apiKey
													? isKeyFormatValid
														? 'border-green-500 focus:border-green-500'
														: 'border-red-500 focus:border-red-500'
													: ''
											}`}
										/>
										{apiKey && (
											<div className="absolute right-3 top-1/2 -translate-y-1/2">
												{isKeyFormatValid ? (
													<Check className="h-4 w-4 text-green-500" />
												) : (
													<AlertCircle className="h-4 w-4 text-red-500" />
												)}
											</div>
										)}
									</div>
									{apiKey && !isKeyFormatValid && (
										<p className="text-xs text-red-600">
											Invalid format. Expected: {provider.placeholder}
										</p>
									)}
								</div>
							)}
						</div>
						)}

						{/* Manage Keys Tab */}
						{activeTab === 'manage' && (
						<div className="space-y-4">
							{state.status === 'not_setup' ? (
								renderVaultNotSetupState()
							) : !isUnlocked ? (
								renderVaultLockedState()
							) : loadingSecrets ? (
								<div className="space-y-4">
									{[1, 2, 3].map((i) => (
										<div key={i} className="flex items-center gap-4 p-4 rounded-lg border">
											<div className="w-8 h-8 bg-gray-200 rounded-md animate-pulse" />
											<div className="flex-1 space-y-2">
												<div className="h-4 bg-gray-200 rounded animate-pulse w-1/3" />
												<div className="h-3 bg-gray-200 rounded animate-pulse w-1/2" />
											</div>
											<div className="w-12 h-6 bg-gray-200 rounded animate-pulse" />
										</div>
									))}
								</div>
							) : managedSecrets.length === 0 ? (
								<div className="text-center py-8 text-kumo-subtle">
									<Key className="h-12 w-12 mx-auto mb-4 opacity-50" />
									<p className="text-lg font-medium mb-2">No API keys configured</p>
									<p className="text-sm">Add your first API key using the "Add Keys" tab</p>
								</div>
							) : (
								<div className="space-y-4">
									<div className="flex items-center justify-between">
										<Label className="text-sm font-medium">Your API Keys</Label>
										<Badge variant="secondary">{managedSecrets.length} total</Badge>
									</div>

									<div className="space-y-3">
										{managedSecrets.map((secret) => {
											const LogoComponent = secret.logo;

											return (
												<div
													key={secret.id}
													className="flex items-center gap-4 p-4 rounded-lg border transition-colors hover:bg-kumo-base/50"
												>
													{/* Provider Logo */}
													<div className="flex items-center justify-center w-8 h-8 rounded-md border shadow-sm bg-white">
														<LogoComponent className="h-5 w-5" />
													</div>

													{/* Key Info */}
													<div className="flex-1 space-y-1">
														<div className="flex items-center gap-2">
															<span className="font-medium capitalize">{secret.name}</span>
														</div>
														<div className="flex items-center gap-3 text-xs text-kumo-subtle">
															<div className="flex items-center gap-1">
																<Eye className="h-3 w-3" />
																<span>{secret.envVarName || secret.provider}</span>
															</div>
															<Separator orientation="vertical" className="h-3" />
															<span>Added {formatDate(secret.createdAt)}</span>
														</div>
													</div>

													{/* Controls */}
													<div className="flex items-center gap-3">
														<Button
															variant="ghost"
															size="sm"
															onClick={() => openDeleteDialog(secret)}
															className="text-red-600 hover:text-red-700 hover:bg-red-50"
														>
															<Trash2 className="h-4 w-4" />
														</Button>
													</div>
												</div>
											);
										})}
									</div>
								</div>
							)}
						</div>
						)}
					</div>

					<DialogFooter>
						<Button variant="outline" onClick={onClose}>
							Close
						</Button>
						{activeTab === 'add' && selectedProvider && (
							<Button onClick={handleSaveKey} disabled={!apiKey || !isKeyFormatValid || isSaving} className="gap-2">
								{isSaving ? (
									<>
										<Loader2 className="h-4 w-4 animate-spin" />
										Adding...
									</>
								) : (
									<>
										<Plus className="h-4 w-4" />
										Add Key
									</>
								)}
							</Button>
						)}
					</DialogFooter>
				</DialogContent>
			</Dialog>

			{/* Delete Confirmation Dialog */}
			<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
				<AlertDialogContent>
					<AlertDialogHeader>
						<AlertDialogTitle>Delete API Key</AlertDialogTitle>
						<AlertDialogDescription>
							Are you sure you want to delete the {secretToDelete?.name} API key? This action cannot be
							undone.
						</AlertDialogDescription>
					</AlertDialogHeader>
					<AlertDialogFooter>
						<AlertDialogCancel>Cancel</AlertDialogCancel>
						<AlertDialogAction
							onClick={handleDeleteSecret}
							disabled={isDeleting}
							className="bg-red-600 hover:bg-red-700"
						>
							{isDeleting ? (
								<>
									<Loader2 className="h-4 w-4 animate-spin mr-2" />
									Deleting...
								</>
							) : (
								'Delete Key'
							)}
						</AlertDialogAction>
					</AlertDialogFooter>
				</AlertDialogContent>
			</AlertDialog>

			{/* Vault Unlock Modal */}
			<VaultUnlockModal open={showUnlockModal} onOpenChange={setShowUnlockModal} />

			{/* Vault Setup Modal */}
			<Dialog open={showSetupModal} onOpenChange={setShowSetupModal}>
				<DialogContent className="sm:max-w-lg p-0 overflow-hidden">
					<VaultSetupWizard
						open={showSetupModal}
						onComplete={handleSetupComplete}
						onCancel={() => setShowSetupModal(false)}
					/>
				</DialogContent>
			</Dialog>
		</>
	);
}
