import {
  BadgeCheck,
  ChevronDown,
  Copy,
  Edit2,
  ExternalLink,
  Key,
  LayoutGrid,
  List as ListIcon,
  Plus,
  Shield,
  Trash2,
  Upload,
  UserPlus,
} from "lucide-react";
import React, { useCallback, useMemo, useRef, useState } from "react";
import { useI18n } from "../application/i18n/I18nProvider";
import { useStoredViewMode } from "../application/state/useStoredViewMode";
import type { GroupConfig } from "../domain/models";
import { reorderVaultItems, sortByVaultOrder } from "../domain/vaultOrder";
import { STORAGE_KEY_VAULT_KEYS_VIEW_MODE } from "../infrastructure/config/storageKeys";
import { logger } from "../lib/logger";
import { cn } from "../lib/utils";
import { Host, Identity, KeyType, ProxyProfile, SSHKey } from "../types";
import { ManagedSource } from "../domain/models";
import { useKeychainBackend } from "../application/state/useKeychainBackend";
import SelectHostPanel from "./SelectHostPanel";
import {
  AsideActionMenu,
  AsideActionMenuItem,
  AsidePanel,
  AsidePanelContent,
} from "./ui/aside-panel";
import { Button } from "./ui/button";


import {
  ContextMenu,
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuSeparator,
  ContextMenuTrigger,
} from "./ui/context-menu";
import { Dropdown, DropdownContent, DropdownTrigger } from "./ui/dropdown";
import { toast } from "./ui/toast";
import { KeychainExportPanel } from "./KeychainExportPanel";
import { KeychainEditPanel } from "./KeychainEditPanel";
import {
  VaultHeaderSearch,
  VaultPageHeader,
  vaultHeaderIconButtonClass,
  vaultSectionTitleClass,
} from "./vault/VaultPageHeader";
import { useVaultItemReorder } from "./vault/vaultReorderDrag";

// Import utilities and components from keychain module
import {
  type FilterTab,
  GenerateStandardPanel,
  IdentityCard,
  IdentityPanel,
  ImportKeyPanel,
  isMacOS,
  KeyCard,
  type PanelMode,
  ViewKeyPanel,
} from "./keychain";

interface KeychainManagerProps {
  keys: SSHKey[];
  identities?: Identity[];
  hosts?: Host[];
  proxyProfiles?: ProxyProfile[];
  customGroups?: string[];
  /**
   * Group default configurations. Needed by the "export public key to
   * host" flow so per-host SSH algorithm settings (legacy / skipEcdsa /
   * overrides) that the host inherits from its group are honored when
   * the export opens its one-off SSH connection.
   */
  groupConfigs?: GroupConfig[];
  managedSources?: ManagedSource[];
  onSave: (key: SSHKey) => void;
  onUpdate: (key: SSHKey) => void;
  onReorderKeys?: (keys: SSHKey[]) => void;
  onDelete: (id: string) => void;
  onSaveIdentity?: (identity: Identity) => void;
  onReorderIdentities?: (identities: Identity[]) => void;
  onDeleteIdentity?: (id: string) => void;
  onNewHost?: () => void;
  onSaveHost?: (host: Host) => void;
  onCreateGroup?: (groupPath: string) => void;
}

const KeychainManager: React.FC<KeychainManagerProps> = ({
  keys,
  identities = [],
  hosts = [],
  proxyProfiles = [],
  customGroups = [],
  groupConfigs = [],
  managedSources = [],
  onSave,
  onUpdate,
  onReorderKeys,
  onDelete,
  onSaveIdentity,
  onReorderIdentities,
  onDeleteIdentity,
  onNewHost: _onNewHost,
  onSaveHost,
  onCreateGroup,
}) => {
  const { t } = useI18n();
  const { generateKeyPair, execCommand } = useKeychainBackend();
  const [activeFilter, setActiveFilter] = useState<FilterTab>("key");
  const [search, setSearch] = useState("");
  const [viewMode, setViewMode] = useStoredViewMode(
    STORAGE_KEY_VAULT_KEYS_VIEW_MODE,
    "grid",
  );

  // Panel stack for navigation (supports back navigation)
  const [panelStack, setPanelStack] = useState<PanelMode[]>([]);
  const panel = useMemo(
    () =>
      panelStack.length > 0
        ? panelStack[panelStack.length - 1]
        : ({ type: "closed" } as PanelMode),
    [panelStack],
  );

  const panelTitle = useMemo(() => {
    switch (panel.type) {
      case "generate":
        return t("keychain.panel.generateKey");
      case "import":
        return t("keychain.panel.newKey");
      case "view":
        return t("keychain.panel.keyDetails");
      case "edit":
        return t("keychain.panel.editKey");
      case "identity":
        return panel.identity
          ? t("keychain.panel.editIdentity")
          : t("keychain.panel.newIdentity");
      case "export":
        return t("keychain.panel.keyExport");
      default:
        return "";
    }
  }, [panel, t]);

  const [showHostSelector, setShowHostSelector] = useState(false);
  const [isExporting, setIsExporting] = useState(false);
  const listRef = useRef<HTMLDivElement | null>(null);

  // Export panel state
  const [exportLocation, setExportLocation] = useState(".ssh");
  const [exportFilename, setExportFilename] = useState("authorized_keys");
  const [exportHost, setExportHost] = useState<Host | null>(null);
  const [exportAdvancedOpen, setExportAdvancedOpen] = useState(false);
  const [exportScript, setExportScript] = useState(`DIR="$HOME/$1"
FILE="$DIR/$2"
if [ ! -d "$DIR" ]; then
  mkdir -p "$DIR"
  chmod 700 "$DIR"
fi
if [ ! -f "$FILE" ]; then
  touch "$FILE"
  chmod 600 "$FILE"
fi
echo $3 >> "$FILE"`);

  // Draft state for forms
  const [draftKey, setDraftKey] = useState<Partial<SSHKey>>({});
  const [draftIdentity, setDraftIdentity] = useState<Partial<Identity>>({});
  const [showPassphrase, setShowPassphrase] = useState(false);
  const [isGenerating, setIsGenerating] = useState(false);

  const keyReorder = useVaultItemReorder({
    containerRef: listRef,
    viewMode,
    dragType: "key-id",
    targetAttribute: "data-key-id",
    disabled: !onReorderKeys || search.trim().length > 0,
    onReorder: (sourceId, targetId, position) => {
      onReorderKeys?.(reorderVaultItems(keys, sourceId, targetId, position));
    },
  });
  const identityReorder = useVaultItemReorder({
    containerRef: listRef,
    viewMode,
    dragType: "identity-id",
    targetAttribute: "data-identity-id",
    disabled: !onReorderIdentities || search.trim().length > 0,
    onReorder: (sourceId, targetId, position) => {
      onReorderIdentities?.(reorderVaultItems(identities, sourceId, targetId, position));
    },
  });

  const showError = useCallback((message: string, title = t("common.error")) => {
    toast.error(message, title);
  }, [t]);

  // Filter keys based on active tab and search
  const filteredKeys = useMemo(() => {
    let result = keys;

    // Filter by tab
    switch (activeFilter) {
      case "key":
        result = result.filter(
          (k) => k.source === "generated" || k.source === "imported" || k.source === "reference",
        );
        break;
      case "certificate":
        result = result.filter(
          (k) => k.category === "certificate" || k.certificate,
        );
        break;
    }

    // Filter by search
    if (search.trim()) {
      const s = search.toLowerCase();
      result = result.filter(
        (k) =>
          k.label.toLowerCase().includes(s) ||
          k.type.toLowerCase().includes(s) ||
          k.publicKey?.toLowerCase().includes(s),
      );
    }

    return sortByVaultOrder(result);
  }, [keys, activeFilter, search]);

  // Filter identities based on search
  const filteredIdentities = useMemo(() => {
    if (!search.trim()) return sortByVaultOrder(identities);
    const s = search.toLowerCase();
    return sortByVaultOrder(identities.filter(
      (i) =>
        i.label.toLowerCase().includes(s) ||
        i.username.toLowerCase().includes(s),
    ));
  }, [identities, search]);

  // Push a new panel onto the stack
  const pushPanel = useCallback((newPanel: PanelMode) => {
    setPanelStack((prev) => [...prev, newPanel]);
  }, []);

  // Pop the top panel from the stack (go back)
  const popPanel = useCallback(() => {
    setPanelStack((prev) => {
      if (prev.length <= 1) {
        // Last panel, close everything
        setDraftKey({});
        setDraftIdentity({});
        setShowPassphrase(false);
        setExportHost(null);
        setExportAdvancedOpen(false);
        return [];
      }
      return prev.slice(0, -1);
    });
  }, []);

  // Close all panels
  const closePanel = useCallback(() => {
    setPanelStack([]);
    setDraftKey({});
    setDraftIdentity({});
    setShowPassphrase(false);
    setExportHost(null);
    setExportAdvancedOpen(false);
  }, []);

  // Open panel for viewing key (replaces stack with single panel)
  const openKeyView = useCallback((key: SSHKey) => {
    setPanelStack([{ type: "view", key }]);
    setDraftKey({ ...key });
  }, []);

  // Open panel for exporting key (pushes onto stack)
  const openKeyExport = useCallback(
    (key: SSHKey) => {
      pushPanel({ type: "export", key });
      setExportHost(null);
      setExportLocation(".ssh");
      setExportFilename("authorized_keys");
    },
    [pushPanel],
  );

  // Open panel for editing key (replaces stack)
  const openKeyEdit = useCallback((key: SSHKey) => {
    setPanelStack([{ type: "edit", key }]);
    setDraftKey({ ...key });
  }, []);

  // Copy public key to clipboard
  const copyPublicKey = useCallback(async (key: SSHKey) => {
    if (key.publicKey) {
      try {
        await navigator.clipboard.writeText(key.publicKey);
        // Could add toast notification here
      } catch (err) {
        logger.error("Failed to copy public key:", err);
      }
    }
  }, []);

  // Open panel for new identity
  const openNewIdentity = useCallback(() => {
    setPanelStack([{ type: "identity" }]);
    setDraftIdentity({
      id: "",
      label: "",
      username: "",
      authMethod: "password",
      created: Date.now(),
    });
  }, []);

  // Open generate panel
  const openGenerate = useCallback(() => {
    const defaultType: KeyType = "ED25519";

    setPanelStack([{ type: "generate", keyType: "standard" }]);
    setDraftKey({
      id: "",
      label: "",
      type: defaultType,
      keySize: undefined,
      privateKey: "",
      publicKey: "",
      source: "generated",
      category: "key",
      created: Date.now(),
    });
  }, []);

  // Open import panel
  const openImport = useCallback(() => {
    setPanelStack([{ type: "import" }]);
    setDraftKey({
      id: "",
      label: "",
      type: "ED25519",
      privateKey: "",
      publicKey: "",
      source: "imported",
      category: "key",
      created: Date.now(),
    });
  }, []);

  // Handle standard key generation
  const handleGenerateStandard = useCallback(async () => {
    if (!draftKey.label?.trim()) {
      showError(t("keychain.validation.labelRequired"), t("common.validation"));
      return;
    }

    setIsGenerating(true);

    try {
      const keyType = (draftKey.type as KeyType) || "ED25519";
      const keySize = draftKey.keySize;

      // Use real key generation via Electron backend
      const result = await generateKeyPair({
        type: keyType,
        bits: keySize,
        comment: `${draftKey.label.trim()}@netcatty`,
      });
      if (!result) {
        throw new Error(
          t("keychain.error.generationUnavailable"),
        );
      }
      if (!result.success || !result.privateKey || !result.publicKey) {
        throw new Error(result.error || t("keychain.error.generateKeyPairFailed"));
      }

      const newKey: SSHKey = {
        id: crypto.randomUUID(),
        label: draftKey.label.trim(),
        type: keyType,
        keySize: keyType !== "ED25519" ? keySize : undefined,
        privateKey: result.privateKey,
        publicKey: result.publicKey,
        passphrase: draftKey.passphrase,
        savePassphrase: draftKey.savePassphrase,
        source: "generated",
        category: "key",
        created: Date.now(),
      };

      onSave(newKey);
      closePanel();
    } catch (err) {
      showError(
        err instanceof Error ? err.message : t("keychain.error.generateKeyFailed"),
        t("keychain.error.keyGenerationTitle"),
      );
    } finally {
      setIsGenerating(false);
    }
  }, [draftKey, onSave, closePanel, generateKeyPair, showError, t]);

  // Handle key import
  const handleImport = useCallback(() => {
    if (!draftKey.label?.trim() || !draftKey.privateKey?.trim()) {
      showError(t("keychain.validation.labelAndPrivateKeyRequired"), t("common.validation"));
      return;
    }

    // Detect key type from private key content
    let detectedType: KeyType = "ED25519";
    const pk = draftKey.privateKey.toLowerCase();
    if (pk.includes("rsa")) detectedType = "RSA";
    else if (pk.includes("ecdsa") || pk.includes("ec ")) detectedType = "ECDSA";
    else if (pk.includes("ed25519")) detectedType = "ED25519";

    const newKey: SSHKey = {
      id: crypto.randomUUID(),
      label: draftKey.label.trim(),
      type: (draftKey.type as KeyType) || detectedType,
      privateKey: draftKey.privateKey.trim(),
      publicKey: draftKey.publicKey?.trim() || undefined,
      certificate: draftKey.certificate?.trim() || undefined,
      passphrase: draftKey.passphrase,
      savePassphrase: draftKey.savePassphrase,
      source: "imported",
      category: draftKey.certificate ? "certificate" : "key",
      created: Date.now(),
    };

    onSave(newKey);
    closePanel();
  }, [draftKey, onSave, closePanel, showError, t]);

  // Handle save identity
  const handleSaveIdentity = useCallback(() => {
    if (!draftIdentity.label?.trim() || !draftIdentity.username?.trim()) {
      showError(t("keychain.validation.labelAndUsernameRequired"), t("common.validation"));
      return;
    }

    if (!onSaveIdentity) return;

    const newIdentity: Identity = {
      id: draftIdentity.id || crypto.randomUUID(),
      label: draftIdentity.label.trim(),
      username: draftIdentity.username.trim(),
      authMethod: draftIdentity.authMethod || "password",
      password: draftIdentity.password,
      keyId: draftIdentity.keyId,
      created: draftIdentity.created || Date.now(),
    };

    onSaveIdentity(newIdentity);
    closePanel();
  }, [draftIdentity, onSaveIdentity, closePanel, showError, t]);

  // Handle delete
  const handleDelete = useCallback(
    async (id: string) => {
      onDelete(id);
      if (panel.type === "view" && panel.key.id === id) {
        closePanel();
      }
    },
    [onDelete, panel, closePanel],
  );

  // Handle delete identity
  const _handleDeleteIdentity = useCallback(
    (id: string) => {
      onDeleteIdentity?.(id);
      if (panel.type === "identity" && panel.identity?.id === id) {
        closePanel();
      }
    },
    [onDeleteIdentity, panel, closePanel],
  );

  // Get icon for key source
  const getKeyIcon = (key: SSHKey) => {
    if (key.certificate) return <BadgeCheck size={16} />;
    return <Key size={16} />;
  };

  // Get key type display
  const getKeyTypeDisplay = (key: SSHKey) => {
    return key.type;
  };

  // File input ref for import
  const fileInputRef = React.useRef<HTMLInputElement>(null);

  // Handle file import
  const handleFileImport = useCallback(
    (event: React.ChangeEvent<HTMLInputElement>) => {
      const file = event.target.files?.[0];
      if (!file) return;

      const reader = new FileReader();
      reader.onload = (e) => {
        const content = e.target?.result as string;
        if (content) {
          // Try to detect key type from content
          let detectedType: KeyType = "ED25519";
          const lc = content.toLowerCase();
          if (lc.includes("rsa")) detectedType = "RSA";
          else if (lc.includes("ecdsa") || lc.includes("ec private"))
            detectedType = "ECDSA";
          else if (lc.includes("ed25519")) detectedType = "ED25519";

          // Extract label from filename (remove extension)
          const label = file.name.replace(/\.(pem|key|pub|ppk)$/i, "");

          setDraftKey((prev) => ({
            ...prev,
            privateKey: content,
            label: prev.label || label,
            type: detectedType,
          }));
        }
      };
      reader.readAsText(file);

      // Reset input so same file can be selected again
      event.target.value = "";
    },
    [],
  );

  return (
    <div className="h-full flex relative">
      {/* Hidden file input */}
      <input
        ref={fileInputRef}
        type="file"
        accept=".pem,.key,.pub,.ppk,*"
        className="hidden"
        onChange={handleFileImport}
      />

      {/* Main Content */}
      <div
        className={cn(
          "flex-1 flex flex-col min-h-0 transition-all duration-200",
          panel.type !== "closed" && "mr-[380px]",
        )}
      >
        <VaultPageHeader>
          {/* Filter Tabs */}
          <div className="flex items-center gap-1">
            {/* KEY button with split interaction: left=switch view, right=dropdown */}
            <Dropdown>
              <div
                className={cn(
                  "flex items-center rounded-md transition-colors",
                  activeFilter === "key"
                    ? "bg-foreground/10 text-foreground hover:bg-foreground/15"
                    : "bg-foreground/5 text-foreground hover:bg-foreground/10",
                )}
              >
                <Button
                  size="sm"
                  variant="ghost"
                  className="h-10 px-3 gap-2 rounded-r-none hover:bg-transparent text-inherit"
                  onClick={() => setActiveFilter("key")}
                >
                  <Key size={14} />
                  {t("keychain.filter.key")}
                </Button>
                <DropdownTrigger asChild>
                  <Button
                    size="sm"
                    variant="ghost"
                    className="h-10 px-1.5 rounded-l-none hover:bg-transparent text-inherit"
                  >
                    <ChevronDown size={12} />
                  </Button>
                </DropdownTrigger>
              </div>
              <DropdownContent className="w-44" align="start" alignToParent>
                <Button
                  variant="ghost"
                  className="w-full justify-start gap-2"
                  onClick={openGenerate}
                >
                  <Plus size={14} /> {t("keychain.action.generateKey")}
                </Button>
                <Button
                  variant="ghost"
                  className="w-full justify-start gap-2"
                  onClick={openImport}
                >
                  <Upload size={14} /> {t("keychain.action.importKey")}
                </Button>
                {onSaveIdentity && (
                  <Button
                    variant="ghost"
                    className="w-full justify-start gap-2"
                    onClick={openNewIdentity}
                  >
                    <UserPlus size={14} /> {t("keychain.action.newIdentity")}
                  </Button>
                )}
              </DropdownContent>
            </Dropdown>

            {/* CERTIFICATE button with split interaction */}
            <Dropdown>
              <div
                className={cn(
                  "flex items-center rounded-md transition-colors",
                  activeFilter === "certificate"
                    ? "bg-foreground/10 text-foreground hover:bg-foreground/15"
                    : "bg-foreground/5 text-foreground hover:bg-foreground/10",
                )}
              >
                <Button
                  size="sm"
                  variant="ghost"
                  className="h-10 px-3 gap-2 rounded-r-none hover:bg-transparent text-inherit"
                  onClick={() => setActiveFilter("certificate")}
                >
                  <BadgeCheck size={14} />
                  {t("keychain.filter.certificate")}
                </Button>
                <DropdownTrigger asChild>
                  <Button
                    size="sm"
                    variant="ghost"
                    className="h-10 px-1.5 rounded-l-none hover:bg-transparent text-inherit"
                  >
                    <ChevronDown size={12} />
                  </Button>
                </DropdownTrigger>
              </div>
              <DropdownContent className="w-48" align="start" alignToParent>
                <Button
                  variant="ghost"
                  className="w-full justify-start gap-2"
                  onClick={openImport}
                >
                  <Upload size={14} /> {t("keychain.action.importCertificate")}
                </Button>
              </DropdownContent>
            </Dropdown>
          </div>

          {/* Search and View Mode - hide search when panel is open */}
          <div className="ml-auto flex items-center gap-2 min-w-0 flex-shrink">
            {panel.type === "closed" && (
              <VaultHeaderSearch
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                placeholder={t("common.searchPlaceholder")}
                className="flex-shrink w-64"
              />
            )}
            <Dropdown>
              <DropdownTrigger asChild>
                <Button
                  variant="ghost"
                  size="icon"
                  className={cn(vaultHeaderIconButtonClass, "flex-shrink-0")}
                >
                  {viewMode === "grid" ? (
                    <LayoutGrid size={16} />
                  ) : (
                    <ListIcon size={16} />
                  )}
                  <ChevronDown size={10} className="ml-0.5" />
                </Button>
              </DropdownTrigger>
              <DropdownContent className="w-32" align="end">
                <Button
                  variant={viewMode === "grid" ? "secondary" : "ghost"}
                  className="w-full justify-start gap-2 h-9"
                  onClick={() => setViewMode("grid")}
                >
                  <LayoutGrid size={14} /> {t("keychain.view.grid")}
                </Button>
                <Button
                  variant={viewMode === "list" ? "secondary" : "ghost"}
                  className="w-full justify-start gap-2 h-9"
                  onClick={() => setViewMode("list")}
                >
                  <ListIcon size={14} /> {t("keychain.view.list")}
                </Button>
              </DropdownContent>
            </Dropdown>
          </div>
        </VaultPageHeader>

        {/* Scrollable Content */}
        <div
          ref={listRef}
          className="flex-1 overflow-y-auto"
          onDragOverCapture={(event) => {
            keyReorder.handleDragOverCapture(event);
            identityReorder.handleDragOverCapture(event);
          }}
          onDragOver={(event) => {
            keyReorder.handleDragOver(event);
            identityReorder.handleDragOver(event);
          }}
          onDropCapture={(event) => {
            keyReorder.handleDropCapture(event);
            identityReorder.handleDropCapture(event);
          }}
          onDragEndCapture={() => {
            keyReorder.handleDragEndCapture();
            identityReorder.handleDragEndCapture();
          }}
        >
          {/* Keys Section */}
          <div className="space-y-3 p-3">
          <div className="flex items-center justify-between">
            <h2 className={vaultSectionTitleClass}>
              {t("keychain.section.keys")}
            </h2>
            <span className="text-xs text-muted-foreground">
              {t("keychain.count.items", { count: filteredKeys.length })}
            </span>
          </div>

          {filteredKeys.length === 0 ? (
            <div className="flex flex-col items-center justify-center h-64 text-muted-foreground">
              <div className="h-16 w-16 rounded-2xl bg-secondary/80 flex items-center justify-center mb-4">
                <Shield size={32} className="opacity-60" />
              </div>
              <h3 className="text-lg font-semibold text-foreground mb-2">
                {t("keychain.empty.title")}
              </h3>
              <p className="text-sm text-center max-w-sm mb-4">
                {t("keychain.empty.desc")}
              </p>
              {(activeFilter === "key" || activeFilter === "certificate") && (
                <div className="flex gap-2">
                  <Button variant="secondary" onClick={openImport}>
                    <Upload size={14} className="mr-2" />
                    {t("common.import")}
                  </Button>
                  <Button onClick={openGenerate}>
                    <Plus size={14} className="mr-2" />
                    {t("common.generate")}
                  </Button>
                </div>
              )}
            </div>
          ) : (
            <div
              className={
                viewMode === "grid"
                  ? "grid gap-3 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
                  : "flex flex-col gap-0"
              }
            >
              {filteredKeys.map((key) => (
                <KeyCard
                  key={key.id}
                  keyItem={key}
                  viewMode={viewMode}
                  isSelected={
                    (panel.type === "view" && panel.key.id === key.id) ||
                    (panel.type === "export" && panel.key.id === key.id)
                  }
                  isMac={isMacOS()}
                  reorderProps={keyReorder.getItemReorderProps(key.id, `key:${key.id}`)}
                  onClick={() => openKeyView(key)}
                  onEdit={() => openKeyEdit(key)}
                  onExport={() => openKeyExport(key)}
                  onCopyPublicKey={() => copyPublicKey(key)}
                  onDelete={() => handleDelete(key.id)}
                />
              ))}
            </div>
          )}
        </div>

        {/* Identities Section */}
        {activeFilter === "key" && filteredIdentities.length > 0 && (
          <div className="space-y-3 px-3 pb-3">
            <div className="flex items-center justify-between">
              <h2 className={vaultSectionTitleClass}>
                {t("keychain.section.identities")}
              </h2>
              <span className="text-xs text-muted-foreground">
                {t("keychain.count.items", { count: filteredIdentities.length })}
              </span>
            </div>
            <div
              className={
                viewMode === "grid"
                  ? "grid gap-3 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
                  : "flex flex-col gap-0"
              }
            >
              {filteredIdentities.map((identity) => (
                <ContextMenu key={identity.id}>
                  <ContextMenuTrigger>
                    <IdentityCard
                      identity={identity}
                      viewMode={viewMode}
                      isSelected={
                        panel.type === "identity" &&
                        panel.identity?.id === identity.id
                      }
                      reorderProps={identityReorder.getItemReorderProps(identity.id, `identity:${identity.id}`)}
                      onClick={() => {
                        setPanelStack([{ type: "identity", identity }]);
                        setDraftIdentity({ ...identity });
                      }}
                    />
                  </ContextMenuTrigger>
                  <ContextMenuContent>
                    <ContextMenuItem
                      onClick={() => {
                        setPanelStack([{ type: "identity", identity }]);
                        setDraftIdentity({ ...identity });
                      }}
                    >
                      <Edit2 className="mr-2 h-4 w-4" /> {t("action.edit")}
                    </ContextMenuItem>
                    {onDeleteIdentity && (
                      <>
                        <ContextMenuSeparator />
                        <ContextMenuItem
                          className="text-destructive"
                          onClick={() => {
                            const ok = window.confirm(
                              t("confirm.deleteIdentity", {
                                name: identity.label || "",
                              }),
                            );
                            if (!ok) return;
                            _handleDeleteIdentity(identity.id);
                          }}
                        >
                          <Trash2 className="mr-2 h-4 w-4" />{" "}
                          {t("action.delete")}
                        </ContextMenuItem>
                      </>
                    )}
                  </ContextMenuContent>
                </ContextMenu>
              ))}
            </div>
          </div>
        )}
        </div>
      </div>

      {/* Slide-out Panel */}
      {panel.type !== "closed" && (
        <AsidePanel
          open={true}
          onClose={closePanel}
          title={panelTitle}
          showBackButton={panelStack.length > 1}
          onBack={popPanel}
          actions={
            panel.type === "identity" && panel.identity && onDeleteIdentity ? (
              <AsideActionMenu>
                <AsideActionMenuItem
                  variant="destructive"
                  icon={<Trash2 size={14} />}
                  onClick={() => {
                    const ok = window.confirm(
                      t("confirm.deleteIdentity", {
                        name: panel.identity?.label || "",
                      }),
                    );
                    if (!ok || !panel.identity) return;
                    _handleDeleteIdentity(panel.identity.id);
                  }}
                >
                  {t("common.delete")}
                </AsideActionMenuItem>
              </AsideActionMenu>
            ) : panel.type === "view" ? (
              <AsideActionMenu>
                {panel.key.publicKey ? (
                  <AsideActionMenuItem
                    icon={<Copy size={14} />}
                    onClick={() => copyPublicKey(panel.key)}
                  >
                    {t("action.copyPublicKey")}
                  </AsideActionMenuItem>
                ) : null}
                <AsideActionMenuItem
                  icon={<ExternalLink size={14} />}
                  onClick={() => openKeyExport(panel.key)}
                >
                  {t("action.keyExport")}
                </AsideActionMenuItem>
                <AsideActionMenuItem
                  icon={<Edit2 size={14} />}
                  onClick={() => openKeyEdit(panel.key)}
                >
                  {t("action.edit")}
                </AsideActionMenuItem>
                <AsideActionMenuItem
                  variant="destructive"
                  icon={<Trash2 size={14} />}
                  onClick={() => handleDelete(panel.key.id)}
                >
                  {t("action.delete")}
                </AsideActionMenuItem>
              </AsideActionMenu>
            ) : undefined
          }
        >
          <AsidePanelContent>
            {/* Generate Standard Key */}
            {panel.type === "generate" && panel.keyType === "standard" && (
              <GenerateStandardPanel
                draftKey={draftKey}
                setDraftKey={setDraftKey}
                showPassphrase={showPassphrase}
                setShowPassphrase={setShowPassphrase}
                isGenerating={isGenerating}
                onGenerate={handleGenerateStandard}
              />
            )}

            {/* Import Key */}
            {panel.type === "import" && (
              <ImportKeyPanel
                draftKey={draftKey}
                setDraftKey={setDraftKey}
                showPassphrase={showPassphrase}
                setShowPassphrase={setShowPassphrase}
                onImport={handleImport}
              />
            )}

            {/* View Key */}
            {panel.type === "view" && (
              <ViewKeyPanel
                keyItem={panel.key}
                onExport={() => openKeyExport(panel.key)}
              />
            )}

            {/* Identity Panel */}
            {panel.type === "identity" && (
              <IdentityPanel
                draftIdentity={draftIdentity}
                setDraftIdentity={setDraftIdentity}
                keys={keys}
                showPassphrase={showPassphrase}
                setShowPassphrase={setShowPassphrase}
                isNew={!panel.identity}
                onSave={handleSaveIdentity}
              />
            )}

            {panel.type === "export" && !showHostSelector && (
              <KeychainExportPanel
                panel={panel}
                t={t}
                getKeyIcon={getKeyIcon}
                getKeyTypeDisplay={getKeyTypeDisplay}
                setShowHostSelector={setShowHostSelector}
                exportHost={exportHost}
                exportLocation={exportLocation}
                setExportLocation={setExportLocation}
                exportFilename={exportFilename}
                setExportFilename={setExportFilename}
                exportAdvancedOpen={exportAdvancedOpen}
                setExportAdvancedOpen={setExportAdvancedOpen}
                exportScript={exportScript}
                setExportScript={setExportScript}
                isExporting={isExporting}
                setIsExporting={setIsExporting}
                keys={keys}
                identities={identities}
                groupConfigs={groupConfigs}
                execCommand={execCommand}
                onSaveIdentity={onSaveIdentity}
                onSaveHost={onSaveHost}
                closePanel={closePanel}
              />
            )}

            {panel.type === "edit" && (
              <KeychainEditPanel
                panel={panel}
                t={t}
                draftKey={draftKey}
                setDraftKey={setDraftKey}
                showPassphrase={showPassphrase}
                setShowPassphrase={setShowPassphrase}
                openKeyExport={openKeyExport}
                onUpdate={onUpdate}
                closePanel={closePanel}
              />
            )}
          </AsidePanelContent>

          {/* Host Selector Overlay for Export */}
          {showHostSelector && panel.type === "export" && (
            <SelectHostPanel
              hosts={hosts}
              customGroups={customGroups}
              selectedHostIds={exportHost?.id ? [exportHost.id] : []}
              multiSelect={false}
              onSelect={(host) => {
                setExportHost(host);
                setShowHostSelector(false);
              }}
              onBack={() => setShowHostSelector(false)}
              onContinue={() => setShowHostSelector(false)}
              availableKeys={keys}
              proxyProfiles={proxyProfiles}
              managedSources={managedSources}
              onSaveHost={onSaveHost}
              onCreateGroup={onCreateGroup}
            />
          )}
        </AsidePanel>
      )}
    </div>
  );
};

export default KeychainManager;
