import {
  buildImageRecordFromSpriteRecord,
  buildImageRecordFromTileRecord,
  buildTileRecordFromImageRecord,
  getImageRecordFromPayload,
  normalizeGraphicRoles,
  normalizeImagesPayloadSnapshot,
} from "./graphicsDocumentHelpers";
import type { JsonObject } from "../editorCore";

describe("graphicsDocumentHelpers", () => {
  it("keeps only supported graphic roles and de-duplicates them", () => {
    expect(normalizeGraphicRoles(["tile", "sprite", "tile", "other", "", null])).toEqual(["tile", "sprite"]);
    expect(normalizeGraphicRoles("tile")).toEqual([]);
  });

  it("builds tile-backed image records without inventing new storage rules", () => {
    const existingRecord: JsonObject = {
      id: "tile_grass",
      roles: ["sprite"],
      tileSymbol: "g",
      tags: ["existing"],
    };

    const result = buildImageRecordFromTileRecord({
      id: "tile_grass",
      name: "Grass",
      symbol: "#",
      rows: ["AB", "C"],
      width: 2,
      height: 2,
      pixelScale: 3,
      opacity: 2,
      tags: ["terrain", "terrain"],
    }, existingRecord);

    expect(result.roles).toEqual(["sprite", "tile"]);
    expect(result.tileSymbol).toBe("#");
    expect(result.rows).toBeUndefined();
    expect(result.defaultFrame).toBe("frame_0");
    expect(result.frames).toEqual([
      expect.objectContaining({
        id: "frame_0",
        rows: ["AB", "C."],
        width: 2,
        height: 2,
        pixelScale: 3,
        opacity: 1,
      }),
    ]);
    expect(result.tags).toEqual(["terrain"]);
  });

  it("updates sprite roles while preserving compatibility fields from existing images", () => {
    const existingRecord: JsonObject = {
      id: "hero",
      roles: ["tile", "sprite"],
      tileSymbol: "@",
    };

    const result = buildImageRecordFromSpriteRecord({
      id: "hero",
      rows: ["X"],
      width: 1,
      height: 1,
    }, "other", existingRecord);

    expect(result.roles).toEqual(["tile"]);
    expect(result.tileSymbol).toBe("@");
  });

  it("hydrates image rows from the resolved default frame", () => {
    const payload: JsonObject = {
      schemaVersion: 1,
      images: [
        {
          id: "tile_grass",
          roles: ["tile"],
          tileSymbol: "G",
          width: 2,
          height: 2,
          defaultFrame: "alt",
          frames: [
            { id: "base", rows: ["AA", "AA"], enabled: true },
            { id: "alt", rows: ["BB", "BB"], enabled: true },
          ],
        },
      ],
    };

    const snapshot = normalizeImagesPayloadSnapshot(payload);
    const imageRecord = getImageRecordFromPayload(snapshot, "tile_grass");

    expect(imageRecord).toEqual(expect.objectContaining({
      id: "tile_grass",
      rows: ["BB", "BB"],
    }));
  });

  it("projects tile records from image records through the current compatibility adapter", () => {
    const tileRecord = buildTileRecordFromImageRecord({
      id: "tile_grass",
      tileSymbol: "G",
      name: "Grass",
      description: "Ground",
      width: 2,
      height: 2,
      frames: [
        { id: "frame_0", rows: ["AB", "CD"] },
      ],
    });

    expect(tileRecord).toEqual(expect.objectContaining({
      id: "tile_grass",
      symbol: "G",
      rows: ["AB", "CD"],
      width: 2,
      height: 2,
    }));
  });
});
