(() => {
  const atlasForm = document.getElementById("atlasForm");
  if (!atlasForm) {
    return;
  }

  const atlasSliceMode = document.getElementById("atlasSliceMode");
  const atlasModeInputs = document.querySelectorAll('input[name="atlas_mode_ui"]');
  const atlasModePills = document.querySelectorAll(".atlas-mode-pill");
  const atlasManualModeInputs = document.querySelectorAll('input[name="atlas_manual_mode_ui"]');
  const atlasManualModePills = document.querySelectorAll(".atlas-manual-mode-pill");
  const atlasExportModeInputs = document.querySelectorAll('input[name="export_mode"]');
  const atlasExportModePills = document.querySelectorAll(".atlas-export-mode-pill");
  const atlasModeSummary = document.getElementById("atlasModeSummary");
  const atlasAdvancedPanel = document.getElementById("atlasAdvancedPanel");
  const atlasPixelExportPanel = document.getElementById("atlasPixelExportPanel");
  const atlasPixelOptions = document.getElementById("atlasPixelOptions");
  const atlasInput = document.getElementById("atlasInput");
  const atlasUploadDropzone = document.getElementById("atlasUploadDropzone");
  const atlasUploadFilename = document.getElementById("atlasUploadFilename");
  const atlasUploadFileMeta = document.getElementById("atlasUploadFileMeta");
  const atlasUploadProgress = document.getElementById("atlasUploadProgress");
  const atlasUploadProgressBar = document.getElementById("atlasUploadProgressBar");
  const atlasUploadProgressLabel = document.getElementById("atlasUploadProgressLabel");
  const atlasRows = document.getElementById("atlasRows");
  const atlasCols = document.getElementById("atlasCols");
  const atlasOriginX = document.getElementById("atlasOriginX");
  const atlasOriginY = document.getElementById("atlasOriginY");
  const atlasRegionWidth = document.getElementById("atlasRegionWidth");
  const atlasRegionHeight = document.getElementById("atlasRegionHeight");
  const atlasCellWidth = document.getElementById("atlasCellWidth");
  const atlasCellHeight = document.getElementById("atlasCellHeight");
  const atlasPixelOutputWidth = document.getElementById("atlasPixelOutputWidth");
  const atlasPixelOutputHeight = document.getElementById("atlasPixelOutputHeight");
  const atlasPixelPresetRow = document.getElementById("atlasPixelPresetRow");
  const atlasSpacingX = document.getElementById("atlasSpacingX");
  const atlasSpacingY = document.getElementById("atlasSpacingY");
  const atlasMarginLeft = document.getElementById("atlasMarginLeft");
  const atlasMarginTop = document.getElementById("atlasMarginTop");
  const atlasMarginRight = document.getElementById("atlasMarginRight");
  const atlasMarginBottom = document.getElementById("atlasMarginBottom");
  const atlasIndexBase = document.getElementById("atlasIndexBase");
  const atlasAutoCloseRadius = document.getElementById("atlasAutoCloseRadius");
  const atlasAutoMinArea = document.getElementById("atlasAutoMinArea");
  const atlasAutoPadding = document.getElementById("atlasAutoPadding");
  const atlasPreviewImage = document.getElementById("atlasPreviewImage");
  const atlasPreviewPlaceholder = document.getElementById("atlasPreviewPlaceholder");
  const atlasSourceMeta = document.getElementById("atlasSourceMeta");
  const atlasPreviewStage = document.querySelector(".atlas-preview-stage");
  const atlasResultMeta = document.getElementById("atlasResultMeta");
  const atlasSliceCount = document.getElementById("atlasSliceCount");
  const atlasDetectedGrid = document.getElementById("atlasDetectedGrid");
  const atlasSliceSize = document.getElementById("atlasSliceSize");
  const atlasSliceNames = document.getElementById("atlasSliceNames");
  const atlasSummaryText = document.getElementById("atlasSummaryText");
  const atlasSourceDownloadLink = document.getElementById("atlasSourceDownloadLink");
  const atlasSourceDownloadHint = document.getElementById("atlasSourceDownloadHint");
  const atlasDownloadLink = document.getElementById("atlasDownloadLink");
  const atlasDownloadHint = document.getElementById("atlasDownloadHint");
  const quickProcessedDownloadLink = document.getElementById("quickProcessedDownloadLink");
  const quickZipDownloadLink = document.getElementById("quickZipDownloadLink");
  const sliceAtlasButton = document.getElementById("sliceAtlasButton");
  const atlasStatusText = document.getElementById("atlasStatusText");
  const atlasStatusDetail = document.getElementById("atlasStatusDetail");
  const visualBoundaryMatch = document.getElementById("visualBoundaryMatch");
  const visualBoundaryChip = document.getElementById("visualBoundaryChip");
  const atlasGridPresetButtons = document.querySelectorAll(".atlas-grid-preset");
  const atlasPixelPresetButtons = document.querySelectorAll(".atlas-pixel-preset");

  let atlasObjectUrl = null;
  let currentAtlasFile = null;
  let atlasDragDepth = 0;
  let currentProcessedAtlas = null;

  function clamp(value, min, max) {
    return Math.min(max, Math.max(min, value));
  }

  function safeJsonParse(text) {
    try {
      return JSON.parse(text);
    } catch (error) {
      return null;
    }
  }

  function selectedAtlasMode() {
    const checkedInput = document.querySelector('input[name="atlas_mode_ui"]:checked');
    return checkedInput ? checkedInput.value : "auto";
  }

  function selectedAtlasManualMode() {
    const checkedInput = document.querySelector('input[name="atlas_manual_mode_ui"]:checked');
    return checkedInput ? checkedInput.value : "grid";
  }

  function selectedAtlasExportMode() {
    const checkedInput = document.querySelector('input[name="export_mode"]:checked');
    return checkedInput ? checkedInput.value : "pixel";
  }

  function formatFileSize(sizeInBytes) {
    if (sizeInBytes < 1024 * 1024) {
      return `${(sizeInBytes / 1024).toFixed(1)} KB`;
    }

    return `${(sizeInBytes / (1024 * 1024)).toFixed(2)} MB`;
  }

  function formatSizeVariants(values) {
    if (!Array.isArray(values) || values.length === 0) {
      return "-";
    }

    if (values.length === 1) {
      return `${values[0]} px`;
    }

    return `${values.join(" / ")} px`;
  }

  function setAtlasStatus(message, type = "idle", detail = "") {
    const fallbackDetail = {
      idle: "上传图集后，就可以直接开始识别和切片。",
      loading: "图集正在上传并处理中，请稍等。",
      success: "切片完成，可以直接下载 ZIP。",
      error: "请检查图集内容或参数设置后再试一次。",
    };

    atlasStatusText.textContent = message;
    atlasStatusText.className = `status-badge status-${type}`;
    atlasStatusDetail.textContent = detail || fallbackDetail[type] || fallbackDetail.idle;
  }

  function setAtlasProgress(options = {}) {
    const {
      visible = false,
      value = 0,
      label = "等待上传",
      state = "idle",
      indeterminate = false,
    } = options;

    atlasUploadProgress.classList.toggle("is-visible", visible);
    atlasUploadProgress.dataset.state = state;
    atlasUploadProgressLabel.textContent = label;
    atlasUploadProgressBar.classList.toggle("is-indeterminate", indeterminate);
    atlasUploadProgressBar.style.width = `${clamp(value, 0, 100)}%`;
  }

  function setAtlasBusy(isBusy) {
    atlasPreviewStage.classList.toggle("is-busy", isBusy);
  }

  function revokeAtlasPreview() {
    if (atlasObjectUrl) {
      URL.revokeObjectURL(atlasObjectUrl);
      atlasObjectUrl = null;
    }
  }

  function syncQuickAtlasDownloads() {
    const atlasDownloads = [
      [atlasSourceDownloadLink, quickProcessedDownloadLink],
      [atlasDownloadLink, quickZipDownloadLink],
    ];

    for (const [sourceLink, quickLink] of atlasDownloads) {
      if (!quickLink) {
        continue;
      }

      const href = sourceLink.getAttribute("href");
      const downloadName = sourceLink.getAttribute("download");
      const isDisabled = sourceLink.classList.contains("disabled") || !href || href === "#";

      if (isDisabled) {
        quickLink.classList.add("disabled");
        quickLink.href = "#";
        quickLink.removeAttribute("download");
        continue;
      }

      quickLink.classList.remove("disabled");
      quickLink.href = href;
      if (downloadName) {
        quickLink.download = downloadName;
      } else {
        quickLink.removeAttribute("download");
      }
    }

    window.dispatchEvent(new Event("perfectpixel:quick-sync"));
  }

  function syncAtlasSourceDownload() {
    if (!currentProcessedAtlas || !currentProcessedAtlas.url) {
      atlasSourceDownloadLink.classList.add("disabled");
      atlasSourceDownloadLink.href = "#";
      atlasSourceDownloadLink.removeAttribute("download");
      syncQuickAtlasDownloads();
      atlasSourceDownloadHint.textContent = "切到“像素结果”并处理完成后，这里可以单独下载压缩后的整图 PNG。";
      return;
    }

    atlasSourceDownloadLink.href = currentProcessedAtlas.url;
    atlasSourceDownloadLink.download = currentProcessedAtlas.name || "pixel-sheet.png";
    atlasSourceDownloadLink.classList.remove("disabled");
    syncQuickAtlasDownloads();
    atlasSourceDownloadHint.textContent = currentProcessedAtlas.width && currentProcessedAtlas.height
      ? `压缩后整图：${currentProcessedAtlas.name} · ${currentProcessedAtlas.width} x ${currentProcessedAtlas.height}`
      : `压缩后整图：${currentProcessedAtlas.name}`;
  }

  function getCurrentAtlasFile() {
    if (currentAtlasFile) {
      return currentAtlasFile;
    }

    if (atlasInput.files && atlasInput.files.length) {
      return atlasInput.files[0];
    }

    return null;
  }

  function trySyncNativeInput(file) {
    if (!file || typeof DataTransfer === "undefined") {
      return;
    }

    try {
      const transfer = new DataTransfer();
      transfer.items.add(file);
      atlasInput.files = transfer.files;
    } catch (error) {
      // Some browsers do not allow assigning FileList programmatically.
    }
  }

  function setAtlasDropzoneFileState(hasFile) {
    atlasUploadDropzone.classList.toggle("has-file", hasFile);
  }

  function resetAtlasDropzoneHint() {
    const file = getCurrentAtlasFile();

    if (file) {
      atlasUploadFilename.textContent = `已载入 ${file.name}`;
      return;
    }

    atlasUploadFilename.textContent = "当前还没有选择图集";
    atlasUploadFileMeta.textContent = "默认直接自动识别，无需手动输入行列";
  }

  function updateGridPresetButtons() {
    const rows = atlasRows.value;
    const cols = atlasCols.value;

    for (const button of atlasGridPresetButtons) {
      const isActive = button.dataset.rows === rows && button.dataset.cols === cols;
      button.classList.toggle("is-active", isActive);
    }
  }

  function updatePixelPresetButtons() {
    const usingPixelExport = selectedAtlasExportMode() === "pixel";
    const width = atlasPixelOutputWidth.value;
    const height = atlasPixelOutputHeight.value;

    if (atlasPixelExportPanel) {
      atlasPixelExportPanel.classList.toggle("is-hidden", !usingPixelExport);
    }

    for (const button of atlasPixelPresetButtons) {
      const size = button.dataset.size || "";
      const isActive = usingPixelExport && width === size && height === size;
      button.classList.toggle("is-active", isActive);
      button.disabled = !usingPixelExport;
    }
  }

  function updateModeSummary() {
    const mode = selectedAtlasMode();
    const exportMode = selectedAtlasExportMode();
    updatePixelPresetButtons();
    const pipelineSummary = exportMode === "pixel"
      ? `导出链路：自动识别切片 -> 像素结果 ${atlasPixelOutputWidth.value || "?"} x ${atlasPixelOutputHeight.value || "?"} -> 原图来源。`
      : "导出链路：自动识别切片 -> 原图切片 ZIP。";
    if (mode === "auto") {
      atlasModeSummary.textContent = `当前模式：自动识别。系统会自动分割小图、自动定位边界、自动统一导出尺寸。${pipelineSummary}`;
      return;
    }

    const manualMode = selectedAtlasManualMode();
    const originX = atlasOriginX.value || "0";
    const originY = atlasOriginY.value || "0";
    const regionWidth = atlasRegionWidth.value.trim() || "自动";
    const regionHeight = atlasRegionHeight.value.trim() || "自动";
    const cellWidth = atlasCellWidth.value.trim() || "?";
    const cellHeight = atlasCellHeight.value.trim() || "?";
    const spacingX = atlasSpacingX.value || "0";
    const spacingY = atlasSpacingY.value || "0";
    const marginSummary = `边距 L${atlasMarginLeft.value || "0"} / T${atlasMarginTop.value || "0"} / R${atlasMarginRight.value || "0"} / B${atlasMarginBottom.value || "0"}`;

    if (manualMode === "cell_size") {
      atlasModeSummary.textContent = `当前模式：按单张尺寸反推。目标单格 ${cellWidth} x ${cellHeight}，起点 (${originX}, ${originY})，区域 ${regionWidth} x ${regionHeight}，间距 ${spacingX} / ${spacingY}，${marginSummary}。${pipelineSummary}`;
      return;
    }

    const rows = atlasRows.value || "?";
    const cols = atlasCols.value || "?";

    atlasModeSummary.textContent = `当前模式：高级手动。规则 ${rows} x ${cols}，起点 (${originX}, ${originY})，区域 ${regionWidth} x ${regionHeight}。${pipelineSummary}`;
  }

  function syncBoundaryChip() {
    visualBoundaryChip.classList.toggle("is-active", Boolean(visualBoundaryMatch.checked));
  }

  function syncAtlasManualModeUI() {
    const manualMode = selectedAtlasManualMode();
    const usingCellSize = selectedAtlasMode() === "manual" && manualMode === "cell_size";

    for (const pill of atlasManualModePills) {
      const input = pill.querySelector("input");
      pill.classList.toggle("is-active", Boolean(input && input.checked));
    }

    atlasRows.disabled = usingCellSize;
    atlasCols.disabled = usingCellSize;

    for (const button of atlasGridPresetButtons) {
      button.disabled = usingCellSize;
      button.classList.toggle("is-disabled", usingCellSize);
    }

    updateGridPresetButtons();
    updateModeSummary();
  }

  function syncAtlasExportModeUI() {
    const exportMode = selectedAtlasExportMode();
    const usingPixelExport = exportMode === "pixel";

    if (usingPixelExport) {
      if (!atlasPixelOutputWidth.value.trim()) {
        atlasPixelOutputWidth.value = "16";
      }

      if (!atlasPixelOutputHeight.value.trim()) {
        atlasPixelOutputHeight.value = "16";
      }
    }

    for (const pill of atlasExportModePills) {
      const input = pill.querySelector("input");
      pill.classList.toggle("is-active", Boolean(input && input.checked));
    }

    atlasPixelOutputWidth.disabled = !usingPixelExport;
    atlasPixelOutputHeight.disabled = !usingPixelExport;

    const mode = selectedAtlasMode();
    if (mode === "manual") {
      sliceAtlasButton.textContent = usingPixelExport
        ? "按规则切片并导出像素结果 ZIP"
        : "按手动规则切片并导出 ZIP";
    } else {
      sliceAtlasButton.textContent = usingPixelExport
        ? "自动识别并导出像素结果 ZIP"
        : "自动识别并导出 ZIP";
    }

    updateModeSummary();
  }

  function applyLinkedAtlasPixelSize(size) {
    const parsedSize = Number.parseInt(String(size || "").trim(), 10);
    if (!Number.isFinite(parsedSize) || parsedSize <= 0) {
      return;
    }

    const normalized = String(parsedSize);
    atlasPixelOutputWidth.value = normalized;
    atlasPixelOutputHeight.value = normalized;
    atlasPixelOutputWidth.dispatchEvent(new Event("input", { bubbles: true }));
    atlasPixelOutputHeight.dispatchEvent(new Event("input", { bubbles: true }));
  }

  function syncAtlasModeUI() {
    const mode = selectedAtlasMode();
    atlasSliceMode.value = mode;

    for (const pill of atlasModePills) {
      const input = pill.querySelector("input");
      pill.classList.toggle("is-active", Boolean(input && input.checked));
    }

    atlasAdvancedPanel.classList.toggle("is-hidden", mode !== "manual");
    syncAtlasManualModeUI();
    syncAtlasExportModeUI();
    resetAtlasResult();
  }

  function resetAtlasResult() {
    currentProcessedAtlas = null;
    atlasResultMeta.textContent = "等待切片";
    atlasSliceCount.textContent = "-";
    atlasDetectedGrid.textContent = "-";
    atlasSliceSize.textContent = "-";
    atlasSliceNames.textContent = "-";
    atlasSummaryText.textContent = selectedAtlasMode() === "manual"
      ? (
        selectedAtlasManualMode() === "cell_size"
          ? (
            selectedAtlasExportMode() === "pixel"
              ? "当前处于按单张尺寸反推 + 像素结果导出模式。生成后会显示反推出的行列结果与像素输出尺寸。"
              : "当前处于按单张尺寸反推模式。生成后会显示反推出的行列结果与导出尺寸。"
          )
          : (
            selectedAtlasExportMode() === "pixel"
              ? "当前处于手动兜底 + 像素结果导出模式。生成后会显示切片行列结果与像素输出尺寸。"
              : "当前处于手动兜底模式。生成后会显示手动切片的行列结果与导出尺寸。"
          )
      )
      : (
        selectedAtlasExportMode() === "pixel"
          ? "上传图集后就可以直接自动识别，并把每张小图生成为你指定大小的像素结果。"
          : "上传图集后就可以直接自动识别。系统会优先尝试无手动参数的自动分割流程。"
      );
    atlasDownloadLink.classList.add("disabled");
    atlasDownloadLink.href = "#";
    atlasDownloadLink.removeAttribute("download");
    atlasDownloadHint.textContent = "切片完成后，这里会启用 ZIP 下载按钮。";
    syncAtlasSourceDownload();
  }

  function updateAtlasPreview() {
    const file = getCurrentAtlasFile();
    revokeAtlasPreview();
    syncAtlasSourceDownload();
    setAtlasProgress();

    if (!file) {
      atlasPreviewImage.removeAttribute("src");
      atlasPreviewImage.style.display = "none";
      atlasPreviewPlaceholder.style.display = "block";
      atlasSourceMeta.textContent = "尚未选择图集";
      atlasUploadFilename.textContent = "当前还没有选择图集";
      atlasUploadFileMeta.textContent = "默认直接自动识别，无需手动输入行列";
      setAtlasDropzoneFileState(false);
      resetAtlasResult();
      window.dispatchEvent(new Event("perfectpixel:quick-sync"));
      return;
    }

    setAtlasDropzoneFileState(true);
    atlasSourceMeta.textContent = "正在读取图集...";
    atlasUploadFilename.textContent = `已载入 ${file.name}`;
    atlasUploadFileMeta.textContent = `${formatFileSize(file.size)} · 已准备识别`;

    atlasObjectUrl = URL.createObjectURL(file);
    syncAtlasSourceDownload();
    atlasPreviewImage.onload = () => {
      const dimensions = `${atlasPreviewImage.naturalWidth} x ${atlasPreviewImage.naturalHeight}`;
      atlasSourceMeta.textContent = `${file.name} · ${dimensions} · ${formatFileSize(file.size)}`;
      atlasUploadFileMeta.textContent = `${dimensions} · ${formatFileSize(file.size)} · 已准备识别`;
      setAtlasStatus("图集已载入", "idle", "现在可以直接开始自动识别切片。");
      window.dispatchEvent(new Event("perfectpixel:quick-sync"));
    };
    atlasPreviewImage.onerror = () => {
      atlasSourceMeta.textContent = "图集预览失败";
      atlasUploadFileMeta.textContent = "请重新选择一张可读取的图集图片";
      setAtlasStatus("图集读取失败", "error", "请换一张 PNG、JPG、JPEG 或 WebP 图集。");
      window.dispatchEvent(new Event("perfectpixel:quick-sync"));
    };

    atlasPreviewImage.src = atlasObjectUrl;
    atlasPreviewImage.style.display = "block";
    atlasPreviewPlaceholder.style.display = "none";
  }

  function buildAtlasFormData() {
    const formData = new FormData(atlasForm);
    const file = getCurrentAtlasFile();

    if (file) {
      formData.set("atlas", file, file.name);
    }

    formData.set("slice_mode", selectedAtlasMode());
    formData.set("manual_mode", selectedAtlasManualMode());
    return formData;
  }

  function requestAtlasSlice(formData) {
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      xhr.open("POST", "/api/slice-atlas");
      xhr.responseType = "json";

      xhr.upload.addEventListener("progress", (event) => {
        if (!event.lengthComputable) {
          return;
        }

        const percent = Math.max(4, Math.round((event.loaded / event.total) * 100));
        setAtlasProgress({
          visible: true,
          value: percent,
          label: `正在上传图集 ${percent}%`,
          state: "uploading",
        });
        setAtlasStatus("正在上传图集...", "loading", "文件已开始上传，请稍等。");
      });

      xhr.upload.addEventListener("load", () => {
        setAtlasProgress({
          visible: true,
          value: 100,
          label: "上传完成，正在分析图集结构...",
          state: "uploading",
          indeterminate: true,
        });
        setAtlasStatus("正在识别并切片...", "loading", "图集已上传，系统正在自动分割并导出 PNG。");
      });

      xhr.onerror = () => {
        reject(new Error("网络连接异常，请稍后再试。"));
      };

      xhr.onload = () => {
        const payload = xhr.response || safeJsonParse(xhr.responseText) || {};

        if (xhr.status >= 200 && xhr.status < 300) {
          resolve(payload);
          return;
        }

        reject(new Error(payload.error || "图集切片失败，请稍后再试。"));
      };

      xhr.send(formData);
    });
  }

  function buildDetectedGridLabel(payload) {
    if (!payload.rows || !payload.cols) {
      return payload.slice_mode === "auto" ? "自动识别完成" : "-";
    }

    if (payload.slice_mode === "auto") {
      return `${payload.rows} x ${payload.cols}（自动）`;
    }

    if (payload.manual_mode === "cell_size") {
      return `${payload.rows} x ${payload.cols}（按尺寸反推）`;
    }

    return `${payload.rows} x ${payload.cols}（手动）`;
  }

  function buildSummaryText(payload) {
    if (payload.slice_mode === "auto") {
      const autoMeta = payload.auto_detection || {};
      const rowLengths = Array.isArray(autoMeta.row_lengths) && autoMeta.row_lengths.length
        ? `每行数量：${autoMeta.row_lengths.join(" / ")}。`
        : "";

      if (payload.export_mode === "pixel") {
        return `自动识别完成：源图 ${payload.source_width} x ${payload.source_height}，识别到 ${payload.slice_count} 张小图，并已按 ${payload.pixel_output_width} x ${payload.pixel_output_height} 生成像素结果。${rowLengths}`;
      }

      return `自动识别完成：源图 ${payload.source_width} x ${payload.source_height}，识别到 ${payload.slice_count} 张小图。${rowLengths}`;
    }

    if (payload.manual_mode === "cell_size") {
      if (payload.export_mode === "pixel") {
        return `反推切片完成：按单张尺寸自动反推出 ${payload.rows} x ${payload.cols}，并已统一生成 ${payload.pixel_output_width} x ${payload.pixel_output_height} 的像素结果，共导出 ${payload.slice_count} 张。`;
      }

      return `反推切片完成：按单张尺寸自动反推出 ${payload.rows} x ${payload.cols}，共导出 ${payload.slice_count} 张。`;
    }

    if (payload.export_mode === "pixel") {
      return `手动切片完成：按 ${payload.rows} x ${payload.cols} 规则切片，并已统一生成 ${payload.pixel_output_width} x ${payload.pixel_output_height} 的像素结果，共导出 ${payload.slice_count} 张。`;
    }

    return `手动切片完成：按 ${payload.rows} x ${payload.cols} 规则导出，共 ${payload.slice_count} 张。`;
  }

  function applyAtlasResult(payload) {
    const sizeLabel = `宽 ${formatSizeVariants(payload.slice_widths)} · 高 ${formatSizeVariants(payload.slice_heights)}`;
    const nameLabel = payload.first_slice && payload.last_slice
      ? `${payload.first_slice} -> ${payload.last_slice}`
      : "-";

    atlasResultMeta.textContent = `${payload.slice_count} 张切片`;
    atlasSliceCount.textContent = `${payload.slice_count} 张`;
    atlasDetectedGrid.textContent = buildDetectedGridLabel(payload);
    atlasSliceSize.textContent = sizeLabel;
    atlasSliceNames.textContent = nameLabel;
    atlasSummaryText.textContent = buildSummaryText(payload);
    atlasDownloadLink.href = payload.zip_url;
    atlasDownloadLink.download = payload.zip_name || "atlas_slices.zip";
    atlasDownloadLink.classList.remove("disabled");
    atlasDownloadHint.textContent = `ZIP 已就绪：${payload.zip_name}`;
    currentProcessedAtlas = payload.processed_image_url
      ? {
        url: payload.processed_image_url,
        name: payload.processed_image_name || "pixel-sheet.png",
        width: payload.processed_image_width || null,
        height: payload.processed_image_height || null,
      }
      : null;
    syncAtlasSourceDownload();
  }

  function isImageFile(file) {
    if (!file) {
      return false;
    }

    return file.type.startsWith("image/") || /\.(png|jpe?g|webp)$/i.test(file.name);
  }

  function assignAtlasFile(file) {
    currentAtlasFile = file;
    trySyncNativeInput(file);
    updateAtlasPreview();
  }

  async function fileFromDataUrl(dataUrl, filename) {
    const response = await fetch(dataUrl);
    const blob = await response.blob();
    const normalizedName = /\.png$/i.test(filename) ? filename : `${filename}.png`;
    return new File([blob], normalizedName, { type: "image/png" });
  }

  function preventDragDefaults(event) {
    event.preventDefault();
    event.stopPropagation();
  }

  async function handleAtlasSubmit(event) {
    event.preventDefault();

    const file = getCurrentAtlasFile();
    if (!file) {
      setAtlasStatus("请先选择一张图集", "error", "上传图集后才能开始切片。");
      return;
    }

    if (
      selectedAtlasExportMode() === "pixel"
      && (!atlasPixelOutputWidth.value.trim() || !atlasPixelOutputHeight.value.trim())
    ) {
      setAtlasStatus("请先填写单张像素结果大小", "error", "导出像素结果时，需要同时填写宽度和高度。");
      return;
    }

    setAtlasBusy(true);
    sliceAtlasButton.disabled = true;
    resetAtlasResult();
    atlasResultMeta.textContent = "处理中...";
    setAtlasProgress({
      visible: true,
      value: 4,
      label: "正在准备上传...",
      state: "uploading",
    });
    setAtlasStatus("正在上传图集...", "loading", "图集正在发送到本地切片接口。");

    try {
      const payload = await requestAtlasSlice(buildAtlasFormData());
      applyAtlasResult(payload);
      setAtlasProgress({
        visible: true,
        value: 100,
        label: "切片完成，可下载 ZIP。",
        state: "success",
      });
      setAtlasStatus("切片完成", "success", "独立 PNG 与 ZIP 压缩包都已经准备好。");
    } catch (error) {
      atlasResultMeta.textContent = "切片失败";
      setAtlasProgress({
        visible: true,
        value: 100,
        label: error.message || "图集切片失败，请稍后再试。",
        state: "error",
      });
      setAtlasStatus(
        error.message || "图集切片失败，请稍后再试。",
        "error",
        "如果自动识别不理想，可以切换到高级手动模式继续处理。",
      );
    } finally {
      setAtlasBusy(false);
      sliceAtlasButton.disabled = false;
    }
  }

  async function runAtlasWorkflowFromGeneratedResult(options = {}) {
    const {
      dataUrl,
      filename = "pixel-result.png",
      scrollIntoView = true,
    } = options;
    if (!dataUrl) {
      throw new Error("Missing generated image data for atlas slicing.");
    }

    const autoMode = document.querySelector('input[name="atlas_mode_ui"][value="auto"]');
    if (autoMode) {
      autoMode.checked = true;
    }
    syncAtlasModeUI();

    const generatedFile = await fileFromDataUrl(dataUrl, filename);
    assignAtlasFile(generatedFile);

    if (scrollIntoView) {
      const atlasCard = document.querySelector(".atlas-card");
      if (atlasCard) {
        atlasCard.scrollIntoView({ behavior: "smooth", block: "start" });
      }
    }

    resetAtlasResult();
    setAtlasStatus(
      "图集已载入，等待导出设置",
      "idle",
      "请先确认导出类型和参数，再点击下方按钮开始识别切片。",
    );
    atlasResultMeta.textContent = "等待开始识别";
    atlasSummaryText.textContent = selectedAtlasExportMode() === "pixel"
      ? "像素结果图已经送入图集模块。先选择导出类型与单张输出尺寸，再开始自动识别切片。"
      : "图片已经送入图集模块。先确认导出类型，再开始自动识别切片。";
    atlasDownloadHint.textContent = "选择导出类型并开始切片后，这里会启用 ZIP 下载按钮。";
  }

  function resetAtlasWorkflowForNewSource() {
    currentAtlasFile = null;
    atlasInput.value = "";
    updateAtlasPreview();
    atlasResultMeta.textContent = "等待新的图片结果";
    atlasSummaryText.textContent = "重新上传图片后，请先重新生成像素图，再选择导出类型并开始切片。";
    setAtlasStatus("已切换到新图片，请重新开始后续步骤", "idle", "旧的切片结果已经清空，新的像素结果生成后再继续。");
  }

  for (const input of atlasModeInputs) {
    input.addEventListener("change", syncAtlasModeUI);
  }

  for (const input of atlasExportModeInputs) {
    input.addEventListener("change", () => {
      syncAtlasExportModeUI();
      resetAtlasResult();
    });
  }

  for (const button of atlasGridPresetButtons) {
    button.addEventListener("click", () => {
      const manualMode = document.querySelector('input[name="atlas_mode_ui"][value="manual"]');
      if (manualMode) {
        manualMode.checked = true;
      }

      const gridMode = document.querySelector('input[name="atlas_manual_mode_ui"][value="grid"]');
      if (gridMode) {
        gridMode.checked = true;
      }

      atlasRows.value = button.dataset.rows || atlasRows.value;
      atlasCols.value = button.dataset.cols || atlasCols.value;
      syncAtlasModeUI();
    });
  }

  for (const button of atlasPixelPresetButtons) {
    button.addEventListener("click", () => {
      applyLinkedAtlasPixelSize(button.dataset.size || "");
    });
  }

  atlasUploadDropzone.addEventListener("click", (event) => {
    if (event.target === atlasInput) {
      return;
    }

    event.preventDefault();
    atlasInput.click();
  });

  atlasInput.addEventListener("click", () => {
    atlasInput.value = "";
  });

  atlasUploadDropzone.addEventListener("dragenter", (event) => {
    preventDragDefaults(event);
    atlasDragDepth += 1;
    atlasUploadDropzone.classList.add("is-dragover");
    atlasUploadFilename.textContent = "松开即可上传这张图集";
    atlasUploadFileMeta.textContent = "支持 PNG、JPG、JPEG、WebP";
  });

  atlasUploadDropzone.addEventListener("dragover", (event) => {
    preventDragDefaults(event);
    atlasUploadDropzone.classList.add("is-dragover");
    atlasUploadFilename.textContent = "松开即可上传这张图集";
    atlasUploadFileMeta.textContent = "支持 PNG、JPG、JPEG、WebP";
  });

  atlasUploadDropzone.addEventListener("dragleave", (event) => {
    preventDragDefaults(event);
    atlasDragDepth = Math.max(0, atlasDragDepth - 1);

    if (atlasDragDepth === 0) {
      atlasUploadDropzone.classList.remove("is-dragover");
      resetAtlasDropzoneHint();
    }
  });

  atlasUploadDropzone.addEventListener("dragend", (event) => {
    preventDragDefaults(event);
    atlasDragDepth = 0;
    atlasUploadDropzone.classList.remove("is-dragover");
    resetAtlasDropzoneHint();
  });

  atlasUploadDropzone.addEventListener("drop", (event) => {
    preventDragDefaults(event);
    atlasDragDepth = 0;
    atlasUploadDropzone.classList.remove("is-dragover");

    const droppedFiles = event.dataTransfer && event.dataTransfer.files
      ? Array.from(event.dataTransfer.files)
      : [];
    const file = droppedFiles.find(isImageFile);

    if (!file) {
      atlasUploadFilename.textContent = "当前还没有选择图集";
      atlasUploadFileMeta.textContent = "请拖入 PNG、JPG、JPEG、WebP 图集";
      setAtlasStatus("请拖入正确的图集格式", "error", "仅支持 PNG、JPG、JPEG、WebP 图片。");
      return;
    }

    assignAtlasFile(file);
    setAtlasStatus("图集已载入", "idle", "拖拽上传成功，现在可以直接开始切片。");
  });

  atlasInput.addEventListener("change", () => {
    const file = atlasInput.files && atlasInput.files[0];
    if (file) {
      currentAtlasFile = file;
    }
    updateAtlasPreview();
  });

  [
    atlasRows,
    atlasCols,
    atlasOriginX,
    atlasOriginY,
    atlasRegionWidth,
    atlasRegionHeight,
    atlasCellWidth,
    atlasCellHeight,
    atlasPixelOutputWidth,
    atlasPixelOutputHeight,
    atlasSpacingX,
    atlasSpacingY,
    atlasMarginLeft,
    atlasMarginTop,
    atlasMarginRight,
    atlasMarginBottom,
    atlasIndexBase,
    atlasAutoCloseRadius,
    atlasAutoMinArea,
    atlasAutoPadding,
  ].forEach((input) => {
    if (!input) {
      return;
    }

    input.addEventListener("input", () => {
      updateGridPresetButtons();
      updateModeSummary();
    });
  });

  visualBoundaryMatch.addEventListener("change", syncBoundaryChip);
  atlasForm.addEventListener("submit", handleAtlasSubmit);
  for (const input of atlasManualModeInputs) {
    input.addEventListener("change", () => {
      syncAtlasManualModeUI();
      resetAtlasResult();
    });
  }

  window.perfectPixelAtlasBridge = {
    runFromGeneratedResult: runAtlasWorkflowFromGeneratedResult,
    resetForNewSource: resetAtlasWorkflowForNewSource,
  };

  updateAtlasPreview();
  syncBoundaryChip();
  syncAtlasExportModeUI();
  syncAtlasModeUI();
})();
