"use client"
import React, { useCallback, useMemo, useRef, useState } from 'react'
import type { Frame, WObject } from '@/lib/wysiwyg/schema'
import { Canvas } from '@/components/wysiwyg/Canvas'
import { PropsPanel } from '@/components/wysiwyg/PropsPanel'
import { LayersPanel } from '@/components/wysiwyg/LayersPanel'
import { exportFrame } from '@/lib/wysiwyg/export'
import { buildZip } from '@/lib/exporter/zip'
import { AssetManager } from '@/lib/assets/assetManager'
import { buildAssetsMetadata } from '@/lib/exporter/assets.meta'
import { buildAssetsIndex } from '@/lib/exporter/assets.index'
import { buildAssetsIntegrityIndex } from '@/lib/exporter/assets.integrity.index'

function emptyFrame(): Frame {
  return {
    id: 'f-wysiwyg',
    width: 800,
    height: 500,
    background: '#111111',
    layers: [
      { id: 'base', name: 'Base', visible: true, locked: false, objects: [] },
    ],
  }
}

function download(filename: string, data: Uint8Array) {
  const ab = data.slice().buffer as ArrayBuffer
  const blob = new Blob([ab], { type: 'application/zip' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = filename
  document.body.appendChild(a)
  a.click()
  a.remove()
  URL.revokeObjectURL(url)
}

let textCounter = 1
let imageCounter = 1
let buttonCounter = 1

export function WysiwygBuilderPage() {
  const [frame, setFrame] = useState<Frame>(() => emptyFrame())
  const assetManagerRef = useRef<AssetManager | null>(null)
  const [selectedIds, setSelectedIds] = useState<string[]>([])
  const selectedId = selectedIds[selectedIds.length - 1] || null
  const selectedObject: WObject | null = useMemo(() => {
    for (const ly of frame.layers) {
      const o = ly.objects.find((x) => x.id === selectedId)
      if (o) return o
    }
    return null
  }, [frame, selectedId])

  const onChangeFrame = useCallback((next: Frame) => setFrame(next), [])
  const onSelectIds = useCallback((ids: string[]) => setSelectedIds(ids), [])

  const addText = useCallback(() => {
    const id = `text-${textCounter++}`
    const obj: WObject = { id, type: 'text', x: 60, y: 60, width: 160, height: 40, rotate: 0, zIndex: 0, props: { text: 'Text', fontSize: 18, color: '#ffffff' } }
    setFrame((prev) => ({
      ...prev,
      layers: prev.layers.map((l, i) => i === 0 ? { ...l, objects: [...l.objects, obj] } : l),
    }))
    setSelectedIds([id])
  }, [])

  const addImage = useCallback(() => {
    const id = `image-${imageCounter++}`
    const obj: WObject = { id, type: 'image', x: 60, y: 120, width: 120, height: 90, rotate: 0, zIndex: 0, props: { src: 'https://via.placeholder.com/120x90', alt: '' } }
    setFrame((prev) => ({
      ...prev,
      layers: prev.layers.map((l, i) => i === 0 ? { ...l, objects: [...l.objects, obj] } : l),
    }))
    setSelectedIds([id])
  }, [])

  const onUploadImage = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files
    if (!files || files.length === 0) return
    const file = files[0]
    const reader = new FileReader()
    reader.onload = () => {
      const result = reader.result
      if (!(result instanceof ArrayBuffer)) return
      const bytes = new Uint8Array(result)
      const am = assetManagerRef.current ?? new AssetManager({ maxBytes: 10 * 1024 * 1024, allowedExts: ['png', 'jpg', 'jpeg', 'webp', 'svg'], pathStrategy: 'grouped' })
      assetManagerRef.current = am
      am.add({ name: file.name, type: file.type, bytes }).then((ref) => {
        const id = `image-${imageCounter++}`
        const obj: WObject = {
          id,
          type: 'image',
          x: 60,
          y: 120,
          width: 120,
          height: 90,
          rotate: 0,
          zIndex: 0,
          props: { src: `/${ref.path}` as string, alt: file.name },
        }
        setFrame((prev) => ({
          ...prev,
          layers: prev.layers.map((l, i) => (i === 0 ? { ...l, objects: [...l.objects, obj] } : l)),
        }))
        setSelectedIds([id])
      }).catch(() => {
        // ignore upload errors in UI for now
      })
    }
    reader.readAsArrayBuffer(file)
  }, [])

  const addButton = useCallback(() => {
    const id = `button-${buttonCounter++}`
    const obj: WObject = { id, type: 'button', x: 60, y: 240, width: 120, height: 36, rotate: 0, zIndex: 0, props: { label: 'Button', href: '#', color: '#ffffff', background: '#2563eb' } }
    setFrame((prev) => ({
      ...prev,
      layers: prev.layers.map((l, i) => i === 0 ? { ...l, objects: [...l.objects, obj] } : l),
    }))
    setSelectedIds([id])
  }, [])

  const onChangeObject = useCallback((next: WObject) => {
    setFrame((prev) => ({
      ...prev,
      layers: prev.layers.map((l) => ({
        ...l,
        objects: l.objects.map((o) => (o.id === next.id ? (next as WObject) : o)),
      })),
    }))
  }, [])

  const doExport = useCallback(async () => {
    const out = exportFrame(frame)
    const am = assetManagerRef.current ?? new AssetManager({ maxBytes: 10 * 1024 * 1024, allowedExts: ['png','jpg','jpeg','webp','svg','woff2','txt'], pathStrategy: 'grouped' })
    assetManagerRef.current = am
    const extras: Record<string, Uint8Array> = {
      'assets.json': buildAssetsMetadata(am),
      'assets.index.json': buildAssetsIndex(am),
      'assets.integrity.index.json': buildAssetsIntegrityIndex(am),
    }
    const assets = am.toZipStructure()
    const zip = await buildZip({ html: out.html, css: out.css, js: out.js, assets, extras })
    download('landing.zip', zip)
  }, [frame])

  return (
    <div className="p-4 grid grid-cols-[260px_1fr_320px] gap-4">
      <div className="space-y-3">
        <div className="flex gap-2 items-center">
          <button type="button" className="bg-gray-200 rounded px-3 py-2" onClick={addText}>Add Text</button>
          <button type="button" className="bg-gray-200 rounded px-3 py-2" onClick={addImage}>Add Image</button>
          <input
            type="file"
            accept="image/png,image/jpeg,image/jpg,image/webp,image/svg+xml"
            data-testid="wysiwyg-image-input"
            onChange={onUploadImage}
          />
        </div>
        <div>
          <button type="button" className="bg-gray-200 rounded px-3 py-2" onClick={addButton}>Add Button</button>
        </div>
        <div className="border rounded p-2">
          <LayersPanel frame={frame} onChange={setFrame} />
        </div>
      </div>
      <div className="space-y-3">
        <div className="flex items-center justify-between">
          <h1 className="text-xl font-semibold">WYSIWYG Builder</h1>
          <button type="button" className="bg-emerald-600 text-white rounded px-4 py-2" onClick={doExport}>Export</button>
        </div>
        <div className="border rounded p-2 inline-block" style={{ background: '#111111' }}>
          <Canvas frame={frame} onChange={onChangeFrame} onSelectIds={onSelectIds} />
        </div>
      </div>
      <div className="border rounded p-2">
        <h2 className="text-sm font-semibold mb-2">Properties</h2>
        {selectedObject ? (
          <PropsPanel object={selectedObject} onChange={onChangeObject} />
        ) : (
          <p className="text-sm text-gray-500">Select an object to edit</p>
        )}
      </div>
    </div>
  )
}

export default WysiwygBuilderPage
