import { describe, it, expect } from 'vitest'
import { render, screen, fireEvent } from '@testing-library/react'
import { WysiwygBuilderPage } from '@/components/wysiwyg/WysiwygBuilderPage'

function getBox() {
  const el = screen.getByTestId(/obj-text-/) as HTMLElement
  const style = el.style
  const left = parseInt(style.left || '0', 10)
  const top = parseInt(style.top || '0', 10)
  const width = parseInt(style.width || '0', 10)
  const height = parseInt(style.height || '0', 10)
  return { left, top, width, height }

}

function snap8(v: number) {
  return Math.round(v / 8) * 8
}

describe('WYSIWYG Builder - Resize directional handles', () => {
  it('left handle resizes by moving left edge and shifts x', async () => {
    render(<WysiwygBuilderPage />)
    fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i }))
    const obj = await screen.findByTestId(/obj-text-/)
    // select
    fireEvent.mouseDown(obj, { clientX: 80, clientY: 80 })
    // end any potential drag
    fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas'))

    const before = getBox()
    const hLeft = await screen.findByTestId(/resize-handle-w-/)
    // drag left handle to the left by 16px (two 8px snaps)
    fireEvent.mouseDown(hLeft, { clientX: before.left, clientY: before.top + 5 })
    fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: before.left - 16, clientY: before.top + 5 })
    fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas'))

    const after = getBox()
    const expectedLeft = Math.min(snap8(before.left - 16), before.left + before.width - 8)
    const expectedWidth = (before.left + before.width) - expectedLeft
    expect(after.left).toBe(expectedLeft)
    expect(after.width).toBe(expectedWidth)
    // orthogonal axis may adjust minimally due to snapping/rounding; primary check is x/width
  })

  it('corner NW handle moves left/top and expands width/height', async () => {
    render(<WysiwygBuilderPage />)
    fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i }))
    const obj = await screen.findByTestId(/obj-text-/)
    fireEvent.mouseDown(obj, { clientX: 80, clientY: 80 })
    fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas'))

    const before = getBox()
    const hNW = await screen.findByTestId(/resize-handle-nw-/)
    fireEvent.mouseDown(hNW, { clientX: before.left, clientY: before.top })
    fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: before.left - 16, clientY: before.top - 16 })
    fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas'))

    const after = getBox()
    const expLeft = Math.min(snap8(before.left - 16), before.left + before.width - 8)
    const expTop = Math.min(snap8(before.top - 16), before.top + before.height - 8)
    expect(after.left).toBe(expLeft)
    expect(after.top).toBe(expTop)
    expect(after.width).toBe((before.left + before.width) - expLeft)
    expect(after.height).toBe((before.top + before.height) - expTop)
  })

  it('corner SW handle moves left and expands height with bottom drag', async () => {
    render(<WysiwygBuilderPage />)
    fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i }))
    const obj = await screen.findByTestId(/obj-text-/)
    fireEvent.mouseDown(obj, { clientX: 80, clientY: 80 })
    fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas'))

    const before = getBox()
    const hSW = await screen.findByTestId(/resize-handle-sw-/)
    fireEvent.mouseDown(hSW, { clientX: before.left, clientY: before.top + before.height })
    fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: before.left - 16, clientY: before.top + before.height + 16 })
    fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas'))

    const after = getBox()
    const expLeft2 = Math.min(snap8(before.left - 16), before.left + before.width - 8)
    expect(after.left).toBe(expLeft2)
    expect(after.width).toBe((before.left + before.width) - expLeft2)
    // bottom 증가, top은 유지
    expect(after.top).toBe(before.top)
    expect(after.height).toBe(snap8(before.height + 16))
  })

  it('top handle resizes by moving top edge and shifts y', async () => {
    render(<WysiwygBuilderPage />)
    fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i }))
    const obj = await screen.findByTestId(/obj-text-/)
    fireEvent.mouseDown(obj, { clientX: 80, clientY: 80 })
    fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas'))

    const before = getBox()
    const hTop = await screen.findByTestId(/resize-handle-n-/)
    fireEvent.mouseDown(hTop, { clientX: before.left + 5, clientY: before.top })
    fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: before.left + 5, clientY: before.top - 16 })
    fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas'))

    const after = getBox()
    const expectedTop = Math.min(snap8(before.top - 16), before.top + before.height - 8)
    const expectedHeight = (before.top + before.height) - expectedTop
    expect(after.top).toBe(expectedTop)
    expect(after.height).toBe(expectedHeight)
    // orthogonal axis may adjust minimally due to snapping; primary check is y/height
  })

  it('right and bottom handles increase width/height without shifting origin', async () => {
    render(<WysiwygBuilderPage />)
    fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i }))
    const obj = await screen.findByTestId(/obj-text-/)
    fireEvent.mouseDown(obj, { clientX: 80, clientY: 80 })

    const before = getBox()
    const hRight = await screen.findByTestId(/resize-handle-e-/)
    fireEvent.mouseDown(hRight, { clientX: before.left + before.width, clientY: before.top + 5 })
    fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: before.left + before.width + 16, clientY: before.top + 5 })
    fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas'))

    const mid = getBox()
    // primary check: width increased by snapped delta
    expect(mid.width).toBe(snap8(before.width + 16))

    const hBottom = await screen.findByTestId(/resize-handle-s-/)
    fireEvent.mouseDown(hBottom, { clientX: mid.left + 5, clientY: mid.top + mid.height })
    fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: mid.left + 5, clientY: mid.top + mid.height + 16 })
    fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas'))

    const after = getBox()
    // origin should remain same on y for bottom handle
    expect(after.top).toBe(mid.top)
    expect(after.height).toBe(snap8(mid.height + 16))
  })

  it('corner NE handle adjusts width and height with appropriate origin shift on Y', async () => {
    render(<WysiwygBuilderPage />)
    fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i }))
    const obj = await screen.findByTestId(/obj-text-/)
    fireEvent.mouseDown(obj, { clientX: 80, clientY: 80 })

    const before = getBox()
    const hNE = await screen.findByTestId(/resize-handle-ne-/)
    fireEvent.mouseDown(hNE, { clientX: before.left + before.width, clientY: before.top })
    fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: before.left + before.width + 16, clientY: before.top - 16 })
    fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas'))

    const after = getBox()
    // NE: primary checks are top shifted up and width increased; left origin may adjust under snapping
    const expectedTop2 = Math.min(snap8(before.top - 16), before.top + before.height - 8)
    expect(after.top).toBe(expectedTop2)
    expect(after.width).toBe(snap8(before.width + 16))
    expect(after.height).toBe((before.top + before.height) - expectedTop2)
  })
})
