import { isPlainObject, type JsonObject } from "../contracts/json";

export function getDirectSpriteRows(record: JsonObject): string[] {
  const rawRows = record.rows;
  if (!Array.isArray(rawRows)) {
    return [];
  }
  return rawRows.map((row) => String(row || ""));
}

export function normalizeRowsToSize(rows: string[], width: number, height: number, fillChar = "."): string[] {
  const safeWidth = Math.max(1, Math.floor(Number(width) || 1));
  const safeHeight = Math.max(1, Math.floor(Number(height) || 1));
  return Array.from({ length: safeHeight }, (_, rowIndex) => {
    const base = String(rows[rowIndex] || "");
    return base.padEnd(safeWidth, fillChar).slice(0, safeWidth);
  });
}

export function getRawImageFrames(record: JsonObject): JsonObject[] {
  if (!Array.isArray(record.frames)) {
    return [];
  }
  return record.frames.filter((entry): entry is JsonObject => isPlainObject(entry));
}

export function getSortedImageFrames(record: JsonObject): JsonObject[] {
  return getRawImageFrames(record)
    .map((entry, index) => ({
      entry,
      sortIndex: Number.isFinite(Number(entry.index)) ? Number(entry.index) : index,
      sourceIndex: index,
    }))
    .sort((left, right) => (
      left.sortIndex !== right.sortIndex
        ? left.sortIndex - right.sortIndex
        : left.sourceIndex - right.sourceIndex
    ))
    .map((entry) => entry.entry);
}

export function getSpriteRows(record: JsonObject): string[] {
  const frames = getSortedImageFrames(record);
  if (frames.length > 0) {
    const defaultFrameId = String(record.defaultFrame || "").trim();
    const enabledFrames = frames.filter((entry) => entry.enabled !== false);
    const renderFrames = enabledFrames.length > 0 ? enabledFrames : frames;
    const resolvedFrame = renderFrames.find((entry) => String(entry.id || "").trim() === defaultFrameId) || renderFrames[0];
    return getDirectSpriteRows(resolvedFrame);
  }
  return getDirectSpriteRows(record);
}
