import { describe, expect, it } from "vitest";
import {
  aspectRatioLabel,
  detailCropRects,
  inventoryCountCropRect,
  inventoryGrid,
  inventoryRect,
  isSixteenNine,
  layoutSupportWarning,
  profileDetailRect,
} from "./layoutProfile";

const HD = { width: 1920, height: 1080 };
const QHD = { width: 2560, height: 1440 };
const ULTRAWIDE = { width: 3440, height: 1440 };

describe("layoutProfile", () => {
  it("detects 16:9 across common resolutions and rejects ultrawide", () => {
    expect(isSixteenNine(HD)).toBe(true);
    expect(isSixteenNine(QHD)).toBe(true);
    expect(isSixteenNine({ width: 3840, height: 2160 })).toBe(true);
    expect(isSixteenNine(ULTRAWIDE)).toBe(false);
    expect(isSixteenNine({ width: 1920, height: 1200 })).toBe(false); // 16:10
  });

  it("labels the aspect ratio", () => {
    expect(aspectRatioLabel(HD)).toBe("1.78:1");
    expect(aspectRatioLabel({ width: 0, height: 0 })).toBe("unknown");
  });

  it("warns only for non-16:9 resolutions", () => {
    expect(layoutSupportWarning(HD)).toBe("");
    expect(layoutSupportWarning(QHD)).toBe("");
    expect(layoutSupportWarning(ULTRAWIDE)).toContain("nicht 16:9");
    expect(layoutSupportWarning({ width: 0, height: 0 })).toBe("");
  });

  it("keeps the detail rect inside the image and on the right half", () => {
    const rect = profileDetailRect(QHD);
    expect(rect.x).toBeGreaterThanOrEqual(QHD.width * 0.45);
    expect(rect.x + rect.width).toBeLessThanOrEqual(QHD.width);
    expect(rect.y + rect.height).toBeLessThanOrEqual(QHD.height);
  });

  it("produces the four artifact crops in top-to-bottom order, all clamped", () => {
    const detail = profileDetailRect(QHD);
    const crops = detailCropRects(detail, QHD);
    expect(crops.map((crop) => crop.id)).toEqual([
      "artifact-title",
      "artifact-main-stat",
      "artifact-substats",
      "artifact-footer",
    ]);
    let previousY = -1;
    for (const crop of crops) {
      expect(crop.rect.x).toBeGreaterThanOrEqual(0);
      expect(crop.rect.y).toBeGreaterThan(previousY);
      expect(crop.rect.x + crop.rect.width).toBeLessThanOrEqual(QHD.width);
      expect(crop.rect.y + crop.rect.height).toBeLessThanOrEqual(QHD.height);
      previousY = crop.rect.y;
    }
  });

  it("places the inventory count crop inside the inventory panel", () => {
    const detail = profileDetailRect(QHD);
    const inv = inventoryRect(QHD, detail);
    const count = inventoryCountCropRect(inv, QHD);
    expect(count.x).toBeGreaterThanOrEqual(inv.x);
    expect(count.x + count.width).toBeLessThanOrEqual(QHD.width);
  });

  it("builds a 5-column inventory grid on the left", () => {
    const detail = profileDetailRect(QHD);
    const grid = inventoryGrid(QHD, detail);
    expect(grid.cols).toBe(5);
    expect(grid.source).toBe("detected");
    expect(grid.centers.length).toBeGreaterThanOrEqual(10);
    expect(grid.centers.every((center) => center.x < detail.x)).toBe(true);
  });

  it("reports a missing grid when the inventory panel is too small", () => {
    const tiny = { width: 320, height: 180 };
    const grid = inventoryGrid(tiny, profileDetailRect(tiny));
    expect(grid.source).toBe("missing");
    expect(grid.centers).toHaveLength(0);
  });
});
