(() => {
  const $ = (id) => document.getElementById(id);
  const CONFIRM_TOKEN = "MIGRATE_LEGACY_WORKSPACE";
  const DELETE_COPY_TOKEN = "DELETE_MIGRATED_ADVANCED_COPY";
  const CLAIM_STORAGE_PREFIX = "liverylab.legacyMigration.advancedClaimed.";
  const DEFAULT_WORKFLOW_HINT = "Moving from LiveryLab 1.0.2 or 1.0.3? Inspect your existing Advanced workspace before choosing a workflow.";
  let busy = false;
  let lastInspection = null;
  let migrationCompleted = false;
  let migrationRunning = false;
  const migrationTarget = "official";
  let pendingOfficialMigration = null;
  let applyAvailable = false;
  let selectedWorkflow = "";
  let officialSetupReady = false;
  let offeredMigrationId = "";

  const featureLabels = {
    driverProfiles: "Driver profiles",
    driverProjects: "Driver projects",
    tyreBrands: "Tyre brands",
    customGrids: "Custom grids",
    numberplates: "Numberplates",
    layerStudioLibrary: "Layer Studio library",
    layerStudioProjects: "Layer Studio projects",
    externalEditorFiles: "External editor files",
  };

  function officialMigrationSupported() {
    const api = window.pywebview?.api;
    return typeof api?.run_pending_legacy_official_migration === "function"
      && typeof api?.cleanup_legacy_advanced_copy === "function";
  }

  function refreshOfficialMigrationCapability() {
    const trigger = $("openLegacyMigration");
    if (!trigger) return;
    trigger.disabled = !officialMigrationSupported();
    trigger.title = trigger.disabled ? "A release sync with the migration runtime is required." : "";
  }

  function migrationId(data = pendingOfficialMigration) {
    return String(data?.migrationId || "").trim();
  }

  function advancedClaimed(data = pendingOfficialMigration) {
    if (String(data?.cleanup?.state || "") === "kept") return true;
    const id = migrationId(data);
    if (!id) return false;
    try {
      return window.localStorage?.getItem(`${CLAIM_STORAGE_PREFIX}${id}`) === "true";
    } catch (_error) {
      return false;
    }
  }

  function rememberAdvancedClaim(data = pendingOfficialMigration) {
    const id = migrationId(data);
    if (!id) return;
    try {
      window.localStorage?.setItem(`${CLAIM_STORAGE_PREFIX}${id}`, "true");
    } catch (_error) {
      // The backend manifest remains the durable source when web storage is unavailable.
    }
  }

  function queueCompleted(data = pendingOfficialMigration) {
    return String(data?.queue?.state || "") === "completed";
  }

  function renderWorkflowMigrationStatus() {
    const status = $("legacyMigrationWorkflowStatus");
    const hint = $("legacyMigrationWorkflowHint");
    const trigger = $("openLegacyMigration");
    if (!status || !hint || !trigger) return;
    if (!pendingOfficialMigration) {
      status.hidden = true;
      hint.hidden = false;
      hint.textContent = DEFAULT_WORKFLOW_HINT;
      trigger.textContent = "Migrate from an older version";
      return;
    }
    if (pendingOfficialMigration.dismissed === true) {
      status.hidden = true;
      hint.hidden = false;
      hint.textContent = "An existing migration is still available, but its automatic reminder is dismissed.";
      trigger.textContent = "Review dismissed migration";
      return;
    }
    const summary = pendingOfficialMigration.queue?.summary || {};
    const claimed = advancedClaimed();
    const failed = Number(summary.failed || 0) + Number(summary.blocked || 0);
    status.hidden = false;
    hint.hidden = true;
    trigger.textContent = "Review pending migration";
    if (queueCompleted() && !claimed) {
      status.textContent = "Official conversion complete. Choose whether to keep or remove the copied Advanced workspace.";
    } else if (queueCompleted()) {
      status.textContent = "Official conversion complete. The migrated Advanced workspace is kept.";
    } else if (failed) {
      status.textContent = `Official conversion finished with warnings: ${summary.successful || 0} successful, ${failed} failed. Failed liveries can be retried.`;
    } else if (claimed) {
      status.textContent = `Migrated Advanced workspace kept. Official conversion remains available for all ${summary.total || 0} liveries.`;
    } else {
      status.textContent = `Workspace migrated. Choose Official to convert all ${summary.total || 0} liveries, or Advanced to keep the migrated workspace.`;
    }
  }

  function formatBytes(value) {
    const bytes = Number(value || 0);
    if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
    const units = ["B", "KB", "MB", "GB", "TB"];
    const index = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);
    const amount = bytes / (1024 ** index);
    return `${amount >= 10 || index === 0 ? amount.toFixed(0) : amount.toFixed(1)} ${units[index]}`;
  }

  function setText(id, value) {
    const element = $(id);
    if (element) element.textContent = String(value ?? "");
  }

  function setHidden(id, hidden) {
    const element = $(id);
    if (element) element.toggleAttribute("hidden", Boolean(hidden));
  }

  function formatPercent(value) {
    const percent = Math.max(0, Math.min(100, Number(value) || 0));
    return Number.isInteger(percent) ? `${percent}%` : `${percent.toFixed(1)}%`;
  }

  function renderList(id, rows, emptyText = "None") {
    const list = $(id);
    if (!list) return;
    list.replaceChildren();
    const values = Array.isArray(rows) && rows.length ? rows : [emptyText];
    values.forEach((value) => {
      const item = document.createElement("li");
      item.textContent = String(value || "-");
      list.append(item);
    });
  }

  function liveryStatusLabel(status) {
    return {
      ready: "Ready",
      ready_with_feature_loss: "Ready with feature loss",
      incomplete: "Incomplete",
      pending: "Pending",
      running: "Converting",
      converted: "Official created",
      already_installed: "Already installed",
      blocked: "Blocked",
      failed: "Failed",
    }[String(status || "")] || String(status || "Pending");
  }

  function renderLiveryRows(containerId, rows = [], queueMode = false) {
    const container = $(containerId);
    if (!container) return;
    container.replaceChildren();
    const values = Array.isArray(rows) ? rows : [];
    values.forEach((row) => {
      const status = String(
        queueMode ? (row.status || "pending") : (row.officialConversionStatus || "ready"),
      );
      const item = document.createElement("div");
      item.className = "legacy-migration-livery-row";
      item.dataset.status = status;
      const title = document.createElement("strong");
      title.textContent = String(row.displayName || row.display_name || row.skinId || row.skin_id || row.sourceKey || "Livery");
      const badge = document.createElement("span");
      badge.textContent = liveryStatusLabel(status);
      const details = document.createElement("small");
      const losses = Array.isArray(row.advancedOnlyFeatures) ? row.advancedOnlyFeatures : [];
      const messages = [];
      if (row.carModel || row.car_model) messages.push(`Car: ${row.carModel || row.car_model}`);
      if (losses.length) messages.push(`Not supported in Official: ${losses.join(", ")}`);
      if (row.lastError) messages.push(String(row.lastError));
      details.textContent = messages.join(" | ") || "No Advanced-only dependencies detected.";
      item.append(title, badge, details);
      container.append(item);
    });
    if (!values.length) {
      const empty = document.createElement("div");
      empty.className = "legacy-migration-livery-row";
      empty.textContent = "No liveries detected.";
      container.append(empty);
    }
  }

  function setApplyAvailable(available) {
    applyAvailable = Boolean(available);
    const apply = $("legacyMigrationApply");
    if (!apply) return;
    apply.hidden = !available;
    apply.disabled = busy || !available;
  }

  function allActionButtons() {
    return [
      "legacyMigrationApply",
      "legacyMigrationRestart",
      "legacyOfficialMigrationResume",
      "legacyOfficialMigrationOpenSetup",
      "legacyOfficialMigrationDeleteCopy",
      "legacyOfficialMigrationKeepCopy",
      "legacyOfficialMigrationDecideLater",
      "legacyOfficialMigrationDismiss",
      "legacyMigrationOpenLongPathsBat",
      "legacyMigrationGoogleLongPaths",
      "legacyMigrationRecheckLongPaths",
    ].map($).filter(Boolean);
  }

  function setBusy(nextBusy, message = "", pickerLabel = "Inspecting...") {
    busy = Boolean(nextBusy);
    const picker = $("pickLegacyMigrationSource");
    const close = $("legacyMigrationClose");
    const closeX = $("legacyMigrationCloseX");
    if (picker) {
      picker.disabled = busy || migrationCompleted || Boolean(pendingOfficialMigration);
      picker.textContent = busy ? pickerLabel : "Choose Folder";
    }
    allActionButtons().forEach((button) => { button.disabled = busy; });
    if ($("legacyMigrationApply")) $("legacyMigrationApply").disabled = busy || !applyAvailable;
    if (close) close.disabled = busy;
    if (closeX) closeX.disabled = busy;
    if (message) setText("legacyMigrationStatus", message);
  }

  function openModal() {
    const modal = $("legacyMigrationModal");
    if (!modal) return;
    if (pendingOfficialMigration) renderOfficialContinuation(pendingOfficialMigration);
    modal.hidden = false;
    if (pendingOfficialMigration) {
      $("legacyOfficialMigrationResume")?.focus();
    } else {
      (migrationCompleted ? $("legacyMigrationRestart") : $("pickLegacyMigrationSource"))?.focus();
    }
  }

  function closeModal() {
    if (busy) return;
    const modal = $("legacyMigrationModal");
    if (modal) modal.hidden = true;
    $("openLegacyMigration")?.focus();
  }

  function resetMigrationProgress() {
    migrationRunning = false;
    const modal = $("legacyMigrationModal");
    if (modal) delete modal.dataset.migrationRunning;
    setHidden("legacyMigrationProgress", true);
    setHidden("legacyMigrationBusy", true);
    if ($("legacyMigrationClose")) $("legacyMigrationClose").hidden = false;
    if ($("legacyMigrationProgressFill")) $("legacyMigrationProgressFill").style.width = "0%";
    setText("legacyMigrationProgressPercent", "0%");
    setText("legacyMigrationProgressPhase", "Preparing migration...");
    setText("legacyMigrationProgressPath", "Waiting for workspace data...");
    setText("legacyMigrationProgressFiles", "Files: 0 / 0");
    setText("legacyMigrationProgressData", "Data copied: 0 B / 0 B");
    setText("legacyMigrationProgressStage", "Stage: Preparing");
  }

  function renderMigrationProgress(payload = {}) {
    const percent = Math.max(0, Math.min(100, Number(payload.percent) || 0));
    const current = Math.max(0, Number(payload.filesWritten ?? payload.current) || 0);
    const total = Math.max(0, Number(payload.totalFiles ?? payload.total) || 0);
    const processed = Math.max(0, Number(payload.bytesProcessed) || 0);
    const totalBytes = Math.max(0, Number(payload.totalBytes) || 0);
    const stage = String(payload.stageLabel || payload.phase || "Migrating workspace");
    const message = String(payload.message || stage);
    const path = String(payload.path || payload.label || "");
    if ($("legacyMigrationProgressFill")) $("legacyMigrationProgressFill").style.width = `${percent}%`;
    setText("legacyMigrationProgressPercent", formatPercent(percent));
    setText("legacyMigrationProgressPhase", stage);
    setText("legacyMigrationProgressPath", path || message || "Preparing workspace...");
    setText("legacyMigrationProgressFiles", `Files: ${current} / ${total || "-"}`);
    setText("legacyMigrationProgressData", totalBytes ? `Data copied: ${formatBytes(processed)} / ${formatBytes(totalBytes)}` : "Automatic verified processing");
    setText("legacyMigrationProgressStage", `Stage: ${message}`);
    setText("legacyMigrationStatus", `${message} (${formatPercent(percent)})`);
  }

  function startMigrationProgress(plan = {}, officialContinuation = false) {
    migrationRunning = true;
    const modal = $("legacyMigrationModal");
    if (modal) {
      modal.dataset.type = "info";
      modal.dataset.migrationRunning = "true";
      modal.hidden = false;
    }
    setHidden("legacyMigrationSummary", true);
    setHidden("legacyOfficialMigrationContinuation", !officialContinuation);
    setHidden("legacyMigrationProgress", false);
    setHidden("legacyMigrationBusy", false);
    setHidden("legacyMigrationApply", true);
    if ($("legacyMigrationClose")) $("legacyMigrationClose").hidden = true;
    setText("legacyMigrationSubtitle", officialContinuation ? "Converting migrated liveries to Official" : "Migrating the local Advanced workspace");
    setText("legacyMigrationIntro", officialContinuation
      ? "Every migrated livery is processed automatically. Advanced-only dependencies are reported in the result."
      : "Do not close LiveryLab while the workspace is copied, verified and committed.");
    setBusy(true, officialContinuation ? "Preparing automatic Official conversion..." : "Preparing the verified migration...", officialContinuation ? "Converting..." : "Migrating...");
    const rootInventory = Object.values(plan.inventory?.roots || {});
    renderMigrationProgress({
      phase: "staging",
      stageLabel: officialContinuation ? "Preparing Official conversion" : "Preparing migration",
      message: officialContinuation ? "Preparing automatic Official conversion..." : "Preparing the verified migration...",
      percent: 0,
      current: 0,
      totalFiles: officialContinuation ? Number(plan.queue?.summary?.total || 0) : rootInventory.reduce((sum, row) => sum + (Number(row?.fileCount) || 0), 0),
      bytesProcessed: 0,
      totalBytes: officialContinuation ? 0 : rootInventory.reduce((sum, row) => sum + (Number(row?.bytes) || 0), 0),
    });
  }

  function finishMigrationProgress({ keepVisible = false } = {}) {
    migrationRunning = false;
    const modal = $("legacyMigrationModal");
    if (modal) delete modal.dataset.migrationRunning;
    setHidden("legacyMigrationBusy", true);
    if (!keepVisible) setHidden("legacyMigrationProgress", true);
    if ($("legacyMigrationClose")) $("legacyMigrationClose").hidden = false;
    setBusy(false);
  }

  function resetCompletionState() {
    migrationCompleted = false;
    resetMigrationProgress();
    const modal = $("legacyMigrationModal");
    if (modal) delete modal.dataset.migrationComplete;
    setHidden("legacyMigrationCompletion", true);
    setHidden("legacyOfficialMigrationContinuation", true);
    setHidden("legacyMigrationPathRow", false);
    ["legacyMigrationRestart", "legacyOfficialMigrationResume", "legacyOfficialMigrationOpenSetup", "legacyOfficialMigrationDeleteCopy", "legacyOfficialMigrationKeepCopy", "legacyOfficialMigrationDecideLater", "legacyOfficialMigrationDismiss"].forEach((id) => setHidden(id, true));
    setText("legacyMigrationTitle", "Migrate from LiveryLab 1.0.2 or 1.0.3");
    setText("legacyMigrationSubtitle", "Inspect and migrate the local Advanced workspace");
    setText("legacyMigrationIntro", "Choose the old portable LiveryLab folder. LiveryLab will inspect it first without changing any files.");
    setText("legacyMigrationApply", "Migrate Complete Workspace");
    const close = $("legacyMigrationClose");
    if (close) {
      close.textContent = "Close";
      close.classList.remove("primary");
    }
  }

  function renderLongPaths(longPaths = {}) {
    if (!Object.keys(longPaths || {}).length && !officialMigrationSupported()) {
      setHidden("legacyMigrationLongPaths", true);
      return true;
    }
    const ready = longPaths?.ready === true;
    setHidden("legacyMigrationLongPaths", ready);
    if (ready) return true;
    const registry = longPaths?.registry || {};
    const runtime = longPaths?.runtime || {};
    setText("legacyMigrationLongPathsMessage", longPaths?.message || "Enable Windows long paths before migration.");
    setText(
      "legacyMigrationLongPathsDetails",
      [
        `Registry: ${registry.enabled ? "enabled" : (registry.available === false ? "could not verify" : "disabled")}`,
        `Runtime test: ${runtime.available ? "passed" : "failed"}`,
        longPaths.longestTargetPathLength ? `Longest predicted target path: ${longPaths.longestTargetPathLength} characters` : "",
      ].filter(Boolean).join(" | "),
    );
    return false;
  }

  function renderInspection(data = {}) {
    resetCompletionState();
    pendingOfficialMigration = null;
    const modal = $("legacyMigrationModal");
    const source = data.source || {};
    const liveries = data.liveries || {};
    const storage = data.storage || {};
    const features = data.features || {};
    const warnings = Array.isArray(data.warnings) ? data.warnings : [];
    const blockers = Array.isArray(data.blockers) ? data.blockers : [];

    setHidden("legacyMigrationSummary", false);
    setText("legacyMigrationDetectedVersion", `LiveryLab ${source.version || "unknown"}`);
    setText("legacyMigrationDetectedRoot", source.root || "-");
    setText("legacyMigrationTotalLiveries", liveries.total || 0);
    setText("legacyMigrationEditableLiveries", liveries.editable || 0);
    setText("legacyMigrationReadOnlyLiveries", liveries.readOnly || 0);
    setText("legacyMigrationIncompleteLiveries", liveries.incomplete || 0);
    setText("legacyMigrationWorkspaceFiles", storage.totalFiles || 0);
    setText("legacyMigrationWorkspaceSize", formatBytes(storage.totalBytes));
    const featureRows = Object.entries(featureLabels)
      .filter(([key]) => features[key]?.present)
      .map(([key, label]) => `${label}: ${Number(features[key]?.count ?? features[key]?.fileCount ?? 0)}`);
    renderList("legacyMigrationFeatures", featureRows, "No additional Advanced data detected.");
    renderList("legacyMigrationWarnings", warnings);
    renderList("legacyMigrationBlockers", blockers);
    setHidden("legacyMigrationWarningsWrap", warnings.length === 0);
    setHidden("legacyMigrationBlockersWrap", blockers.length === 0);
    lastInspection = data;
    const longPathsReady = renderLongPaths(data.longPaths || {});
    const ready = data.ready === true && blockers.length === 0 && longPathsReady;
    setApplyAvailable(ready);
    if (modal) modal.dataset.type = ready ? (warnings.length ? "warning" : "success") : "error";
    setText(
      "legacyMigrationStatus",
      ready
        ? `LiveryLab ${source.version || "1.0.2 / 1.0.3"} was detected. The complete local workspace is ready to migrate.`
        : (longPathsReady ? "The selected installation needs attention before it can be migrated." : "Migration is blocked until Windows Long Path Support is ready."),
    );
  }

  function renderError(message, details = "") {
    if ($("legacyMigrationModal")) $("legacyMigrationModal").dataset.type = "error";
    setApplyAvailable(false);
    setText("legacyMigrationStatus", [message, details].filter(Boolean).join("\n\n") || "The old LiveryLab folder could not be inspected.");
  }

  function renderPlanBlocked(plan = {}) {
    const blockers = Array.isArray(plan.blockers) ? plan.blockers : [];
    renderList("legacyMigrationWarnings", plan.warnings || []);
    renderList("legacyMigrationBlockers", blockers, "Migration plan could not be prepared.");
    setHidden("legacyMigrationWarningsWrap", !(plan.warnings || []).length);
    setHidden("legacyMigrationBlockersWrap", false);
    renderLongPaths(plan.longPaths || {});
    setApplyAvailable(false);
    if ($("legacyMigrationModal")) $("legacyMigrationModal").dataset.type = "error";
    setText("legacyMigrationStatus", "The workspace migration is blocked. No files were changed.");
  }

  async function inspectPath(path) {
    const sourcePath = String(path || "").trim();
    if (!sourcePath) return;
    if ($("legacyMigrationSourcePath")) $("legacyMigrationSourcePath").value = sourcePath;
    if (typeof window.pywebview?.api?.inspect_legacy_install !== "function") {
      renderError("Legacy migration inspection is unavailable in this runtime copy. A release-folder sync is required.");
      return;
    }
    setBusy(true, "Inspecting the old LiveryLab workspace...");
    try {
      const result = await window.pywebview.api.inspect_legacy_install({ path: sourcePath });
      if (!result?.ok) renderError(result?.message, result?.errorDetails);
      else renderInspection(result.data || {});
    } catch (error) {
      renderError(error?.message || String(error));
    } finally {
      setBusy(false);
    }
  }

  async function chooseSource() {
    if (busy || migrationCompleted || pendingOfficialMigration) return;
    const api = window.pywebview?.api;
    if (typeof api?.choose_path !== "function") return renderError("Folder selection is unavailable in this runtime copy.");
    const result = await api.choose_path("folder", ["All files (*.*)"], "", $("legacyMigrationSourcePath")?.value.trim() || "");
    if (!result?.ok) return renderError(result?.message || "The folder dialog could not be opened.");
    const path = String(result.data?.path || "").trim();
    if (path) await inspectPath(path);
  }

  function migrationConfirmationDetails(plan = {}) {
    const liveries = plan.liveries || {};
    return [
      `Source: ${plan.source?.root || "-"}`,
      `Target: ${plan.target?.root || "-"}`,
      `Workspace: ${plan.inventory?.totalFiles || 0} files / ${formatBytes(plan.inventory?.totalBytes)}`,
      `Liveries: ${liveries.total || 0} total, ${liveries.editable || 0} editable, ${liveries.readOnly || 0} read-only`,
      "Destination: Complete local workspace; choose Official or Advanced after restart",
      "",
      "All migrated Advanced liveries will start inactive. Read-only liveries remain read-only.",
      "Official conversion is offered only after the Official workflow setup is complete.",
      "Advanced-only dependencies remain available in the copied Advanced workspace.",
      "The old LiveryLab folder remains unchanged.",
      "AC EVO game files, content.kspkg and SavedCars are not changed in this step.",
    ].join("\n");
  }

  function renderCompletion(result = {}) {
    finishMigrationProgress();
    migrationCompleted = true;
    lastInspection = null;
    const modal = $("legacyMigrationModal");
    if (modal) {
      modal.dataset.type = "success";
      modal.dataset.migrationComplete = "true";
      modal.hidden = false;
    }
    setApplyAvailable(false);
    setHidden("legacyMigrationCompletion", false);
    setText("legacyMigrationSubtitle", "Local workspace migration complete");
    setText("legacyMigrationIntro", "The migration completed without modifying the old installation or AC EVO game files.");
    setText("legacyMigrationStatus", `${result.liveryCount || 0} Advanced liveries migrated. All are inactive; ${result.readOnlyCount || 0} remain read-only.`);
    const completion = $("legacyMigrationCompletion");
    if (completion) {
      const strong = completion.querySelector("strong");
      const span = completion.querySelector("span");
      if (strong) strong.textContent = "Restart required";
      if (span) span.textContent = "Restart LiveryLab, then choose Official or Advanced. LiveryLab remembers that the final migration step is still available.";
    }
    setHidden("legacyMigrationRestart", false);
    setText("legacyMigrationRestart", "Restart and Choose Workflow");
    setBusy(false);
    $("legacyMigrationRestart")?.focus();
  }

  function renderMigrationFailure(result = {}) {
    finishMigrationProgress({ keepVisible: true });
    if ($("legacyMigrationModal")) $("legacyMigrationModal").dataset.type = "error";
    setText("legacyMigrationSubtitle", "Workspace migration failed");
    setText("legacyMigrationIntro", "The migration stopped and LiveryLab attempted to restore the previous target state.");
    setText("legacyMigrationProgressPhase", "Migration failed");
    setText("legacyMigrationProgressStage", "Stage: Rolled back after an error");
    renderError(result?.message || "The workspace migration failed.", result?.errorDetails);
  }

  async function migrateWorkspace() {
    if (busy || !lastInspection) return;
    const sourcePath = String(lastInspection.source?.root || $("legacyMigrationSourcePath")?.value || "").trim();
    const api = window.pywebview?.api;
    if (!sourcePath || typeof api?.create_legacy_workspace_migration_plan !== "function" || typeof api?.apply_legacy_workspace_migration !== "function") {
      return renderError("Legacy workspace migration is unavailable in this runtime copy. A release-folder sync is required.");
    }
    setBusy(true, "Preparing the migration plan...", "Preparing...");
    let planResult;
    try {
      planResult = await api.create_legacy_workspace_migration_plan({ sourcePath, migrationTarget });
    } catch (error) {
      setBusy(false);
      return renderError(error?.message || String(error));
    }
    setBusy(false);
    if (!planResult?.ok) return renderError(planResult?.message, planResult?.errorDetails);
    const plan = planResult.data || {};
    if (plan.ready !== true) return renderPlanBlocked(plan);
    if (typeof window.showConfirmModal !== "function") return renderError("The migration confirmation dialog is unavailable.");
    const legacyModal = $("legacyMigrationModal");
    if (legacyModal) legacyModal.hidden = true;
    const confirmed = await window.showConfirmModal({
      type: "warning",
      title: "Migrate the complete legacy workspace?",
      subtitle: `LiveryLab ${plan.source?.version || "1.0.2 / 1.0.3"} to current portable installation`,
      message: "LiveryLab will copy the local workspace through a verified staging area and commit it only after validation.",
      details: migrationConfirmationDetails(plan),
      confirmLabel: "Migrate Workspace",
      cancelLabel: "Cancel",
    });
    if (legacyModal) legacyModal.hidden = false;
    if (!confirmed) return;
    startMigrationProgress(plan);
    let answer;
    try {
      answer = await api.apply_legacy_workspace_migration({ planId: plan.planId, confirmToken: CONFIRM_TOKEN });
    } catch (error) {
      answer = { ok: false, message: error?.message || String(error) };
    }
    if (!answer?.ok) return renderMigrationFailure(answer || {});
    renderCompletion(answer.data || {});
  }

  function renderOfficialContinuation(data = {}) {
    pendingOfficialMigration = data;
    migrationCompleted = false;
    lastInspection = null;
    resetMigrationProgress();
    setHidden("legacyMigrationSummary", true);
    setHidden("legacyMigrationLongPaths", true);
    setHidden("legacyMigrationCompletion", true);
    setHidden("legacyMigrationPathRow", true);
    setHidden("legacyOfficialMigrationContinuation", false);
    setHidden("legacyMigrationApply", true);
    const queue = data.queue || {};
    const summary = queue.summary || {};
    const claimed = advancedClaimed(data);
    const completed = String(queue.state || "") === "completed";
    const failedCount = Number(summary.failed || 0) + Number(summary.blocked || 0);
    const pendingCount = Number(summary.pending || 0) + Number(summary.running || 0);
    const partialFinished = !completed && failedCount > 0 && pendingCount === 0;
    const continued = !completed && Number(summary.successful || 0) > 0 && !partialFinished;
    const cleanupPending = completed && data.cleanup?.state === "pending" && !claimed;
    const conversionReady = selectedWorkflow === "official" && officialSetupReady;
    setText("legacyMigrationTitle", "Complete migration to Official");
    setText("legacyMigrationSubtitle", completed
      ? "Official migration complete"
      : (partialFinished ? "Official conversion finished with warnings" : "Final conversion is available"));
    setText("legacyOfficialMigrationHeading", completed
      ? "Official migration complete"
      : (partialFinished ? "Conversion run complete with warnings" : "Official migration ready to continue"));
    setText("legacyOfficialMigrationMessage", completed
      ? (cleanupPending ? "All Official versions were validated. Choose what to do with the copied Advanced workspace." : "All Official versions were validated successfully.")
      : (partialFinished
        ? `${summary.successful || 0} of ${summary.total || 0} liveries were converted successfully. ${failedCount} failed and remain available for a later retry.`
        : "LiveryLab will automatically process every remaining migrated livery."));
    setText("legacyMigrationIntro", completed
      ? (cleanupPending
        ? "All migrated liveries were converted and validated. Choose what to do with the copied Advanced workspace."
        : "All migrated liveries were converted and validated. The copied Advanced workspace is being kept.")
      : (partialFinished
        ? "The successful Official liveries are finished and available in My Liveries. The copied Advanced workspace is kept because some liveries could not be converted."
        : "After the Official setup is complete, LiveryLab can convert every migrated livery automatically. No manual Advanced export is required."));
    setText(
      "legacyOfficialMigrationSummary",
      `${summary.successful || 0} successful / ${summary.total || 0} total | ${failedCount} failed | ${summary.warnings || 0} with Advanced-only features | ${pendingCount} not processed`,
    );
    renderLiveryRows("legacyOfficialMigrationRows", queue.items || [], true);
    setHidden("legacyOfficialMigrationResume", completed || !conversionReady);
    setText("legacyOfficialMigrationResume", partialFinished
      ? "Retry Failed Liveries"
      : (continued ? "Continue Official Conversion" : "Convert All to Official"));
    setHidden("legacyOfficialMigrationOpenSetup", completed || conversionReady);
    setText("legacyOfficialMigrationOpenSetup", selectedWorkflow === "official" ? "Open Official Setup" : "Choose Official Workflow");
    setHidden("legacyOfficialMigrationCleanup", !cleanupPending);
    setHidden("legacyOfficialMigrationDeleteCopy", !cleanupPending);
    setHidden("legacyOfficialMigrationKeepCopy", !cleanupPending);
    setHidden("legacyOfficialMigrationDecideLater", !cleanupPending);
    setHidden("legacyOfficialMigrationDismiss", completed);
    setText("legacyOfficialMigrationDismiss", data.dismissed === true ? "Restore Migration Reminder" : "Dismiss Migration Reminder");
    setText("legacyMigrationStatus", completed
      ? (cleanupPending
        ? "Official conversion completed successfully. You can make the storage decision now or later."
        : "Migration finished successfully. The Advanced workspace remains available.")
      : (partialFinished
        ? "Conversion run finished. Successful liveries are complete; failed liveries can be retried now or later."
        : (conversionReady
          ? "Official setup is complete. Start the final conversion when you are ready."
          : "Choose the Official workflow and complete its setup first. This pending conversion does not expire.")));
    if ($("legacyMigrationModal")) {
      $("legacyMigrationModal").dataset.type = completed ? "success" : (partialFinished ? "warning" : "info");
      $("legacyMigrationModal").hidden = false;
    }
    renderWorkflowMigrationStatus();
  }

  async function runOfficialContinuation() {
    if (busy || !pendingOfficialMigration) return;
    if (selectedWorkflow !== "official" || !officialSetupReady) {
      renderOfficialContinuation(pendingOfficialMigration);
      return;
    }
    const api = window.pywebview?.api;
    if (typeof api?.run_pending_legacy_official_migration !== "function") return renderError("Official migration continuation is unavailable in this runtime copy.");
    startMigrationProgress(pendingOfficialMigration, true);
    let answer;
    try {
      answer = await api.run_pending_legacy_official_migration();
    } catch (error) {
      answer = { ok: false, message: error?.message || String(error) };
    }
    finishMigrationProgress();
    if (!answer?.ok) return renderError(answer?.message || "Official migration failed.", answer?.errorDetails);
    const previous = pendingOfficialMigration;
    const next = {
      ...previous,
      dismissed: false,
      queue: answer.data?.queue || previous.queue || {},
      cleanup: answer.data?.cleanup || previous.cleanup || {},
    };
    pendingOfficialMigration = next;
    if (queueCompleted(next) && advancedClaimed(next)) {
      if (String(next.cleanup?.state || "") === "kept") {
        renderOfficialContinuation(next);
        pendingOfficialMigration = null;
        setText("legacyOfficialMigrationHeading", "Official migration complete");
        setText("legacyOfficialMigrationMessage", "All Official versions were validated. The migrated Advanced workspace remains available.");
        renderWorkflowMigrationStatus();
        return;
      }
      await cleanupAdvancedCopy("keep", { silent: true });
      return;
    }
    const refreshed = await api.get_pending_legacy_official_migration();
    renderOfficialContinuation(refreshed?.data?.pending ? refreshed.data : next);
  }

  async function setMigrationReminderDismissed(dismissed) {
    if (busy || !pendingOfficialMigration) return;
    const api = window.pywebview?.api;
    if (typeof api?.set_legacy_official_migration_dismissed !== "function") {
      return renderError("This runtime cannot update the migration reminder preference.");
    }
    setBusy(true, dismissed ? "Dismissing migration reminder..." : "Restoring migration reminder...");
    const result = await api.set_legacy_official_migration_dismissed({
      migrationId: migrationId(pendingOfficialMigration),
      dismissed: Boolean(dismissed),
    });
    setBusy(false);
    if (!result?.ok) return renderError(result?.message || "Migration reminder preference could not be saved.", result?.errorDetails);
    pendingOfficialMigration = {
      ...pendingOfficialMigration,
      dismissed: result.data?.dismissed === true,
    };
    renderWorkflowMigrationStatus();
    if (pendingOfficialMigration.dismissed) closeModal();
    else renderOfficialContinuation(pendingOfficialMigration);
  }

  async function loadPendingOfficialMigration({ show = false } = {}) {
    const api = window.pywebview?.api;
    if (typeof api?.get_pending_legacy_official_migration !== "function") return;
    const result = await api.get_pending_legacy_official_migration();
    if (!result?.ok || !result.data?.pending) {
      pendingOfficialMigration = null;
      renderWorkflowMigrationStatus();
      return null;
    }
    pendingOfficialMigration = result.data;
    if (queueCompleted(result.data) && advancedClaimed(result.data)) {
      if (String(result.data.cleanup?.state || "") !== "kept") {
        try {
          const keep = await api.cleanup_legacy_advanced_copy({ decision: "keep", confirmToken: "" });
          if (!keep?.ok) throw new Error(keep?.message || "Keep decision could not be stored.");
        } catch (_error) {
          renderWorkflowMigrationStatus();
          return result.data;
        }
      }
      pendingOfficialMigration = null;
      renderWorkflowMigrationStatus();
      return null;
    }
    renderWorkflowMigrationStatus();
    if (show) renderOfficialContinuation(result.data);
    return result.data;
  }

  async function cleanupAdvancedCopy(decision, { silent = false } = {}) {
    if (busy || !pendingOfficialMigration) return;
    const api = window.pywebview?.api;
    if (typeof api?.cleanup_legacy_advanced_copy !== "function") return;
    let confirmed = true;
    if (decision === "delete" && typeof window.showConfirmModal === "function") {
      $("legacyMigrationModal").hidden = true;
      confirmed = await window.showConfirmModal({
        type: "warning",
        title: "Delete the copied Advanced migration data?",
        subtitle: "Reclaim disk space in the current LiveryLab installation",
        message: "Official projects and imported user source files are kept. Unsupported Tyre Brands, Driver Profiles and separate plate assets will remain only in the unchanged old installation.",
        details: "Only files owned by this migration are removed. AC EVO game files and the old LiveryLab installation are not changed.",
        confirmLabel: "Delete Copied Data",
        cancelLabel: "Cancel",
      });
      $("legacyMigrationModal").hidden = false;
    }
    if (!confirmed) return;
    setBusy(true, decision === "delete" ? "Removing copied Advanced migration data..." : "Keeping the Advanced workspace...");
    const result = await api.cleanup_legacy_advanced_copy({
      decision,
      confirmToken: decision === "delete" ? DELETE_COPY_TOKEN : "",
    });
    setBusy(false);
    if (!result?.ok) return renderError(result?.message || "Advanced copy cleanup failed.", result?.errorDetails);
    pendingOfficialMigration = null;
    setHidden("legacyOfficialMigrationDeleteCopy", true);
    setHidden("legacyOfficialMigrationKeepCopy", true);
    setHidden("legacyOfficialMigrationDecideLater", true);
    setHidden("legacyOfficialMigrationCleanup", true);
    setText("legacyOfficialMigrationHeading", decision === "delete" ? "Copied Advanced data removed" : "Advanced workspace kept");
    setText("legacyOfficialMigrationMessage", decision === "delete"
      ? `${formatBytes(result.data?.removedBytes)} was removed from the new LiveryLab folder. The old installation remains unchanged.`
      : "The migrated Advanced workspace remains available and inactive alongside the Official versions.");
    setText("legacyMigrationStatus", "Migration finished successfully.");
    if ($("legacyMigrationModal")) $("legacyMigrationModal").dataset.type = "success";
    renderWorkflowMigrationStatus();
  }

  async function claimAdvancedWorkspace() {
    const pending = pendingOfficialMigration || await loadPendingOfficialMigration();
    if (!pending) return;
    rememberAdvancedClaim(pending);
    renderWorkflowMigrationStatus();
    const api = window.pywebview?.api;
    if (typeof api?.cleanup_legacy_advanced_copy !== "function") return;
    try {
      const result = await api.cleanup_legacy_advanced_copy({ decision: "keep", confirmToken: "" });
      if (result?.ok) {
        pending.cleanup = { ...(pending.cleanup || {}), state: "kept", decision: "keep" };
        if (queueCompleted(pending)) pendingOfficialMigration = null;
        renderWorkflowMigrationStatus();
      }
    } catch (_error) {
      // Older no-build runtimes cannot persist an early keep decision; local storage preserves it until final conversion.
    }
  }

  async function handleWorkflowSelected(scope) {
    selectedWorkflow = String(scope || "").toLowerCase() === "official" ? "official" : "advanced";
    officialSetupReady = false;
    await loadPendingOfficialMigration();
    if (selectedWorkflow === "advanced") await claimAdvancedWorkspace();
  }

  async function handleSetupGate(scope, ready) {
    const normalized = String(scope || "").toLowerCase();
    officialSetupReady = normalized === "official" && ready === true;
    if (!officialSetupReady) return;
    const pending = pendingOfficialMigration || await loadPendingOfficialMigration();
    if (!pending || pending.dismissed === true) return;
    const id = migrationId(pending);
    if (offeredMigrationId === id || !id) return;
    offeredMigrationId = id;
    window.setTimeout(() => renderOfficialContinuation(pending), 250);
  }

  async function restartApp() {
    const api = window.pywebview?.api;
    if (typeof api?.restart_app !== "function") return renderError("Automatic restart is unavailable. Close and reopen LiveryLab manually.");
    setBusy(true, "Restarting LiveryLab...", "Restarting...");
    const result = await api.restart_app();
    if (!result?.ok) {
      setBusy(false);
      renderError(result?.message || "LiveryLab could not restart automatically.", result?.errorDetails);
    }
  }

  async function openLongPathsHelp(action) {
    const api = window.pywebview?.api;
    if (typeof api?.open_long_paths_help !== "function") return;
    const result = await api.open_long_paths_help(action);
    if (!result?.ok) renderError(result?.message || "Long Paths help could not be opened.", result?.errorDetails);
  }

  function openOfficialSetup() {
    closeModal();
    const choice = document.querySelector('[data-workflow-choice="official"]');
    if (choice instanceof HTMLElement) choice.click();
  }

  const previousProgressHandler = window.handleBackendProgress;
  window.handleBackendProgress = function handleLegacyMigrationProgress(eventName, payload) {
    if (eventName === "legacy_migration" || eventName === "legacy_official_migration") {
      renderMigrationProgress(payload || {});
      return;
    }
    if (typeof previousProgressHandler === "function") previousProgressHandler.call(window, eventName, payload);
  };

  $("openLegacyMigration")?.addEventListener("click", openModal);
  $("pickLegacyMigrationSource")?.addEventListener("click", chooseSource);
  $("legacyMigrationApply")?.addEventListener("click", migrateWorkspace);
  $("legacyMigrationRestart")?.addEventListener("click", restartApp);
  $("legacyOfficialMigrationResume")?.addEventListener("click", runOfficialContinuation);
  $("legacyOfficialMigrationOpenSetup")?.addEventListener("click", openOfficialSetup);
  $("legacyOfficialMigrationDeleteCopy")?.addEventListener("click", () => cleanupAdvancedCopy("delete"));
  $("legacyOfficialMigrationKeepCopy")?.addEventListener("click", () => cleanupAdvancedCopy("keep"));
  $("legacyOfficialMigrationDecideLater")?.addEventListener("click", closeModal);
  $("legacyOfficialMigrationDismiss")?.addEventListener("click", () => setMigrationReminderDismissed(pendingOfficialMigration?.dismissed !== true));
  $("legacyMigrationOpenLongPathsBat")?.addEventListener("click", () => openLongPathsHelp("folder"));
  $("legacyMigrationGoogleLongPaths")?.addEventListener("click", () => openLongPathsHelp("google"));
  $("legacyMigrationRecheckLongPaths")?.addEventListener("click", () => inspectPath($("legacyMigrationSourcePath")?.value || ""));
  $("legacyMigrationClose")?.addEventListener("click", closeModal);
  $("legacyMigrationCloseX")?.addEventListener("click", closeModal);
  $("legacyMigrationBackdrop")?.addEventListener("click", closeModal);
  document.addEventListener("keydown", (event) => {
    if (event.key !== "Escape" || $("legacyMigrationModal")?.hidden || busy) return;
    event.preventDefault();
    closeModal();
  });

  const initializePendingMigration = () => {
    refreshOfficialMigrationCapability();
    return loadPendingOfficialMigration().catch(() => {});
  };
  refreshOfficialMigrationCapability();
  if (window.pywebview?.api) initializePendingMigration();
  else window.addEventListener("pywebviewready", initializePendingMigration, { once: true });

  window.LiveryLabLegacyMigration = {
    inspectPath,
    migrateWorkspace,
    loadPendingOfficialMigration,
    handleWorkflowSelected,
    handleSetupGate,
    open: openModal,
    close: closeModal,
  };
})();
