import { useEffect, useRef } from 'react'
import type { BuiltinPhantom } from '../phantom/builtins.ts'
import type { Phantom } from '../phantom/phantomTypes.ts'
import { phantomExtent } from '../phantom/phantomTypes.ts'

function PhantomPreview({ phantom }: { phantom: Phantom }) {
  const ref = useRef<HTMLCanvasElement>(null)
  useEffect(() => {
    const canvas = ref.current
    if (!canvas) return
    const ctx = canvas.getContext('2d')
    if (!ctx) return
    const W = canvas.width
    const H = canvas.height
    ctx.clearRect(0, 0, W, H)
    const ext = phantomExtent(phantom)
    const span = Math.max(ext.max[0] - ext.min[0], ext.max[1] - ext.min[1], 1e-6) * 1.15
    const cx = (ext.min[0] + ext.max[0]) / 2
    const cy = (ext.min[1] + ext.max[1]) / 2
    const scale = Math.min(W, H) / span
    // Depth shading by z so the 3-D shape reads.
    const zmin = ext.min[2]
    const zmax = ext.max[2]
    const zrange = zmax - zmin || 1
    ctx.globalCompositeOperation = 'lighter'
    for (let i = 0; i < phantom.ns; i++) {
      const px = W / 2 + (phantom.x[i] - cx) * scale
      const py = H / 2 - (phantom.y[i] - cy) * scale
      const zt = (phantom.z[i] - zmin) / zrange
      const shade = Math.round(60 + 150 * zt)
      ctx.fillStyle = `rgba(${Math.round(shade * 0.35)}, ${shade}, ${Math.round(shade * 0.9)}, 0.5)`
      ctx.fillRect(px - 1, py - 1, 2, 2)
    }
    ctx.globalCompositeOperation = 'source-over'
  }, [phantom])
  return <canvas ref={ref} width={220} height={220} className="phantom-preview" />
}

export function PhantomPanel({
  builtins,
  selectedId,
  onSelect,
  phantom,
  loading,
}: {
  builtins: BuiltinPhantom[]
  selectedId: string
  onSelect: (id: string) => void
  phantom: Phantom | null
  loading: boolean
}) {
  return (
    <section className="panel">
      <div className="panel-head">
        <h2>Phantom</h2>
      </div>
      <div className="phantom-options">
        {builtins.map((b) => (
          <label key={b.id} className={`phantom-option${b.id === selectedId ? ' selected' : ''}`}>
            <input type="radio" name="phantom" checked={b.id === selectedId} onChange={() => onSelect(b.id)} />
            <span className="phantom-label">{b.label}</span>
            <span className="phantom-desc">{b.description}</span>
          </label>
        ))}
      </div>
      <div className="phantom-preview-wrap">
        {loading && <div className="muted">Loading phantom…</div>}
        {!loading && phantom && <PhantomPreview phantom={phantom} />}
        {!loading && phantom && (
          <div className="phantom-stats">
            <div>
              <strong>{phantom.ns.toLocaleString()}</strong> spins
            </div>
            <div>
              T1 {(phantom.t1[0] * 1000).toFixed(0)} ms · T2 {(phantom.t2[0] * 1000).toFixed(0)} ms
            </div>
            <div className="muted">XY projection, shaded by z</div>
          </div>
        )}
      </div>
      <p className="muted small">
        <code>.phantom</code> format. A single water-like tissue, densely and uniformly sampled.
      </p>
    </section>
  )
}
