import { BitbybitGeometryRuntime } from './facade/geometryRuntime'
import type { ShapeHandle } from './facade/types'

type PrimitiveEvidence = { name: string; meshVertices: number; meshTriangles: number; volume?: number; length?: number }
type PrimitiveReport = { schemaVersion: 1; status: 'pass' | 'failed'; browserId: 'chrome'; operations: PrimitiveEvidence[]; beforeRelease: { shapeCount: number; kernelReferenceCount: number }; afterRelease: { shapeCount: number; kernelReferenceCount: number }; opfs?: { markerSuite: string; markerOperations: number; markerRemoved: boolean }; error?: string }

const status = (message: string) => { document.querySelector('#status')!.textContent = message }

const run = async (): Promise<PrimitiveReport> => {
  const runtime = new BitbybitGeometryRuntime()
  const context = { documentId: 'chrome-part-primitives', documentVersion: 1 }
  const owned: ShapeHandle[] = []
  const operations: PrimitiveEvidence[] = []
  try {
    const capabilities = await runtime.initialize()
    if (capabilities.status !== 'ready') throw new Error(capabilities.reason || `Bitbybit runtime status is ${capabilities.status}.`)
    const capture = async (name: string, shape: ShapeHandle, includeMass = true, requireMesh = true) => {
      if (!requireMesh) {
        const length = await runtime.linearLength(shape)
        if (!(length > 0)) throw new Error(`${name} returned a zero-length wire.`)
        operations.push({ name, meshVertices: 0, meshTriangles: 0, length })
        return
      }
      let mesh
      try { mesh = await runtime.mesh(shape) } catch (error) { throw new Error(`${name}: ${error instanceof Error ? error.message : String(error)}`) }
      if (mesh.positions.length < 9 || mesh.indices.length < 3) throw new Error(`${name} returned an empty mesh.`)
      const mass = includeMass ? await runtime.massProperties(shape) : undefined
      operations.push({ name, meshVertices: mesh.positions.length / 3, meshTriangles: mesh.indices.length / 3, ...(mass ? { volume: mass.volume } : {}) })
    }
    const ellipsoid = await runtime.createEllipsoid({ ...context, radius1: 2, radius2: 3, radius3: 4 })
    owned.push(ellipsoid); await capture('ellipsoid', ellipsoid)
    const torus = await runtime.createTorus({ ...context, majorRadius: 5, minorRadius: 1, angle: 360 })
    owned.push(torus); await capture('torus', torus)
    const prism = await runtime.createPrism({ ...context, polygon: 6, circumradius: 2, height: 4 })
    owned.push(prism); await capture('prism', prism)
    const wedge = await runtime.createWedge({ ...context, xmin: 0, ymin: 0, zmin: 0, z2min: 0, x2min: 0, xmax: 4, ymax: 5, zmax: 6, z2max: 6, x2max: 4 })
    owned.push(wedge); await capture('wedge', wedge)
    const helix = await runtime.createHelix({ ...context, radius: 2, pitch: 3, height: 6 })
    owned.push(helix); await capture('helix', helix, false, false)
    const markerDirectory = await navigator.storage.getDirectory()
    const markerName = 'part-primitives-chrome-marker.json'
    const marker = await markerDirectory.getFileHandle(markerName, { create: true })
    const writable = await marker.createWritable()
    await writable.write(JSON.stringify({ suite: 'PART-ALL', operations: operations.length }))
    await writable.close()
    const markerPayload = JSON.parse(await (await marker.getFile()).text())
    await markerDirectory.removeEntry(markerName)
    let markerRemoved = false
    try { await markerDirectory.getFileHandle(markerName) } catch (error) { markerRemoved = error instanceof DOMException && error.name === 'NotFoundError' }
    const beforeRelease = { shapeCount: runtime.capabilities().shapeCount, kernelReferenceCount: runtime.capabilities().kernelReferenceCount }
    await Promise.all(owned.map((shape) => runtime.release(shape)))
    const afterRelease = { shapeCount: runtime.capabilities().shapeCount, kernelReferenceCount: runtime.capabilities().kernelReferenceCount }
    runtime.dispose()
    if (afterRelease.shapeCount !== 0 || afterRelease.kernelReferenceCount !== 0) throw new Error(`Part primitive ownership gate failed: ${JSON.stringify(afterRelease)}`)
    return { schemaVersion: 1, status: capabilities.status === 'ready' && operations.length === 5 && markerPayload.suite === 'PART-ALL' && markerPayload.operations === 5 && markerRemoved ? 'pass' : 'failed', browserId: 'chrome', operations, beforeRelease, afterRelease, opfs: { markerSuite: markerPayload.suite, markerOperations: markerPayload.operations, markerRemoved } }
  } catch (error) {
    const beforeRelease = { shapeCount: runtime.capabilities().shapeCount, kernelReferenceCount: runtime.capabilities().kernelReferenceCount }
    await Promise.all(owned.map((shape) => runtime.release(shape).catch(() => {})))
    const afterRelease = { shapeCount: runtime.capabilities().shapeCount, kernelReferenceCount: runtime.capabilities().kernelReferenceCount }
    runtime.dispose()
    return { schemaVersion: 1, status: 'failed', browserId: 'chrome', operations, beforeRelease, afterRelease, error: error instanceof Error ? error.message : String(error) }
  }
}

run().then((report) => {
  ;(window as Window & { __bitbybitPartPrimitiveReport?: PrimitiveReport }).__bitbybitPartPrimitiveReport = report
  document.documentElement.dataset.status = report.status
  status(JSON.stringify(report))
}).catch((error) => { document.documentElement.dataset.status = 'failed'; status(error instanceof Error ? error.message : String(error)) })

export {}
