import { describe, it, expect, vi } from "vitest";
import { drawAxes } from "../drawAxes";

function makeScene() {
  const textMock = { setOrigin: vi.fn() };
  const g = {
    fillStyle: vi.fn(),
    fillRect: vi.fn(),
  };
  const scene = {
    add: {
      graphics: vi.fn(() => g),
      text: vi.fn(() => textMock),
    },
    _g: g,
    _text: textMock,
  };
  return { scene, g, textMock };
}

describe("drawAxes", () => {
  it("creates a graphics object", () => {
    const { scene } = makeScene();
    drawAxes(scene, { x: false, y: false });
    expect(scene.add.graphics).toHaveBeenCalledOnce();
  });

  describe("axis.x = true", () => {
    it("draws major and mid tick rects on the x axis", () => {
      const { scene, g } = makeScene();
      drawAxes(scene, { x: true, y: false });
      expect(g.fillRect).toHaveBeenCalled();
    });

    it("adds text labels for labeled ticks", () => {
      const { scene } = makeScene();
      drawAxes(scene, { x: true, y: false });
      // labeledTicks = [20, 40, 60, 80] → 4 calls
      const xCalls = scene.add.text.mock.calls;
      expect(xCalls.length).toBeGreaterThanOrEqual(4);
    });

    it("does not add text for y axis when only x is enabled", () => {
      const { scene } = makeScene();
      drawAxes(scene, { x: true, y: false }, 800, 600);
      // All text calls should use bottomY (alturaTela - 8 = 592) as y coordinate
      const yCoordsOfText = scene.add.text.mock.calls.map((c) => c[1]);
      // bottomY + 2 = 594 for labeledTicks that produce text at bottomY+2
      yCoordsOfText.forEach((y) => {
        expect(typeof y).toBe("number");
      });
    });
  });

  describe("axis.y = true", () => {
    it("draws major and mid tick rects on the y axis", () => {
      const { scene, g } = makeScene();
      drawAxes(scene, { x: false, y: true });
      expect(g.fillRect).toHaveBeenCalled();
    });

    it("adds text labels for labeled ticks on y axis", () => {
      const { scene } = makeScene();
      drawAxes(scene, { x: false, y: true });
      expect(scene.add.text).toHaveBeenCalled();
    });
  });

  describe("axis.x = false, axis.y = false", () => {
    it("draws no rects and no text", () => {
      const { scene, g } = makeScene();
      drawAxes(scene, { x: false, y: false });
      expect(g.fillRect).not.toHaveBeenCalled();
      expect(scene.add.text).not.toHaveBeenCalled();
    });
  });

  describe("axis.x = true, axis.y = true", () => {
    it("draws both axes", () => {
      const { scene, g } = makeScene();
      drawAxes(scene, { x: true, y: true });
      // majorTicks (4) + midTicks (5) for each axis = 18 fillRect calls
      expect(g.fillRect.mock.calls.length).toBe(18);
      // labeledTicks (4) for x + 4 for y = 8 text calls
      expect(scene.add.text.mock.calls.length).toBe(8);
    });
  });

  describe("default dimensions", () => {
    it("uses 800x600 by default", () => {
      const { scene, g } = makeScene();
      // Should not throw without explicit dimensions
      expect(() => drawAxes(scene, { x: true, y: true })).not.toThrow();
    });
  });

  describe("custom dimensions", () => {
    it("accepts custom width and height", () => {
      const { scene } = makeScene();
      expect(() => drawAxes(scene, { x: true, y: true }, 1024, 768)).not.toThrow();
    });
  });
});
