import assert from "node:assert/strict"
import { describe, it } from "node:test"
import {
  normalizeImportedGraphics,
  normalizeLegacyImageAttrs,
} from "./docs-graphic-import.ts"
import { extractGraphicPositionsFromDocx } from "./docx-position-import.ts"
import { computeCropImageStyle } from "./docs-graphic-types.ts"

function normalizeImportedTipTap(content: Record<string, unknown>) {
  return normalizeImportedGraphics(normalizeLegacyImageAttrs(content))
}

describe("richtext-import chain", () => {
  it("preserves placement and rotation through full chain", () => {
    const result = normalizeImportedTipTap({
      type: "doc",
      content: [
        {
          type: "paragraph",
          content: [
            {
              type: "image",
              attrs: {
                src: "data:image/png;base64,abc",
                width: 200,
                height: 120,
                placement: "absolute",
                wrap: "square",
                x: 40,
                y: 20,
                rotationDeg: 15,
                floatSide: "right",
              },
            },
          ],
        },
      ],
    })
    const node = result.content?.[0] as { type?: string; attrs?: Record<string, unknown> }
    assert.equal(node.type, "docsGraphic")
    assert.equal(node.attrs?.placement, "absolute")
    assert.equal(node.attrs?.x, 40)
    assert.equal(node.attrs?.y, 20)
    assert.equal(node.attrs?.rotationDeg, 15)
    assert.equal(node.attrs?.floatSide, "right")
  })

  it("preserves crop attrs through full chain", () => {
    const result = normalizeImportedTipTap({
      type: "doc",
      content: [
        {
          type: "image",
          attrs: {
            src: "data:image/png;base64,abc",
            cropX: 0.1,
            cropY: 0.2,
            cropWidth: 0.8,
            cropHeight: 0.7,
          },
        },
      ],
    })
    const node = result.content?.[0] as { attrs?: Record<string, unknown> }
    assert.equal(node.attrs?.cropX, 0.1)
    assert.equal(node.attrs?.cropY, 0.2)
    assert.equal(node.attrs?.cropWidth, 0.8)
    assert.equal(node.attrs?.cropHeight, 0.7)
  })
})

describe("docx-position-import", () => {
  it("extractGraphicPositionsFromDocx parses inline extent", () => {
    const archive = {
      "word/document.xml": new TextEncoder().encode(`
        <w:document>
          <w:body>
            <w:p>
              <w:drawing>
                <wp:inline>
                  <wp:extent cx="914400" cy="457200"/>
                </wp:inline>
              </w:drawing>
            </w:p>
          </w:body>
        </w:document>
      `),
    }
    const positions = extractGraphicPositionsFromDocx(archive)
    assert.equal(positions.length, 1)
    assert.equal(positions[0]?.width, 96)
    assert.equal(positions[0]?.height, 48)
    assert.equal(positions[0]?.placement, "inline")
    assert.equal(positions[0]?.wrap, "inline")
  })
})

describe("docs-graphic-types crop", () => {
  it("computeCropImageStyle returns styles when crop active", () => {
    const style = computeCropImageStyle(
      {
        cropX: 0.1,
        cropY: 0,
        cropWidth: 0.8,
        cropHeight: 1,
        cropShape: "rect",
      },
      240,
      160,
      800,
      600
    )
    assert.ok(style.img.width)
    assert.equal(style.clipPath, undefined)
  })
})
