"use client";

import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
import { open } from "@tauri-apps/plugin-dialog";
import { useReducedMotion } from "motion/react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { FaFileArchive, FaFolder } from "react-icons/fa";
import { LuChevronRight } from "react-icons/lu";
import { toast } from "sonner";
import { LoadingButton } from "@/components/loading-button";
import { Alert, AlertDescription } from "@/components/ui/alert";
import {
  AnimatedDisclosureChevron,
  AnimatedDisclosureContent,
} from "@/components/ui/animated-disclosure";
import {
  AnimatedTabs,
  AnimatedTabsContent,
  AnimatedTabsList,
  AnimatedTabsTrigger,
} from "@/components/ui/animated-tabs";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Progress } from "@/components/ui/progress";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { WayfernConfigForm } from "@/components/wayfern-config-form";
import { useGroupEvents } from "@/hooks/use-group-events";
import { useProxyEvents } from "@/hooks/use-proxy-events";
import { useVpnEvents } from "@/hooks/use-vpn-events";
import { translateBackendError } from "@/lib/backend-errors";
import { getBrowserDisplayName, getBrowserIcon } from "@/lib/browser-utils";
import { fireSprinkleConfetti } from "@/lib/confetti";
import { cn } from "@/lib/utils";
import type {
  ArchiveScanResult,
  DetectedProfile,
  ImportProfileItem,
  ProfileImportBatchResult,
  ProfileImportProgress,
  ProfileImportReport,
  WayfernConfig,
} from "@/types";
import { RippleButton } from "./ui/ripple";

/**
 * What an import actually carried, and what it could not.
 *
 * The counts matter more than they look: an import that reports zero of
 * everything is the exact symptom of the bug where copied data landed where
 * the browser never reads it, and it used to be indistinguishable from success.
 */
function ImportReportSummary({ report }: { report: ProfileImportReport }) {
  const { t } = useTranslation();

  // Label-then-value rather than "{{count}} cookies": it keeps the row scannable
  // and sidesteps needing correct plural forms in ten languages.
  const carried = (
    [
      ["importProfile.reportCookies", report.cookies_migrated],
      ["importProfile.reportPasswords", report.passwords_migrated],
      ["importProfile.reportAutofill", report.payment_methods_migrated],
      ["importProfile.reportExtensions", report.extensions_migrated],
      ["importProfile.reportHistory", report.history_entries],
      ["importProfile.reportBookmarks", report.bookmarks],
      ["importProfile.reportLocalStorage", report.local_storage_origins],
    ] as const
  )
    .filter(([, count]) => count > 0)
    .map(([key, count]) => `${t(key)} ${count.toLocaleString()}`);

  const unrecoverable =
    report.cookies_unrecoverable +
    report.passwords_unrecoverable +
    report.payment_methods_unrecoverable;

  return (
    <div className="mt-0.5 space-y-0.5 pl-1 text-xs text-muted-foreground">
      <p>
        {carried.length > 0
          ? carried.join(" · ")
          : t("importProfile.reportNothingCarried")}
      </p>
      {unrecoverable > 0 && (
        <p>
          {t("importProfile.reportUnrecoverable", { count: unrecoverable })}
        </p>
      )}
      {report.warnings.map((code) => (
        <p key={code} className="text-warning-text">
          {t(`importProfile.warnings.${code}`)}
        </p>
      ))}
    </div>
  );
}

/**
 * Fold a retry's results back into the batch it came from.
 *
 * A retry only resubmits the items that failed, so the previous batch is still
 * authoritative for every other row. Replacing it wholesale would make the
 * successful imports disappear from the summary.
 */
function mergeImportResults(
  previous: ProfileImportBatchResult,
  retry: ProfileImportBatchResult,
): ProfileImportBatchResult {
  const byPath = new Map(retry.results.map((item) => [item.source_path, item]));
  const results = previous.results.map(
    (item) => byPath.get(item.source_path) ?? item,
  );
  const count = (status: string) =>
    results.filter((item) => item.status === status).length;
  return {
    imported_count: count("imported"),
    skipped_count: count("skipped"),
    failed_count: count("failed"),
    results,
  };
}

interface ImportProfileDialogProps {
  isOpen: boolean;
  onClose: () => void;
  crossOsUnlocked?: boolean;
  subPage?: boolean;
}

type Step = "select" | "configure" | "importing";
type ImportMode = "auto-detect" | "manual";
type DuplicateStrategy = "rename" | "skip";

export function ImportProfileDialog({
  isOpen,
  onClose,
  crossOsUnlocked,
  subPage,
}: ImportProfileDialogProps) {
  const { t } = useTranslation();
  const [currentStep, setCurrentStep] = useState<Step>("select");
  const [importMode, setImportMode] = useState<ImportMode>("auto-detect");

  const [detectedProfiles, setDetectedProfiles] = useState<DetectedProfile[]>(
    [],
  );
  const [scannedProfiles, setScannedProfiles] = useState<DetectedProfile[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [isScanning, setIsScanning] = useState(false);
  const [manualPath, setManualPath] = useState("");
  const [extractedDir, setExtractedDir] = useState<string | null>(null);

  const [selectedPaths, setSelectedPaths] = useState<Set<string>>(new Set());
  const [profileNames, setProfileNames] = useState<Record<string, string>>({});

  const [selectedGroupId, setSelectedGroupId] = useState<string>("none");
  const [isCreatingGroup, setIsCreatingGroup] = useState(false);
  const [newGroupName, setNewGroupName] = useState("");
  const [duplicateStrategy, setDuplicateStrategy] =
    useState<DuplicateStrategy>("rename");
  // "none" | "round-robin" | a stored proxy id
  const [proxyAssignment, setProxyAssignment] = useState<string>("none");
  // "none" | a VPN config id (applied to every imported profile)
  const [vpnAssignment, setVpnAssignment] = useState<string>("none");
  const [wayfernConfig, setWayfernConfig] = useState<WayfernConfig>({});
  // Fingerprint + advanced options collapse behind disclosures — the default
  // path is just names + proxy/VPN.
  const [showFingerprint, setShowFingerprint] = useState(false);
  const [showAdvanced, setShowAdvanced] = useState(false);

  const [isImporting, setIsImporting] = useState(false);
  const [progress, setProgress] = useState<ProfileImportProgress | null>(null);
  const [result, setResult] = useState<ProfileImportBatchResult | null>(null);

  const { storedProxies } = useProxyEvents();
  const { groups } = useGroupEvents();
  const { vpnConfigs } = useVpnEvents();
  const reducedMotion = useReducedMotion();

  const activeProfiles =
    importMode === "auto-detect" ? detectedProfiles : scannedProfiles;
  const selectedProfiles = useMemo(
    () => activeProfiles.filter((p) => selectedPaths.has(p.path)),
    [activeProfiles, selectedPaths],
  );

  const registerProfileNames = useCallback((profiles: DetectedProfile[]) => {
    setProfileNames((prev) => {
      const next = { ...prev };
      for (const profile of profiles) {
        if (next[profile.path] === undefined) {
          next[profile.path] = profile.name;
        }
      }
      return next;
    });
  }, []);

  const loadDetectedProfiles = useCallback(async () => {
    setIsLoading(true);
    try {
      const profiles = await invoke<DetectedProfile[]>(
        "detect_existing_profiles",
      );
      setDetectedProfiles(profiles);
      registerProfileNames(profiles);
      if (profiles.length === 0) {
        setImportMode("manual");
      }
    } catch (error) {
      console.error("Failed to detect existing profiles:", error);
      toast.error(t("importProfile.detectFailed"));
    } finally {
      setIsLoading(false);
    }
  }, [t, registerProfileNames]);

  const cleanupExtractedDir = useCallback(async (dir: string | null) => {
    if (!dir) return;
    try {
      await invoke("cleanup_profile_import_scratch", { extractedDir: dir });
    } catch (error) {
      console.error("Failed to clean up extracted archive:", error);
    }
  }, []);

  const applyScanResult = useCallback(
    (profiles: DetectedProfile[]) => {
      setScannedProfiles(profiles);
      registerProfileNames(profiles);
      setSelectedPaths(new Set(profiles.map((p) => p.path)));
      if (profiles.length === 0) {
        toast.info(t("importProfile.noProfilesInLocation"));
      }
    },
    [registerProfileNames, t],
  );

  const scanPath = useCallback(
    async (path: string) => {
      setIsScanning(true);
      try {
        if (path.toLowerCase().endsWith(".zip")) {
          await cleanupExtractedDir(extractedDir);
          setExtractedDir(null);
          const scan = await invoke<ArchiveScanResult>("scan_profile_archive", {
            archivePath: path,
          });
          setExtractedDir(scan.extracted_dir);
          applyScanResult(scan.profiles);
        } else {
          const profiles = await invoke<DetectedProfile[]>(
            "scan_folder_for_profiles",
            { folderPath: path },
          );
          applyScanResult(profiles);
        }
      } catch (error) {
        console.error("Failed to scan for profiles:", error);
        toast.error(translateBackendError(t, error));
      } finally {
        setIsScanning(false);
      }
    },
    [applyScanResult, cleanupExtractedDir, extractedDir, t],
  );

  const handleBrowseFolder = async () => {
    try {
      const selected = await open({
        directory: true,
        multiple: false,
        title: t("importProfile.selectFolderTitle"),
      });
      if (selected && typeof selected === "string") {
        setManualPath(selected);
        await scanPath(selected);
      }
    } catch (error) {
      console.error("Failed to open folder dialog:", error);
      toast.error(t("importProfile.folderDialogFailed"));
    }
  };

  const handleBrowseArchive = async () => {
    try {
      const selected = await open({
        multiple: false,
        title: t("importProfile.selectArchiveTitle"),
        filters: [{ name: "ZIP", extensions: ["zip"] }],
      });
      if (selected && typeof selected === "string") {
        setManualPath(selected);
        await scanPath(selected);
      }
    } catch (error) {
      console.error("Failed to open archive dialog:", error);
      toast.error(t("importProfile.folderDialogFailed"));
    }
  };

  const togglePath = (path: string, checked: boolean) => {
    setSelectedPaths((prev) => {
      const next = new Set(prev);
      if (checked) {
        next.add(path);
      } else {
        next.delete(path);
      }
      return next;
    });
  };

  const toggleAll = (checked: boolean) => {
    setSelectedPaths(
      checked ? new Set(activeProfiles.map((p) => p.path)) : new Set(),
    );
  };

  const proxyIdForIndex = useCallback(
    (index: number): string | null => {
      if (proxyAssignment === "none") return null;
      if (proxyAssignment === "round-robin") {
        if (storedProxies.length === 0) return null;
        return storedProxies[index % storedProxies.length].id;
      }
      return proxyAssignment;
    },
    [proxyAssignment, storedProxies],
  );

  const handleCreateGroup = async () => {
    const name = newGroupName.trim();
    if (!name) return;
    try {
      const group = await invoke<{ id: string; name: string }>(
        "create_profile_group",
        { name },
      );
      setSelectedGroupId(group.id);
      setIsCreatingGroup(false);
      setNewGroupName("");
    } catch (error) {
      console.error("Failed to create group:", error);
      toast.error(translateBackendError(t, error));
    }
  };

  const handleImport = useCallback(
    async (allowRunning = false, retryPaths?: ReadonlySet<string>) => {
      if (selectedProfiles.length === 0) {
        toast.error(t("importProfile.selectAtLeastOne"));
        return;
      }
      if (
        selectedProfiles.some((p) => !(profileNames[p.path] ?? p.name).trim())
      ) {
        toast.error(t("importProfile.emptyNames"));
        return;
      }

      // Filter AFTER the map, so a retry keeps the proxy each profile was
      // originally assigned by the index-based round-robin.
      const items: ImportProfileItem[] = selectedProfiles
        .map((p, index) => ({
          source_path: p.path,
          browser_type: p.browser,
          new_profile_name: (profileNames[p.path] ?? p.name).trim(),
          proxy_id: proxyIdForIndex(index),
          vpn_id: vpnAssignment === "none" ? null : vpnAssignment,
          allow_running: allowRunning,
        }))
        .filter((item) => !retryPaths || retryPaths.has(item.source_path));

      if (items.length === 0) {
        return;
      }

      setCurrentStep("importing");
      setIsImporting(true);
      setProgress(null);
      // A retry covers only the failed subset, so the earlier results are still
      // the truth for everything else and must not be thrown away.
      const previous = retryPaths ? result : null;
      setResult(null);
      try {
        const batchResult = await invoke<ProfileImportBatchResult>(
          "import_browser_profiles",
          {
            items,
            groupId: selectedGroupId === "none" ? null : selectedGroupId,
            duplicateStrategy: duplicateStrategy,
            wayfernConfig,
          },
        );
        setResult(
          previous ? mergeImportResults(previous, batchResult) : batchResult,
        );
        toast.success(
          t("importProfile.resultsSummary", {
            imported: batchResult.imported_count,
            skipped: batchResult.skipped_count,
            failed: batchResult.failed_count,
          }),
        );
        if (batchResult.imported_count > 0 && !reducedMotion) {
          fireSprinkleConfetti();
        }
      } catch (error) {
        console.error("Failed to import profiles:", error);
        toast.error(translateBackendError(t, error));
        setCurrentStep("configure");
      } finally {
        setIsImporting(false);
      }
    },
    [
      selectedProfiles,
      profileNames,
      proxyIdForIndex,
      vpnAssignment,
      selectedGroupId,
      duplicateStrategy,
      wayfernConfig,
      reducedMotion,
      result,
      t,
    ],
  );

  // A source browser that is still running is the one failure the user can fix
  // without starting over, so offer the override right where it happened.
  const hasRunningBrowserFailure = useMemo(
    () =>
      (result?.results ?? []).some(
        (item) =>
          item.status === "failed" &&
          item.error?.includes("IMPORT_SOURCE_BROWSER_RUNNING"),
      ),
    [result],
  );

  const handleClose = () => {
    void cleanupExtractedDir(extractedDir);
    setCurrentStep("select");
    setImportMode(detectedProfiles.length > 0 ? "auto-detect" : "manual");
    setScannedProfiles([]);
    setManualPath("");
    setExtractedDir(null);
    setSelectedPaths(new Set());
    setProfileNames({});
    setSelectedGroupId("none");
    setIsCreatingGroup(false);
    setNewGroupName("");
    setDuplicateStrategy("rename");
    setProxyAssignment("none");
    setVpnAssignment("none");
    setWayfernConfig({});
    setShowFingerprint(false);
    setShowAdvanced(false);
    setProgress(null);
    setResult(null);
    onClose();
  };

  useEffect(() => {
    if (isOpen) {
      void loadDetectedProfiles();
    }
  }, [isOpen, loadDetectedProfiles]);

  useEffect(() => {
    if (!isOpen) return;
    const unlistenPromise = listen<ProfileImportProgress>(
      "profile-import-progress",
      (event) => {
        setProgress(event.payload);
      },
    );
    return () => {
      void unlistenPromise.then((unlisten) => unlisten());
    };
  }, [isOpen]);

  const allSelected =
    activeProfiles.length > 0 && selectedPaths.size >= activeProfiles.length;

  const renderProfileList = (profiles: DetectedProfile[]) => (
    <div className="space-y-2">
      <div className="flex items-center justify-between">
        <label
          htmlFor="import-select-all"
          className="flex cursor-pointer items-center gap-2 text-sm"
        >
          <Checkbox
            id="import-select-all"
            checked={allSelected}
            onCheckedChange={(checked) => toggleAll(checked === true)}
          />
          {t("importProfile.selectAll")}
        </label>
        <span className="text-xs text-muted-foreground">
          {t("importProfile.selectedCount", { count: selectedPaths.size })}
        </span>
      </div>
      <div className="max-h-64 space-y-1 overflow-y-auto rounded-lg border border-border p-2">
        {profiles.map((profile) => {
          const IconComponent = getBrowserIcon(profile.browser);
          const checkboxId = `import-profile-${encodeURIComponent(profile.path)}`;
          return (
            <label
              key={profile.path}
              htmlFor={checkboxId}
              className="flex cursor-pointer items-center gap-2 rounded-md p-2 hover:bg-muted"
            >
              <Checkbox
                id={checkboxId}
                checked={selectedPaths.has(profile.path)}
                onCheckedChange={(checked) =>
                  togglePath(profile.path, checked === true)
                }
              />
              {IconComponent && <IconComponent className="size-4 shrink-0" />}
              <div className="min-w-0 flex-1">
                <p className="truncate text-sm font-medium">{profile.name}</p>
                <p className="truncate text-xs text-muted-foreground">
                  {profile.path}
                </p>
              </div>
            </label>
          );
        })}
      </div>
    </div>
  );

  const progressPercent =
    progress && progress.total > 0
      ? Math.round((progress.completed / progress.total) * 100)
      : 0;

  return (
    <Dialog open={isOpen} onOpenChange={handleClose} subPage={subPage}>
      <DialogContent className="flex max-h-[80vh] max-w-[min(48rem,calc(100%-4rem))] flex-col">
        {!subPage && (
          <DialogHeader className="shrink-0">
            <DialogTitle>{t("importProfile.title")}</DialogTitle>
          </DialogHeader>
        )}

        <div className="min-h-0 flex-1 overflow-y-auto">
          <div
            className={cn("space-y-6", subPage && "mx-auto w-full max-w-3xl")}
          >
            {currentStep === "select" && (
              <AnimatedTabs
                value={importMode}
                onValueChange={(v) => {
                  setImportMode(v as ImportMode);
                  setSelectedPaths(new Set());
                }}
                className="flex flex-col gap-6"
              >
                <AnimatedTabsList>
                  <AnimatedTabsTrigger value="auto-detect" disabled={isLoading}>
                    {t("importProfile.autoDetect")}
                  </AnimatedTabsTrigger>
                  <AnimatedTabsTrigger value="manual" disabled={isLoading}>
                    {t("importProfile.manualImport")}
                  </AnimatedTabsTrigger>
                </AnimatedTabsList>

                <AnimatedTabsContent value="auto-detect">
                  <div className="space-y-4">
                    <h3 className="text-lg font-medium">
                      {t("importProfile.detectedProfilesTitle")}
                    </h3>

                    {isLoading ? (
                      <div className="py-8 text-center">
                        <p className="text-muted-foreground">
                          {t("importProfile.scanning")}
                        </p>
                      </div>
                    ) : detectedProfiles.length === 0 ? (
                      <div className="py-8 text-center">
                        <p className="text-muted-foreground">
                          {t("importProfile.noneFound")}
                        </p>
                        <p className="mt-2 text-sm text-muted-foreground">
                          {t("importProfile.noneFoundHint")}
                        </p>
                      </div>
                    ) : (
                      renderProfileList(detectedProfiles)
                    )}
                  </div>
                </AnimatedTabsContent>

                <AnimatedTabsContent value="manual">
                  <div className="space-y-4">
                    <h3 className="text-lg font-medium">
                      {t("importProfile.manualTitle")}
                    </h3>

                    <div>
                      <Label htmlFor="manual-profile-path" className="mb-2">
                        {t("importProfile.profileFolderPath")}
                      </Label>
                      <div className="flex gap-2">
                        <Input
                          id="manual-profile-path"
                          value={manualPath}
                          onChange={(e) => {
                            setManualPath(e.target.value);
                          }}
                          placeholder={t(
                            "importProfile.profileFolderPlaceholder",
                          )}
                        />
                        <Button
                          variant="outline"
                          size="icon"
                          onClick={() => void handleBrowseFolder()}
                          title={t("importProfile.browseFolderTitle")}
                        >
                          <FaFolder className="size-4" />
                        </Button>
                        <Button
                          variant="outline"
                          size="icon"
                          onClick={() => void handleBrowseArchive()}
                          title={t("importProfile.selectArchiveTitle")}
                        >
                          <FaFileArchive className="size-4" />
                        </Button>
                        <LoadingButton
                          variant="outline"
                          isLoading={isScanning}
                          disabled={!manualPath.trim()}
                          onClick={() => void scanPath(manualPath.trim())}
                        >
                          {t("importProfile.scanButton")}
                        </LoadingButton>
                      </div>
                      <p className="mt-2 text-xs text-muted-foreground">
                        {t("importProfile.manualHint")}
                      </p>
                      <p className="mt-2 text-xs break-all text-muted-foreground">
                        {t("importProfile.examplePaths")}
                        <br />
                        macOS: ~/Library/Application
                        Support/Google/Chrome/Default
                        <br />
                        Windows: %LOCALAPPDATA%\Google\Chrome\User Data\Default
                        <br />
                        Linux: ~/.config/google-chrome/Default
                      </p>
                    </div>

                    {scannedProfiles.length > 0 &&
                      renderProfileList(scannedProfiles)}
                  </div>
                </AnimatedTabsContent>
              </AnimatedTabs>
            )}

            {currentStep === "configure" && (
              <div className="space-y-4">
                <Alert>
                  <AlertDescription>
                    {t("importProfile.importedAs", {
                      browser: getBrowserDisplayName("wayfern"),
                    })}
                  </AlertDescription>
                </Alert>

                <div>
                  <Label className="mb-2">
                    {t("importProfile.profilesToImport")}
                  </Label>
                  <div className="max-h-48 space-y-2 overflow-y-auto rounded-lg border border-border p-2">
                    {selectedProfiles.map((profile) => (
                      <div
                        key={profile.path}
                        className="flex items-center gap-2"
                      >
                        <span
                          className="min-w-0 flex-1 truncate text-xs text-muted-foreground"
                          title={profile.path}
                        >
                          {profile.name}
                        </span>
                        <Input
                          className="flex-1"
                          aria-label={t("importProfile.newProfileName")}
                          value={profileNames[profile.path] ?? profile.name}
                          onChange={(e) => {
                            setProfileNames((prev) => ({
                              ...prev,
                              [profile.path]: e.target.value,
                            }));
                          }}
                          placeholder={t(
                            "importProfile.newProfileNamePlaceholder",
                          )}
                        />
                      </div>
                    ))}
                  </div>
                </div>

                <div>
                  <Label className="mb-2">
                    {t("importProfile.proxyOptional")}
                  </Label>
                  <Select
                    value={proxyAssignment}
                    onValueChange={setProxyAssignment}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder={t("importProfile.noProxy")} />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="none">
                        {t("importProfile.noProxy")}
                      </SelectItem>
                      {storedProxies.length > 0 && (
                        <SelectItem value="round-robin">
                          {t("importProfile.proxyRoundRobin")}
                        </SelectItem>
                      )}
                      {storedProxies.map((proxy) => (
                        <SelectItem key={proxy.id} value={proxy.id}>
                          {proxy.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>

                {vpnConfigs.length > 0 && (
                  <div>
                    <Label className="mb-2">
                      {t("importProfile.vpnOptional")}
                    </Label>
                    <Select
                      value={vpnAssignment}
                      onValueChange={setVpnAssignment}
                    >
                      <SelectTrigger>
                        <SelectValue placeholder={t("importProfile.noVpn")} />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="none">
                          {t("importProfile.noVpn")}
                        </SelectItem>
                        {vpnConfigs.map((vpn) => (
                          <SelectItem key={vpn.id} value={vpn.id}>
                            {vpn.name}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                )}

                <div>
                  <button
                    type="button"
                    className="flex cursor-pointer items-center gap-1 text-sm font-medium text-muted-foreground hover:text-foreground"
                    onClick={() => setShowAdvanced((v) => !v)}
                    aria-expanded={showAdvanced}
                  >
                    <AnimatedDisclosureChevron open={showAdvanced}>
                      <LuChevronRight className="size-3.5" />
                    </AnimatedDisclosureChevron>
                    {t("importProfile.advancedOptions")}
                  </button>
                  <AnimatedDisclosureContent
                    open={showAdvanced}
                    className="mt-3 space-y-4"
                  >
                    <div>
                      <Label className="mb-2">
                        {t("importProfile.groupOptional")}
                      </Label>
                      {isCreatingGroup ? (
                        <div className="flex gap-2">
                          <Input
                            value={newGroupName}
                            onChange={(e) => setNewGroupName(e.target.value)}
                            placeholder={t(
                              "importProfile.newGroupNamePlaceholder",
                            )}
                          />
                          <Button
                            variant="outline"
                            disabled={!newGroupName.trim()}
                            onClick={() => void handleCreateGroup()}
                          >
                            {t("common.buttons.create")}
                          </Button>
                          <Button
                            variant="ghost"
                            onClick={() => {
                              setIsCreatingGroup(false);
                              setNewGroupName("");
                            }}
                          >
                            {t("common.buttons.cancel")}
                          </Button>
                        </div>
                      ) : (
                        <Select
                          value={selectedGroupId}
                          onValueChange={(value) => {
                            if (value === "create-new") {
                              setIsCreatingGroup(true);
                            } else {
                              setSelectedGroupId(value);
                            }
                          }}
                        >
                          <SelectTrigger>
                            <SelectValue
                              placeholder={t("importProfile.noGroup")}
                            />
                          </SelectTrigger>
                          <SelectContent>
                            <SelectItem value="none">
                              {t("importProfile.noGroup")}
                            </SelectItem>
                            {groups.map((group) => (
                              <SelectItem key={group.id} value={group.id}>
                                {group.name}
                              </SelectItem>
                            ))}
                            <SelectItem value="create-new">
                              {t("importProfile.createNewGroup")}
                            </SelectItem>
                          </SelectContent>
                        </Select>
                      )}
                    </div>

                    <div>
                      <Label className="mb-2">
                        {t("importProfile.duplicateStrategyLabel")}
                      </Label>
                      <Select
                        value={duplicateStrategy}
                        onValueChange={(value) => {
                          setDuplicateStrategy(value as DuplicateStrategy);
                        }}
                      >
                        <SelectTrigger>
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="rename">
                            {t("importProfile.duplicateRename")}
                          </SelectItem>
                          <SelectItem value="skip">
                            {t("importProfile.duplicateSkip")}
                          </SelectItem>
                        </SelectContent>
                      </Select>
                    </div>
                  </AnimatedDisclosureContent>
                </div>

                <div>
                  <button
                    type="button"
                    className="flex cursor-pointer items-center gap-1 text-sm font-medium text-muted-foreground hover:text-foreground"
                    onClick={() => setShowFingerprint((v) => !v)}
                    aria-expanded={showFingerprint}
                  >
                    <AnimatedDisclosureChevron open={showFingerprint}>
                      <LuChevronRight className="size-3.5" />
                    </AnimatedDisclosureChevron>
                    {t("importProfile.configureFingerprint")}
                  </button>
                  <AnimatedDisclosureContent
                    open={showFingerprint}
                    className="mt-3"
                  >
                    <WayfernConfigForm
                      config={wayfernConfig}
                      onConfigChange={(key, value) => {
                        setWayfernConfig((prev) => ({ ...prev, [key]: value }));
                      }}
                      isCreating={true}
                      crossOsUnlocked={crossOsUnlocked}
                      limitedMode={!crossOsUnlocked}
                    />
                  </AnimatedDisclosureContent>
                </div>
              </div>
            )}

            {currentStep === "importing" && (
              <div className="space-y-4">
                {isImporting && (
                  <div className="space-y-2">
                    <h3 className="text-lg font-medium">
                      {t("importProfile.importingTitle")}
                    </h3>
                    <Progress value={progressPercent} />
                    {progress && (
                      <p className="text-sm text-muted-foreground">
                        {t("importProfile.importProgress", {
                          completed: progress.completed,
                          total: progress.total,
                        })}
                        {progress.status === "importing" && (
                          <> — {progress.name}</>
                        )}
                      </p>
                    )}
                  </div>
                )}

                {result && (
                  <div className="space-y-2">
                    <h3 className="text-lg font-medium">
                      {t("importProfile.resultsSummary", {
                        imported: result.imported_count,
                        skipped: result.skipped_count,
                        failed: result.failed_count,
                      })}
                    </h3>
                    <div className="max-h-64 space-y-1 overflow-y-auto rounded-lg border border-border p-2">
                      {result.results.map((item) => (
                        <div key={item.source_path} className="p-1 text-sm">
                          <div className="flex items-center gap-2">
                            <span
                              className={cn(
                                "shrink-0 text-xs font-medium",
                                item.status === "imported" &&
                                  "text-success-text",
                                item.status === "skipped" &&
                                  "text-muted-foreground",
                                item.status === "failed" &&
                                  "text-destructive-text",
                              )}
                            >
                              {item.status === "imported" &&
                                t("importProfile.statusImported")}
                              {item.status === "skipped" &&
                                t("importProfile.statusSkipped")}
                              {item.status === "failed" &&
                                t("importProfile.statusFailed")}
                            </span>
                            <span className="min-w-0 flex-1 truncate">
                              {item.name || item.source_path}
                            </span>
                            {item.error && (
                              <span className="min-w-0 flex-1 truncate text-xs text-destructive-text">
                                {translateBackendError(
                                  t,
                                  new Error(item.error),
                                )}
                              </span>
                            )}
                          </div>
                          {item.report && (
                            <ImportReportSummary report={item.report} />
                          )}
                        </div>
                      ))}
                    </div>

                    {hasRunningBrowserFailure && (
                      <Alert>
                        <AlertDescription className="space-y-2">
                          <p>{t("importProfile.closeSourceBrowserHint")}</p>
                          <Button
                            variant="outline"
                            size="sm"
                            onClick={() => {
                              void handleImport(
                                true,
                                new Set(
                                  result.results
                                    .filter(
                                      (item) =>
                                        item.status === "failed" &&
                                        item.error?.includes(
                                          "IMPORT_SOURCE_BROWSER_RUNNING",
                                        ),
                                    )
                                    .map((item) => item.source_path),
                                ),
                              );
                            }}
                          >
                            {t("importProfile.importAnyway")}
                          </Button>
                        </AlertDescription>
                      </Alert>
                    )}
                  </div>
                )}
              </div>
            )}
          </div>
        </div>

        <div
          className={cn(
            "flex shrink-0 items-center justify-end gap-2",
            subPage
              ? "mx-auto w-full max-w-3xl border-t border-border pt-2"
              : undefined,
          )}
        >
          {currentStep === "select" && (
            <>
              {!subPage && (
                <RippleButton variant="outline" onClick={handleClose}>
                  {t("common.buttons.cancel")}
                </RippleButton>
              )}
              <RippleButton
                disabled={selectedPaths.size === 0}
                onClick={() => {
                  setCurrentStep("configure");
                }}
              >
                {t("importProfile.nextButton")}
              </RippleButton>
            </>
          )}
          {currentStep === "configure" && (
            <>
              <RippleButton
                variant="outline"
                onClick={() => {
                  setCurrentStep("select");
                }}
              >
                {t("common.buttons.back")}
              </RippleButton>
              <LoadingButton
                isLoading={isImporting}
                onClick={() => {
                  void handleImport();
                }}
              >
                {t("importProfile.importButtonCount", {
                  count: selectedProfiles.length,
                })}
              </LoadingButton>
            </>
          )}
          {currentStep === "importing" && (
            <RippleButton disabled={isImporting} onClick={handleClose}>
              {t("common.buttons.close")}
            </RippleButton>
          )}
        </div>
      </DialogContent>
    </Dialog>
  );
}
