import assert from "node:assert/strict"
import { describe, it } from "node:test"
import {
  applyGraphicKeyboardAction,
  cycleFloatSide,
  graphicKeyboardActionFromKey,
  isInFlowGraphic,
} from "./docs-graphic-keyboard.ts"
import { DOCS_GRAPHIC_DEFAULTS } from "./docs-graphic-types.ts"

describe("docs-graphic-keyboard", () => {
  it("maps arrow keys to move steps", () => {
    const event = { key: "ArrowRight", shiftKey: false, altKey: false, metaKey: false, ctrlKey: false } as KeyboardEvent
    assert.deepEqual(graphicKeyboardActionFromKey(event), { type: "move", dx: 1, dy: 0 })
  })

  it("maps shift+arrow to larger move", () => {
    const event = { key: "ArrowDown", shiftKey: true, altKey: false, metaKey: false, ctrlKey: false } as KeyboardEvent
    assert.deepEqual(graphicKeyboardActionFromKey(event), { type: "move", dx: 0, dy: 10 })
  })

  it("maps alt+arrow to resize", () => {
    const event = { key: "ArrowRight", shiftKey: false, altKey: true, metaKey: false, ctrlKey: false } as KeyboardEvent
    assert.deepEqual(graphicKeyboardActionFromKey(event), { type: "resize", dw: 5, dh: 0 })
  })

  it("maps mod+] to bring forward", () => {
    const event = { key: "]", shiftKey: false, altKey: false, metaKey: true, ctrlKey: false } as KeyboardEvent
    assert.deepEqual(graphicKeyboardActionFromKey(event), { type: "layer", direction: "forward" })
  })

  it("applyGraphicKeyboardAction moves page-layer coords", () => {
    const attrs = {
      ...DOCS_GRAPHIC_DEFAULTS,
      wrap: "in-front" as const,
      positionMode: "fixed-on-page" as const,
      pageX: 100,
      pageY: 50,
    }
    const patch = applyGraphicKeyboardAction(attrs, { type: "move", dx: 3, dy: -2 })
    assert.equal(patch?.pageX, 103)
    assert.equal(patch?.pageY, 48)
  })

  it("isInFlowGraphic detects move-with-text graphics outside page layer", () => {
    const attrs = {
      ...DOCS_GRAPHIC_DEFAULTS,
      wrap: "square" as const,
      positionMode: "move-with-text" as const,
    }
    assert.equal(isInFlowGraphic(attrs), true)
    assert.equal(
      isInFlowGraphic({ ...attrs, positionMode: "fixed-on-page", placement: "absolute" }),
      false
    )
  })

  it("cycleFloatSide rotates left, center, right", () => {
    assert.equal(cycleFloatSide("left", "right"), "center")
    assert.equal(cycleFloatSide("center", "right"), "right")
    assert.equal(cycleFloatSide("right", "right"), "left")
    assert.equal(cycleFloatSide("left", "left"), "right")
    assert.equal(cycleFloatSide("center", "left"), "left")
  })

  it("applyGraphicKeyboardAction defers in-flow arrow moves to runGraphicKeyboardAction", () => {
    const attrs = {
      ...DOCS_GRAPHIC_DEFAULTS,
      placement: "block" as const,
      wrap: "square" as const,
      positionMode: "move-with-text" as const,
    }
    assert.equal(applyGraphicKeyboardAction(attrs, { type: "move", dx: 1, dy: 0 }), null)
  })

  it("applyGraphicKeyboardAction shrinks width from left with offset", () => {
    const attrs = {
      ...DOCS_GRAPHIC_DEFAULTS,
      placement: "absolute" as const,
      x: 40,
      y: 20,
      width: 100,
      height: 80,
    }
    const patch = applyGraphicKeyboardAction(attrs, { type: "resize", dw: -10, dh: 0 })
    assert.equal(patch?.width, 90)
    assert.equal(patch?.x, 50)
  })
})
