import { chromium, type Browser, type Page, type BrowserContext } from '@playwright/test'

const FIGMA_CDP_PORT = 9222

export class FigmaHelper {
  private browser!: Browser
  private context!: BrowserContext
  page!: Page

  async connect() {
    this.browser = await chromium.connectOverCDP(`http://localhost:${FIGMA_CDP_PORT}`)
    const contexts = this.browser.contexts()
    if (contexts.length === 0) throw new Error('No Figma contexts found')
    this.context = contexts[0]

    const pages = this.context.pages()
    const editorPage = pages.find((p) => p.url().includes('figma.com/design'))
    if (!editorPage) {
      throw new Error(
        `No Figma editor page found. Open a file in Figma first.\nPages: ${pages.map((p) => p.url()).join(', ')}`
      )
    }
    this.page = editorPage
  }

  async disconnect() {
    await this.browser?.close()
  }

  get canvas() {
    return this.page.locator('canvas.gpu-view-content')
  }

  async screenshotCanvas() {
    return this.canvas.screenshot()
  }

  private async canvasBounds() {
    return this.canvas.boundingBox().then((b) => b!)
  }

  async waitForRender() {
    await this.page.waitForTimeout(500)
  }

  async click(canvasX: number, canvasY: number) {
    const box = await this.canvasBounds()
    await this.page.mouse.click(box.x + canvasX, box.y + canvasY)
  }

  async drag(
    fromX: number,
    fromY: number,
    toX: number,
    toY: number,
    steps = 10
  ) {
    const box = await this.canvasBounds()
    await this.page.mouse.move(box.x + fromX, box.y + fromY)
    await this.page.mouse.down()
    await this.page.mouse.move(box.x + toX, box.y + toY, { steps })
    await this.page.mouse.up()
  }

  async pressKey(key: string) {
    await this.page.keyboard.press(key)
  }

  async drawRect(x: number, y: number, width: number, height: number) {
    await this.pressKey('r')
    await this.waitForRender()
    await this.drag(x, y, x + width, y + height)
    await this.waitForRender()
  }

  async selectAll() {
    await this.pressKey('Meta+a')
    await this.waitForRender()
  }

  async deleteSelection() {
    await this.selectAll()
    await this.pressKey('Backspace')
    await this.waitForRender()
  }
}
