#target photoshop
app.bringToFront();

// ====== SETTINGS ======
var OUTER_SMARTOBJECT_NAME = "Etikett"; // äußeres (projiziertes) Smart-Objekt
var INNER_PDF_SO_NAME = "Frischer_Geist"; // inneres PDF-Smart-Objekt
var PDF_PAGE_NUMBER = 1; // 1-seitig / immer gleiche Seite
var JPG_QUALITY = 12;

// ====== GUARDS ======
if (app.documents.length === 0) {
  alert("Bitte öffne Photoshop (kein Dokument nötig), dann starte das Skript.");
}

// ====== PICK FILES/FOLDERS ======
var templateFile = File.openDialog("Template-PSD auswählen (dein Mockup.psd)", "PSD:*.psd");
if (!templateFile) exit();

var inputFolder = Folder.selectDialog("Ordner mit Etiketten-PDFs auswählen");
if (!inputFolder) exit();

var outputFolder = Folder.selectDialog("Zielordner für JPGs auswählen");
if (!outputFolder) exit();

var pdfFiles = inputFolder.getFiles(function(f) {
  return f instanceof File && /\.pdf$/i.test(f.name);
});

if (!pdfFiles || pdfFiles.length === 0) {
  alert("Keine PDFs im gewählten Ordner gefunden.");
  exit();
}

// ====== HELPERS ======
function findLayerByName(container, name) {
  // container can be Document or LayerSet
  var layers = container.layers;
  for (var i = 0; i < layers.length; i++) {
    var l = layers[i];
    if (l.name === name) return l;
    if (l.typename === "LayerSet") {
      var found = findLayerByName(l, name);
      if (found) return found;
    }
  }
  return null;
}

function editSmartObjectContents() {
  // opens the active smart object contents in a new document
  var id = stringIDToTypeID("placedLayerEditContents");
  executeAction(id, undefined, DialogModes.NO);
}

function replacePlacedLayerContents(fileObj, pageNumberOptional) {
  // Replaces contents of the active placed layer (Smart Object). Works for linked + embedded.
  // For PDFs we also try to pass page number to avoid dialogs.
  var id = stringIDToTypeID("placedLayerReplaceContents");
  var desc = new ActionDescriptor();
  desc.putPath(charIDToTypeID("null"), fileObj);

  // Try PDF page number hint (Photoshop versions differ; harmless if ignored)
  try {
    if (pageNumberOptional && pageNumberOptional > 0) {
      desc.putInteger(stringIDToTypeID("pageNumber"), pageNumberOptional);
    }
  } catch (e) {}

  executeAction(id, desc, DialogModes.NO);
}

function exportJPG(doc, outFile) {
  // Duplicate → flatten → saveAs JPG → close duplicate (keeps layers intact in working doc)
  var dup = doc.duplicate();
  dup.flatten();

  var jpgOptions = new JPEGSaveOptions();
  jpgOptions.quality = JPG_QUALITY;
  jpgOptions.embedColorProfile = true;

  dup.saveAs(outFile, jpgOptions, true);
  dup.close(SaveOptions.DONOTSAVECHANGES);
}

// ====== MAIN LOOP ======
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;

var oldDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;

try {
  for (var i = 0; i < pdfFiles.length; i++) {
    var pdf = pdfFiles[i];
    var baseName = pdf.name.replace(/\.[^\.]+$/, "");

    // Open a fresh copy of the template each iteration (robust, no undo/history issues)
    var doc = app.open(templateFile);

    // 1) Find & open outer smart object "Etikett"
    var outerLayer = findLayerByName(doc, OUTER_SMARTOBJECT_NAME);
    if (!outerLayer) {
      doc.close(SaveOptions.DONOTSAVECHANGES);
      throw new Error("Äußeres Smart-Objekt nicht gefunden: " + OUTER_SMARTOBJECT_NAME);
    }
    doc.activeLayer = outerLayer;
    editSmartObjectContents();

    // Now we're inside the smart object document (PSB)
    var soDoc = app.activeDocument;

    // 2) Find inner PDF smart object layer and replace its contents with current PDF
    var innerLayer = findLayerByName(soDoc, INNER_PDF_SO_NAME);
    if (!innerLayer) {
      soDoc.close(SaveOptions.DONOTSAVECHANGES);
      doc.close(SaveOptions.DONOTSAVECHANGES);
      throw new Error("Inneres PDF-Smart-Objekt nicht gefunden: " + INNER_PDF_SO_NAME);
    }

    soDoc.activeLayer = innerLayer;
    replacePlacedLayerContents(pdf, PDF_PAGE_NUMBER);

    // 3) Save & close inner smart object doc to propagate changes back
    soDoc.save();
    soDoc.close(SaveOptions.SAVECHANGES);

    // Back to main mockup doc
    var mainDoc = app.activeDocument; // should be the template doc
    var outFile = new File(outputFolder.fsName + "/" + baseName + ".jpg");
    exportJPG(mainDoc, outFile);

    // Close without saving (template stays untouched on disk)
    mainDoc.close(SaveOptions.DONOTSAVECHANGES);
  }

  alert("Fertig! " + pdfFiles.length + " Varianten als JPG exportiert.");
} catch (err) {
  alert("Abbruch wegen Fehler:\n" + err.message);
} finally {
  app.displayDialogs = oldDisplayDialogs;
  app.preferences.rulerUnits = originalRulerUnits;
}