<script setup lang="ts">
import * as PIXI from 'pixi.js'
import { Viewport } from 'pixi-viewport'
import { onMounted, onBeforeUnmount, ref } from 'vue'
import tableSvg from '@/assets/images/table.png'

const viewportArea = ref<HTMLDivElement | null>(null)
let app: PIXI.Application | null = null
let viewport: Viewport | null = null
let resizeObserver: ResizeObserver | null = null

onMounted(async () => {
  if (!viewportArea.value) return

  app = new PIXI.Application()

  // 1. Initialize with resizeTo
  await app.init({
    resizeTo: viewportArea.value,
    antialias: true,
    backgroundColor: 0x222222,
    roundPixels: true,
    resolution: window.devicePixelRatio * 2,
    autoDensity: true,
  })

  viewportArea.value.appendChild(app.canvas)

  // 2. Create Viewport
  viewport = new Viewport({
    screenWidth: viewportArea.value.clientWidth,
    screenHeight: viewportArea.value.clientHeight,
    worldWidth: 3000,
    worldHeight: 2000,
    events: app.renderer.events,
  })

  app.stage.addChild(viewport)

  // 3. Configure Behaviors & Clamping
  viewport
    .drag()
    .pinch()
    .wheel()
    .decelerate({
      friction: 0.95,
    })
    .clamp({ direction: 'all' }) // Don't let user pan outside 1000x1000
    .clampZoom({
      maxHeight: 2000, // Max zoom out (show whole world)
      minWidth: 500, // Max zoom in (detail)
    })

  // Add visual markers
  setupScene(viewport)

  // 4. Handle Dynamic Resizing
  resizeObserver = new ResizeObserver(() => {
    if (viewport && viewportArea.value) {
      const { clientWidth, clientHeight } = viewportArea.value
      // Tell the viewport the "window" size changed
      viewport.resize(clientWidth, clientHeight)
      viewport.fitWorld()
    }
  })
  resizeObserver.observe(viewportArea.value)

  viewportArea.value.addEventListener(
    'wheel',
    (e) => {
      e.preventDefault()
    },
    { passive: false },
  )
})

async function setupScene(v: Viewport) {
  // Border

  const svgTexture = await PIXI.Assets.load({
    src: tableSvg,
    data: {},
  })

  const background = new PIXI.Sprite({
    texture: svgTexture,
    width: v.worldWidth,
    height: v.worldHeight,
  })

  v.addChild(background)

  // Center Sprite
  const sprite = v.addChild(new PIXI.Sprite(PIXI.Texture.WHITE))
  sprite.tint = 0xff0000
  sprite.setSize(100, 100)
  sprite.position.set(450, 450)
}

onBeforeUnmount(() => {
  resizeObserver?.disconnect()
  app?.destroy(true, { children: true, texture: true })
})
</script>

<template>
  <div class="viewport-wrapper" ref="viewportArea"></div>
</template>

<style scoped>
.viewport-wrapper {
  overflow: hidden;
  height: 100%;
  aspect-ratio: 3/2;
}
</style>
