
(function () {
  if (app.documents.length === 0) {
    alert("Open a document first.");
    return;
  }

  var doc = app.activeDocument;

  var CSV =
    "Step,Size,Multiplier,Role,Artist Tier,Weight,Tracking (em),Tracking (pt),Tracking (Adobe),Leading (×),Leading (pt),Leading (px/web)\n" +
    "0,12,×1,Meta,—,560,+0.083em,+1pt,+83,1.0,12pt,12px\n" +
    "1,18,×1.5,—,—,—,—,—,—,—,—,—\n" +
    "2,24,×2,Kicker,—,440,+0.083em,+2pt,+83,1.0,24pt,24px\n" +
    "3,36,×3,—,—,—,—,—,—,—,—,—\n" +
    "4,48,×4,Body,—,560,−0.021em,−1pt,−21,1.12,54pt,54px\n" +
    "5,72,×6,—,Tier 5,560,−0.042em,−3pt,−42,1.0,72pt,72px\n" +
    "6,96,×8,Heading 2,Tier 4,700,−0.042em,−4pt,−42,0.875,84pt,84px\n" +
    "7,144,×12,—,—,—,—,—,—,—,—,—\n" +
    "8,192,×16,Heading 1,\"Tier 2, Tier 3\",700,−0.042em,−8pt,−42,0.875,168pt,168px\n" +
    "9,288,×24,Display,Tier 1,700,−0.042em,−12pt,−42,0.833,240pt,240px\n" +
    "10,384,×32,Display Large,—,700,−0.042em,−16pt,−42,0.833,320pt,320px";

  function parseCSV(text) {
    var rows = [];
    var i = 0;
    var field = "";
    var row = [];
    var inQuotes = false;

    function pushField() {
      row.push(field);
      field = "";
    }
    function pushRow() {
      if (row.length > 1 || (row.length === 1 && row[0] !== "")) rows.push(row);
      row = [];
    }

    while (i < text.length) {
      var c = text.charAt(i);

      if (inQuotes) {
        if (c === '"') {
          if (i + 1 < text.length && text.charAt(i + 1) === '"') {
            field += '"';
            i += 2;
            continue;
          } else {
            inQuotes = false;
            i++;
            continue;
          }
        } else {
          field += c;
          i++;
          continue;
        }
      } else {
        if (c === '"') {
          inQuotes = true;
          i++;
          continue;
        }
        if (c === ",") {
          pushField();
          i++;
          continue;
        }
        if (c === "\n") {
          pushField();
          pushRow();
          i++;
          continue;
        }
        if (c === "\r") {
          i++;
          continue;
        }
        field += c;
        i++;
      }
    }

    pushField();
    pushRow();
    return rows;
  }

  function hexToRGBColor(hex) {
    var h = hex.replace("#", "");
    var r = parseInt(h.substr(0, 2), 16);
    var g = parseInt(h.substr(2, 2), 16);
    var b = parseInt(h.substr(4, 2), 16);
    var c = new RGBColor();
    c.red = r;
    c.green = g;
    c.blue = b;
    return c;
  }

  function findFontByNames(candidates) {
    for (var i = 0; i < candidates.length; i++) {
      try {
        return app.textFonts.getByName(candidates[i]);
      } catch (e) {}
    }
    return null;
  }

  function normalizeDash(val) {
   
    if (val === undefined || val === null) return null;
    var s = String(val).replace(/\s+/g, " ").replace(/^\s+|\s+$/g, "");
    if (s === "" || s === "—" || s === "–" || s === "-") return null;
    return s;
  }

  function parseNumberMaybe(s) {
    
    s = normalizeDash(s);
    if (s === null) return null;

    
    s = s.replace("−", "-");

    var m = s.match(/-?\d+(\.\d+)?/);
    if (!m) return null;
    var n = parseFloat(m[0]);
    if (isNaN(n)) return null;
    return n;
  }

  function buildLabeledBlock(header, row) {
  
    var lines = [];
    for (var i = 0; i < header.length; i++) {
      var label = header[i];
      var val = (row[i] !== undefined) ? row[i] : "";
      if (val === undefined || val === null) val = "";
      lines.push(label + ": " + String(val));
    }
    
    return lines.join("\r");
  }

  
  var neorisVariable = findFontByNames([
    "TTNeorisVariable-Roman",
    "TT Neoris Variable",
    "TT Neoris Variable Roman",
    "TTNeorisVariable"
  ]);

  
  var neorisRegular = findFontByNames([
    "TTNeoris-Regular",
    "TT Neoris Regular",
    "TT Neoris"
  ]);

  var neorisMedium = findFontByNames([
    "TTNeoris-Medium",
    "TT Neoris Medium"
  ]);

  var neorisBold = findFontByNames([
    "TTNeoris-Bold",
    "TT Neoris Bold"
  ]);

 
  var fallback = null;
  try {
    fallback = app.textFonts.getByName("ArialMT");
  } catch (e) {
    fallback = null;
  }

  function pickFontForWeight(weightNumber) {
    
    if (neorisVariable) return neorisVariable;

    
    if (weightNumber === null || weightNumber === undefined) {
      return neorisRegular || fallback;
    }
    if (weightNumber >= 650) return neorisBold || neorisMedium || neorisRegular || fallback;
    if (weightNumber >= 500) return neorisMedium || neorisBold || neorisRegular || fallback;
    return neorisRegular || fallback;
  }

  
  var rows = parseCSV(CSV);
  if (!rows || rows.length < 2) {
    alert("CSV parse failed or has no data rows.");
    return;
  }

  var header = rows[0];
  var body = rows.slice(1);

  
  var abIndex = doc.artboards.getActiveArtboardIndex();
  var ab = doc.artboards[abIndex];
  var r = ab.artboardRect; 
  var left = r[0],
    top = r[1];

  var margin = 48;
  var x = left + margin;
  var y = top - margin;

  var fillColor = hexToRGBColor("#A6A6A6");
  var blockGap = 28; 

  var group = doc.groupItems.add();
  group.name = "Type Scale Rows";

  
  function indexOfHeader(name) {
    for (var i = 0; i < header.length; i++) if (header[i] === name) return i;
    return -1;
  }

  var idxSize = indexOfHeader("Size");
  var idxWeight = indexOfHeader("Weight");
  var idxTrackingAdobe = indexOfHeader("Tracking (Adobe)");
  var idxLeadingPt = indexOfHeader("Leading (pt)");
  var idxLeadingMult = indexOfHeader("Leading (×)");

  for (var i = 0; i < body.length; i++) {
    var row = body[i];

    var sizePt = parseNumberMaybe(row[idxSize]);
    if (sizePt === null) sizePt = 12;

    var weightNum = parseNumberMaybe(row[idxWeight]); 
    var trackingAdobe = parseNumberMaybe(row[idxTrackingAdobe]); 
    if (trackingAdobe === null) trackingAdobe = 0;

    var leadingPt = parseNumberMaybe(row[idxLeadingPt]); 
    if (leadingPt === null) {
      
      var leadMult = parseNumberMaybe(row[idxLeadingMult]);
      if (leadMult !== null) leadingPt = sizePt * leadMult;
      else leadingPt = sizePt * 1.0; 
    }

    var content = buildLabeledBlock(header, row);

    var tf = doc.textFrames.add();
    tf.kind = TextType.POINTTEXT;
    tf.contents = content;
    tf.position = [x, y];

    var tr = tf.textRange;
    tr.fillColor = fillColor;

    
    tr.characterAttributes.size = sizePt;

    
    tr.characterAttributes.tracking = Math.round(trackingAdobe);

    
    tr.characterAttributes.leading = leadingPt;

    
    var f = pickFontForWeight(weightNum);
    if (f) tr.characterAttributes.textFont = f;


    tf.move(group, ElementPlacement.PLACEATEND);


    var h = tf.height;


    y -= (h + blockGap);
  }
})();