import { useState, useRef, useEffect } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { Pencil, Trash2, Plus, Check, X, ChevronDown } from 'lucide-react'
import { toast } from 'sonner'
import {
  listOutputTypes, createOutputType, updateOutputType, deleteOutputType,
} from '../../api/outputTypes'
import type { OutputType } from '../../api/outputTypes'
import { listPricingTiers } from '../../api/pricing'
import type { PricingTier } from '../../api/pricing'
import { getWorkflows } from '../../api/workflows'
import type { WorkflowDefinition } from '../../api/workflows'

const RENDERERS = ['blender', 'pillow']
const FORMATS = ['png', 'jpg', 'gltf', 'stl', 'mp4', 'webm']
const ALL_CATEGORIES = [
  { key: 'TRB', label: 'TRB' },
  { key: 'Kugellager', label: 'Kugellager' },
  { key: 'CRB', label: 'CRB' },
  { key: 'Gleitlager', label: 'Gleitlager' },
  { key: 'SRB_TORB', label: 'SRB/TORB' },
  { key: 'Linear_schiene', label: 'Linear' },
  { key: 'Anschlagplatten', label: 'Anschlag' },
]
const EMPTY_FORM ={ name: '', description: '', renderer: 'threejs', output_format: 'png', sort_order: 0, compatible_categories: [] as string[], render_backend: 'auto', is_animation: false, transparent_bg: false, cycles_device: '' as string, pricing_tier_id: null as number | null, width: '', height: '', engine: '', samples: '', frame_count: '', fps: '', turntable_axis: 'world_z', bg_color: '', noise_threshold: '', denoiser: '', denoising_input_passes: '', denoising_prefilter: '', denoising_quality: '', denoising_use_gpu: '' }

export default function OutputTypeTable() {
  const qc = useQueryClient()
  const [showAdd, setShowAdd] = useState(false)
  const [form, setForm] = useState(EMPTY_FORM)
  const [editingId, setEditingId] = useState<string | null>(null)
  const [editDraft, setEditDraft] = useState<Partial<OutputType>>({})

  const { data: types, isLoading } = useQuery({
    queryKey: ['output-types-admin'],
    queryFn: () => listOutputTypes(true),
  })

  const { data: pricingTiers } = useQuery({
    queryKey: ['pricing-tiers'],
    queryFn: listPricingTiers,
  })

  const { data: workflows } = useQuery({
    queryKey: ['workflows'],
    queryFn: getWorkflows,
  })

  const updateWorkflowMut = useMutation({
    mutationFn: ({ id, workflow_definition_id }: { id: string; workflow_definition_id: string | null }) =>
      updateOutputType(id, { workflow_definition_id }),
    onSuccess: () => {
      toast.success('Workflow updated')
      qc.invalidateQueries({ queryKey: ['output-types-admin'] })
      qc.invalidateQueries({ queryKey: ['output-types'] })
    },
    onError: (e: any) => toast.error(e.response?.data?.detail || 'Failed to update workflow'),
  })

  const createMut = useMutation({
    mutationFn: () => {
      const rs: Record<string, unknown> = {}
      if (form.width) rs.width = Number(form.width)
      if (form.height) rs.height = Number(form.height)
      if (form.engine) rs.engine = form.engine
      if (form.samples) rs.samples = Number(form.samples)
      if (form.is_animation) {
        if (form.frame_count) rs.frame_count = Number(form.frame_count)
        if (form.fps) rs.fps = Number(form.fps)
        if (form.turntable_axis) rs.turntable_axis = form.turntable_axis
        if (form.bg_color) rs.bg_color = form.bg_color
      }
      if (form.noise_threshold) rs.noise_threshold = form.noise_threshold
      if (form.denoiser) rs.denoiser = form.denoiser
      if (form.denoising_input_passes) rs.denoising_input_passes = form.denoising_input_passes
      if (form.denoising_prefilter) rs.denoising_prefilter = form.denoising_prefilter
      if (form.denoising_quality) rs.denoising_quality = form.denoising_quality
      if (form.denoising_use_gpu) rs.denoising_use_gpu = form.denoising_use_gpu
      return createOutputType({
        name: form.name.trim(),
        description: form.description.trim() || undefined,
        renderer: form.renderer,
        output_format: form.output_format,
        sort_order: Number(form.sort_order),
        compatible_categories: form.compatible_categories,
        render_backend: form.render_backend,
        is_animation: form.is_animation,
        transparent_bg: form.transparent_bg,
        cycles_device: form.cycles_device || null,
        pricing_tier_id: form.pricing_tier_id,
        render_settings: Object.keys(rs).length > 0 ? rs : {},
      })
    },
    onSuccess: () => {
      toast.success('Output type created')
      qc.invalidateQueries({ queryKey: ['output-types-admin'] })
      qc.invalidateQueries({ queryKey: ['output-types'] })
      setForm(EMPTY_FORM)
      setShowAdd(false)
    },
    onError: (e: any) => toast.error(e.response?.data?.detail || 'Failed to create output type'),
  })

  const updateMut = useMutation({
    mutationFn: ({ id, data }: { id: string; data: Partial<OutputType> & { _width?: string; _height?: string; _engine?: string; _samples?: string; _frame_count?: string; _fps?: string; _turntable_axis?: string; _bg_color?: string; _noise_threshold?: string; _denoiser?: string; _denoising_input_passes?: string; _denoising_prefilter?: string; _denoising_quality?: string; _denoising_use_gpu?: string } }) => {
      const { _width, _height, _engine, _samples, _frame_count, _fps, _turntable_axis, _bg_color, _noise_threshold, _denoiser, _denoising_input_passes, _denoising_prefilter, _denoising_quality, _denoising_use_gpu, ...rest } = data
      if (_width !== undefined || _height !== undefined || _engine !== undefined || _samples !== undefined || _frame_count !== undefined || _fps !== undefined || _turntable_axis !== undefined || _bg_color !== undefined || _noise_threshold !== undefined || _denoiser !== undefined || _denoising_input_passes !== undefined || _denoising_prefilter !== undefined || _denoising_quality !== undefined || _denoising_use_gpu !== undefined) {
        const ot = types?.find((t) => t.id === id)
        const existing = ot?.render_settings || {}
        const rs = { ...existing }
        if (_width !== undefined) {
          if (_width) rs.width = Number(_width); else delete rs.width
        }
        if (_height !== undefined) {
          if (_height) rs.height = Number(_height); else delete rs.height
        }
        if (_engine !== undefined) {
          if (_engine) rs.engine = _engine; else delete rs.engine
        }
        if (_samples !== undefined) {
          if (_samples) rs.samples = Number(_samples); else delete rs.samples
        }
        if (_frame_count !== undefined) {
          if (_frame_count) rs.frame_count = Number(_frame_count); else delete rs.frame_count
        }
        if (_fps !== undefined) {
          if (_fps) rs.fps = Number(_fps); else delete rs.fps
        }
        if (_turntable_axis !== undefined) {
          if (_turntable_axis) rs.turntable_axis = _turntable_axis; else delete rs.turntable_axis
        }
        if (_bg_color !== undefined) {
          if (_bg_color) rs.bg_color = _bg_color; else delete rs.bg_color
        }
        if (_noise_threshold !== undefined) {
          if (_noise_threshold) rs.noise_threshold = _noise_threshold; else delete rs.noise_threshold
        }
        if (_denoiser !== undefined) {
          if (_denoiser) rs.denoiser = _denoiser; else delete rs.denoiser
        }
        if (_denoising_input_passes !== undefined) {
          if (_denoising_input_passes) rs.denoising_input_passes = _denoising_input_passes; else delete rs.denoising_input_passes
        }
        if (_denoising_prefilter !== undefined) {
          if (_denoising_prefilter) rs.denoising_prefilter = _denoising_prefilter; else delete rs.denoising_prefilter
        }
        if (_denoising_quality !== undefined) {
          if (_denoising_quality) rs.denoising_quality = _denoising_quality; else delete rs.denoising_quality
        }
        if (_denoising_use_gpu !== undefined) {
          if (_denoising_use_gpu) rs.denoising_use_gpu = _denoising_use_gpu; else delete rs.denoising_use_gpu
        }
        rest.render_settings = rs
      }
      return updateOutputType(id, rest)
    },
    onSuccess: () => {
      toast.success('Output type updated')
      qc.invalidateQueries({ queryKey: ['output-types-admin'] })
      qc.invalidateQueries({ queryKey: ['output-types'] })
      setEditingId(null)
      setEditDraft({})
    },
    onError: (e: any) => toast.error(e.response?.data?.detail || 'Failed to update'),
  })

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteOutputType(id),
    onSuccess: () => {
      toast.success('Output type deleted')
      qc.invalidateQueries({ queryKey: ['output-types-admin'] })
      qc.invalidateQueries({ queryKey: ['output-types'] })
    },
    onError: (e: any) => toast.error(e.response?.data?.detail || 'Failed to delete'),
  })

  // Check if transparent_bg / bg_color controls should be visible
  function showTransparentBg(renderer: string, _format: string) {
    return renderer === 'blender'
  }

  // Check if blender-specific engine/samples columns should be visible
  function showBlenderSettings(renderer: string) {
    return renderer === 'blender'
  }

  return (
    <div>
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b border-border-light text-left">
            <th className="px-4 py-2 font-medium text-content-secondary">Name</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Renderer used to produce this output (blender / pillow)">Renderer</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Output file format (jpg, png, mp4, webm)">Format</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Animation — output is a video (mp4/webm turntable)">Anim</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Turntable animation settings: frame count, FPS, and rotation axis (animation output types only)">Turntable</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Transparent Background — render with alpha channel (PNG only; Blender film_transparent)">BG</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Cycles compute device override — auto, gpu, or cpu (Blender/Cycles only)">Device</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Blender render engine override — cycles or eevee (overrides global setting for this output type)">Engine</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Sample count override for this output type (overrides global Cycles/EEVEE sample settings)">Samples</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Cycles denoising settings: denoiser, noise threshold, input passes, prefilter, quality, GPU routing">Denoise</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Compatible product categories — empty means compatible with all categories">Categories</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Output resolution in pixels (width × height); leave empty to use global default">Resolution</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Pricing tier used to calculate the per-item cost for this output type">Pricing</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Workflow definition assigned to this output type">Workflow</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Sort order — lower numbers appear first in the wizard output-type picker">Sort</th>
            <th className="px-4 py-2 font-medium text-content-secondary" title="Active — inactive types are hidden from the order wizard">Active</th>
            <th className="px-4 py-2 font-medium text-content-secondary">Actions</th>
          </tr>
        </thead>
        <tbody>
          {isLoading && (
            <tr>
              <td colSpan={17} className="px-4 py-4 text-center text-content-muted">Loading…</td>
            </tr>
          )}
          {types?.map((ot) => (
            <tr key={ot.id} className="border-b border-border-light hover:bg-surface-hover">
              {editingId === ot.id ? (
                <>
                  <td className="px-4 py-2">
                    <input
                      className="input-sm"
                      value={editDraft.name ?? ot.name}
                      onChange={(e) => setEditDraft({ ...editDraft, name: e.target.value })}
                    />
                  </td>
                  <td className="px-4 py-2">
                    <select
                      className="input-sm"
                      value={editDraft.renderer ?? ot.renderer}
                      onChange={(e) => setEditDraft({ ...editDraft, renderer: e.target.value })}
                    >
                      {RENDERERS.map((r) => <option key={r}>{r}</option>)}
                    </select>
                  </td>
                  <td className="px-4 py-2">
                    <select
                      className="input-sm"
                      value={editDraft.output_format ?? ot.output_format}
                      onChange={(e) => setEditDraft({ ...editDraft, output_format: e.target.value })}
                    >
                      {FORMATS.map((f) => <option key={f}>{f}</option>)}
                    </select>
                  </td>
                  <td className="px-4 py-2">
                    <input
                      type="checkbox"
                      checked={editDraft.is_animation ?? ot.is_animation}
                      onChange={(e) => setEditDraft({ ...editDraft, is_animation: e.target.checked })}
                    />
                  </td>
                  <td className="px-4 py-2">
                    {(editDraft.is_animation ?? ot.is_animation) ? (
                      <div className="flex flex-col gap-1">
                        <div className="flex items-center gap-1">
                          <input
                            type="number" min={1} max={3600}
                            className="input-sm w-16" placeholder="120"
                            value={(editDraft as any)._frame_count ?? (ot.render_settings?.frame_count || '')}
                            onChange={(e) => setEditDraft({ ...editDraft, _frame_count: e.target.value } as any)}
                            title="Frame count"
                          />
                          <span className="text-content-muted text-xs">f</span>
                          <input
                            type="number" min={1} max={120}
                            className="input-sm w-14" placeholder="30"
                            value={(editDraft as any)._fps ?? (ot.render_settings?.fps || '')}
                            onChange={(e) => setEditDraft({ ...editDraft, _fps: e.target.value } as any)}
                            title="FPS"
                          />
                          <span className="text-content-muted text-xs">fps</span>
                        </div>
                        <select
                          className="input-sm"
                          value={(editDraft as any)._turntable_axis ?? (ot.render_settings?.turntable_axis || 'world_z')}
                          onChange={(e) => setEditDraft({ ...editDraft, _turntable_axis: e.target.value } as any)}
                          title="Rotation axis"
                        >
                          <option value="world_z">World Z</option>
                          <option value="world_x">World X</option>
                          <option value="world_y">World Y</option>
                        </select>
                      </div>
                    ) : (
                      <span className="text-content-muted">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {showTransparentBg(editDraft.renderer ?? ot.renderer, editDraft.output_format ?? ot.output_format) ? (
                      <div className="flex flex-col gap-1">
                        <label className="flex items-center gap-1 text-xs text-content-secondary">
                          <input
                            type="checkbox"
                            checked={editDraft.transparent_bg ?? ot.transparent_bg}
                            onChange={(e) => setEditDraft({ ...editDraft, transparent_bg: e.target.checked })}
                            title="Transparent background (PNG alpha)"
                          />
                          alpha
                        </label>
                        {(() => {
                          const cur = (editDraft as any)._bg_color !== undefined
                            ? (editDraft as any)._bg_color as string
                            : (ot.render_settings?.bg_color as string || '')
                          const enabled = cur !== ''
                          return (
                            <>
                              <label className="flex items-center gap-1 text-xs text-content-secondary">
                                <input
                                  type="checkbox"
                                  checked={enabled}
                                  onChange={(e) => setEditDraft({ ...editDraft, _bg_color: e.target.checked ? (cur || '#000000') : '' } as any)}
                                  title="Composite over solid background color"
                                />
                                BG color
                              </label>
                              {enabled && (
                                <div className="flex items-center gap-1">
                                  <input
                                    type="color"
                                    className="w-7 h-6 rounded border border-border-default cursor-pointer p-0"
                                    value={cur}
                                    onChange={(e) => setEditDraft({ ...editDraft, _bg_color: e.target.value } as any)}
                                  />
                                  <input
                                    type="text"
                                    className="input-sm w-20 font-mono text-xs"
                                    placeholder="#rrggbb"
                                    value={cur}
                                    onChange={(e) => setEditDraft({ ...editDraft, _bg_color: e.target.value } as any)}
                                  />
                                </div>
                              )}
                            </>
                          )
                        })()}
                      </div>
                    ) : (
                      <span className="text-content-muted">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {showBlenderSettings(editDraft.renderer ?? ot.renderer) ? (
                      <select
                        className="input-sm"
                        value={editDraft.cycles_device ?? (ot.cycles_device || '')}
                        onChange={(e) => setEditDraft({ ...editDraft, cycles_device: e.target.value || null })}
                      >
                        <option value="">System default</option>
                        <option value="auto">Auto</option>
                        <option value="gpu">GPU</option>
                        <option value="cpu">CPU</option>
                      </select>
                    ) : (
                      <span className="text-content-muted">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {showBlenderSettings(editDraft.renderer ?? ot.renderer) ? (
                      <select
                        className="input-sm"
                        value={(editDraft as any)._engine ?? (ot.render_settings?.engine || '')}
                        onChange={(e) => setEditDraft({ ...editDraft, _engine: e.target.value } as any)}
                      >
                        <option value="">System default</option>
                        <option value="cycles">Cycles</option>
                        <option value="eevee">EEVEE</option>
                      </select>
                    ) : (
                      <span className="text-content-muted">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {showBlenderSettings(editDraft.renderer ?? ot.renderer) ? (
                      <input
                        type="number"
                        min={1}
                        max={4096}
                        className="input-sm w-20"
                        placeholder="default"
                        value={(editDraft as any)._samples ?? (ot.render_settings?.samples || '')}
                        onChange={(e) => setEditDraft({ ...editDraft, _samples: e.target.value } as any)}
                      />
                    ) : (
                      <span className="text-content-muted">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {showBlenderSettings(editDraft.renderer ?? ot.renderer) ? (
                      <div className="flex flex-col gap-1 min-w-[120px]">
                        <select
                          className="input-sm"
                          value={(editDraft as any)._denoiser ?? (ot.render_settings?.denoiser as string || '')}
                          onChange={(e) => setEditDraft({ ...editDraft, _denoiser: e.target.value } as any)}
                          title="Denoiser"
                        >
                          <option value="">Auto</option>
                          <option value="OPTIX">OptiX</option>
                          <option value="OPENIMAGEDENOISE">OIDN</option>
                        </select>
                        <input
                          type="number"
                          step="0.001" min="0.001" max="1"
                          className="input-sm w-20"
                          placeholder="threshold"
                          value={(editDraft as any)._noise_threshold ?? (ot.render_settings?.noise_threshold as string || '')}
                          onChange={(e) => setEditDraft({ ...editDraft, _noise_threshold: e.target.value } as any)}
                          title="Noise threshold (adaptive sampling)"
                        />
                        <select
                          className="input-sm"
                          value={(editDraft as any)._denoising_input_passes ?? (ot.render_settings?.denoising_input_passes as string || '')}
                          onChange={(e) => setEditDraft({ ...editDraft, _denoising_input_passes: e.target.value } as any)}
                          title="Input passes"
                        >
                          <option value="">Default</option>
                          <option value="RGB">RGB</option>
                          <option value="RGB_ALBEDO">RGB+Albedo</option>
                          <option value="RGB_ALBEDO_NORMAL">RGB+Albedo+Normal</option>
                        </select>
                        <select
                          className="input-sm"
                          value={(editDraft as any)._denoising_prefilter ?? (ot.render_settings?.denoising_prefilter as string || '')}
                          onChange={(e) => setEditDraft({ ...editDraft, _denoising_prefilter: e.target.value } as any)}
                          title="Prefilter"
                        >
                          <option value="">Default</option>
                          <option value="NONE">None</option>
                          <option value="FAST">Fast</option>
                          <option value="ACCURATE">Accurate</option>
                        </select>
                        <select
                          className="input-sm"
                          value={(editDraft as any)._denoising_quality ?? (ot.render_settings?.denoising_quality as string || '')}
                          onChange={(e) => setEditDraft({ ...editDraft, _denoising_quality: e.target.value } as any)}
                          title="Quality (Blender 4.2+)"
                        >
                          <option value="">Default</option>
                          <option value="HIGH">High</option>
                          <option value="BALANCED">Balanced</option>
                          <option value="FAST">Fast</option>
                        </select>
                        <select
                          className="input-sm"
                          value={(editDraft as any)._denoising_use_gpu ?? (ot.render_settings?.denoising_use_gpu as string || '')}
                          onChange={(e) => setEditDraft({ ...editDraft, _denoising_use_gpu: e.target.value } as any)}
                          title="OIDN GPU routing"
                        >
                          <option value="">Auto</option>
                          <option value="1">GPU</option>
                          <option value="0">CPU</option>
                        </select>
                      </div>
                    ) : (
                      <span className="text-content-muted">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    <CategoryMultiSelect
                      value={(editDraft.compatible_categories ?? ot.compatible_categories) || []}
                      onChange={(cats) => setEditDraft({ ...editDraft, compatible_categories: cats })}
                    />
                  </td>
                  <td className="px-4 py-2">
                    <div className="flex items-center gap-1">
                      <input
                        type="number"
                        className="input-sm w-16"
                        placeholder="W"
                        value={(editDraft as any)._width ?? (ot.render_settings?.width || '')}
                        onChange={(e) => setEditDraft({ ...editDraft, _width: e.target.value } as any)}
                      />
                      <span className="text-content-muted text-xs">x</span>
                      <input
                        type="number"
                        className="input-sm w-16"
                        placeholder="H"
                        value={(editDraft as any)._height ?? (ot.render_settings?.height || '')}
                        onChange={(e) => setEditDraft({ ...editDraft, _height: e.target.value } as any)}
                      />
                    </div>
                  </td>
                  <td className="px-4 py-2">
                    <select
                      className="input-sm"
                      value={editDraft.pricing_tier_id ?? ot.pricing_tier_id ?? ''}
                      onChange={(e) => setEditDraft({ ...editDraft, pricing_tier_id: e.target.value ? Number(e.target.value) : null })}
                    >
                      <option value="">Category default</option>
                      {pricingTiers?.map((t) => (
                        <option key={t.id} value={t.id}>
                          {t.category_key}/{t.quality_level} — {t.price_per_item.toFixed(2)}
                        </option>
                      ))}
                    </select>
                  </td>
                  <td className="px-4 py-2">
                    <select
                      className="input-sm"
                      value={editDraft.workflow_definition_id ?? ot.workflow_definition_id ?? ''}
                      onChange={(e) => setEditDraft({ ...editDraft, workflow_definition_id: e.target.value || null })}
                    >
                      <option value="">— Legacy —</option>
                      {workflows?.filter((w) => w.is_active).map((w) => (
                        <option key={w.id} value={w.id}>{w.name}</option>
                      ))}
                    </select>
                  </td>
                  <td className="px-4 py-2">
                    <input
                      type="number"
                      className="input-sm w-16"
                      value={editDraft.sort_order ?? ot.sort_order}
                      onChange={(e) => setEditDraft({ ...editDraft, sort_order: Number(e.target.value) })}
                    />
                  </td>
                  <td className="px-4 py-2">
                    <input
                      type="checkbox"
                      checked={editDraft.is_active ?? ot.is_active}
                      onChange={(e) => setEditDraft({ ...editDraft, is_active: e.target.checked })}
                    />
                  </td>
                  <td className="px-4 py-2 flex items-center gap-2">
                    <button
                      className="btn-icon text-status-success-text"
                      onClick={() => updateMut.mutate({ id: ot.id, data: editDraft })}
                      title="Save changes"
                    >
                      <Check size={15} />
                    </button>
                    <button
                      className="btn-icon text-content-muted"
                      onClick={() => { setEditingId(null); setEditDraft({}) }}
                      title="Cancel editing"
                    >
                      <X size={15} />
                    </button>
                  </td>
                </>
              ) : (
                <>
                  <td className="px-4 py-2 font-medium">{ot.name}</td>
                  <td className="px-4 py-2 text-content-muted">{ot.renderer}</td>
                  <td className="px-4 py-2 text-content-muted">{ot.output_format}</td>
                  <td className="px-4 py-2">
                    {ot.is_animation && (
                      <span className="text-xs px-1.5 py-0.5 rounded bg-purple-50 text-purple-700">video</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {ot.is_animation ? (
                      <div className="flex flex-col gap-0.5">
                        <span className="text-xs text-content-secondary">
                          {(ot.render_settings?.frame_count as number) || 120}f / {(ot.render_settings?.fps as number) || 30}fps
                        </span>
                        <span className="text-xs text-content-muted">
                          360° {({'world_z': 'World Z', 'world_x': 'World X', 'world_y': 'World Y'} as Record<string, string>)[ot.render_settings?.turntable_axis as string] ?? 'World Z'}
                        </span>
                      </div>
                    ) : (
                      <span className="text-content-muted">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {showTransparentBg(ot.renderer, ot.output_format) && (
                      <div className="flex flex-col gap-1">
                        {ot.transparent_bg && (
                          <span className="text-xs px-1.5 py-0.5 rounded bg-sky-50 text-sky-700" title="Transparent background">alpha</span>
                        )}
                        {!!ot.render_settings?.bg_color && (
                          <div className="flex items-center gap-1" title={`BG color: ${ot.render_settings.bg_color}`}>
                            <span
                              className="inline-block w-4 h-4 rounded border border-border-default"
                              style={{ backgroundColor: ot.render_settings.bg_color as string }}
                            />
                            <span className="text-xs text-content-muted font-mono">{ot.render_settings.bg_color as string}</span>
                          </div>
                        )}
                      </div>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {showBlenderSettings(ot.renderer) ? (
                      ot.cycles_device ? (
                        <span className={`text-xs px-1.5 py-0.5 rounded font-medium ${
                          ot.cycles_device === 'gpu' ? 'bg-violet-50 text-violet-700' :
                          ot.cycles_device === 'cpu' ? 'bg-status-warning-bg text-status-warning-text' :
                          'bg-surface-muted text-content-muted'
                        }`}>
                          {ot.cycles_device.toUpperCase()}
                        </span>
                      ) : (
                        <span className="text-xs text-content-muted">system</span>
                      )
                    ) : (
                      <span className="text-content-muted">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {showBlenderSettings(ot.renderer) ? (
                      ot.render_settings?.engine ? (
                        <span className={`text-xs px-1.5 py-0.5 rounded font-medium ${
                          ot.render_settings.engine === 'cycles' ? 'bg-status-success-bg text-status-success-text' : 'bg-status-info-bg text-status-info-text'
                        }`}>
                          {ot.render_settings.engine === 'cycles' ? 'Cycles' : 'EEVEE'}
                        </span>
                      ) : (
                        <span className="text-xs text-content-muted">default</span>
                      )
                    ) : (
                      <span className="text-content-muted">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {showBlenderSettings(ot.renderer) ? (
                      ot.render_settings?.samples ? (
                        <span className="text-xs font-medium text-content-secondary">{ot.render_settings.samples as number}</span>
                      ) : (
                        <span className="text-xs text-content-muted">default</span>
                      )
                    ) : (
                      <span className="text-content-muted">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {showBlenderSettings(ot.renderer) ? (
                      <div className="flex flex-col gap-0.5">
                        {ot.render_settings?.denoiser ? (
                          <span className="text-xs px-1.5 py-0.5 rounded bg-indigo-50 text-indigo-700 font-medium">
                            {ot.render_settings.denoiser === 'OPTIX' ? 'OptiX' : 'OIDN'}
                          </span>
                        ) : null}
                        {ot.render_settings?.noise_threshold ? (
                          <span className="text-xs text-content-muted">t={ot.render_settings.noise_threshold as string}</span>
                        ) : null}
                        {ot.render_settings?.denoising_prefilter ? (
                          <span className="text-xs text-content-muted">{ot.render_settings.denoising_prefilter as string}</span>
                        ) : null}
                        {!ot.render_settings?.denoiser && !ot.render_settings?.noise_threshold && !ot.render_settings?.denoising_prefilter && (
                          <span className="text-xs text-content-muted">default</span>
                        )}
                      </div>
                    ) : (
                      <span className="text-content-muted">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {(!ot.compatible_categories || ot.compatible_categories.length === 0) ? (
                      <span className="text-xs text-content-muted">All</span>
                    ) : (
                      <div className="flex flex-wrap gap-1">
                        {ot.compatible_categories.map((c: string) => (
                          <span key={c} className="text-xs px-1.5 py-0.5 rounded bg-status-info-bg text-status-info-text">
                            {ALL_CATEGORIES.find((ac) => ac.key === c)?.label || c}
                          </span>
                        ))}
                      </div>
                    )}
                  </td>
                  <td className="px-4 py-2 text-content-muted text-xs">
                    {ot.render_settings?.width || ot.render_settings?.height
                      ? `${ot.render_settings.width || '?'}x${ot.render_settings.height || '?'}`
                      : <span className="text-content-muted">default</span>}
                  </td>
                  <td className="px-4 py-2">
                    {ot.pricing_tier_name ? (
                      <div className="flex items-center gap-1">
                        <span className="text-xs text-content-secondary truncate max-w-[80px]" title={ot.pricing_tier_name}>
                          {ot.pricing_tier_name}
                        </span>
                        {ot.price_per_item != null && (
                          <span className="text-xs px-1.5 py-0.5 rounded bg-emerald-50 text-emerald-700 font-medium">
                            {ot.price_per_item.toFixed(2)}
                          </span>
                        )}
                      </div>
                    ) : (
                      <span className="text-xs text-content-muted">Category default</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    {(() => {
                      const wf = workflows?.find((w) => w.id === ot.workflow_definition_id)
                      return wf ? (
                        <span className="text-xs px-2 py-0.5 rounded-full bg-status-success-bg text-status-success-text font-medium">
                          {wf.name}
                        </span>
                      ) : (
                        <span className="text-xs px-2 py-0.5 rounded-full bg-surface-muted text-content-muted">
                          Legacy
                        </span>
                      )
                    })()}
                  </td>
                  <td className="px-4 py-2 text-content-muted">{ot.sort_order}</td>
                  <td className="px-4 py-2">
                    <span className={`text-xs px-2 py-0.5 rounded-full font-medium ${
                      ot.is_active ? 'bg-status-success-bg text-status-success-text' : 'bg-surface-muted text-content-muted'
                    }`}>
                      {ot.is_active ? 'active' : 'inactive'}
                    </span>
                  </td>
                  <td className="px-4 py-2 flex items-center gap-2">
                    <button
                      className="btn-icon text-content-muted hover:text-accent"
                      onClick={() => { setEditingId(ot.id); setEditDraft({}) }}
                      title="Edit output type"
                    >
                      <Pencil size={14} />
                    </button>
                    <button
                      className="btn-icon text-content-muted hover:text-red-500"
                      onClick={() => {
                        if (confirm(`Delete output type "${ot.name}"?`)) deleteMut.mutate(ot.id)
                      }}
                      title="Delete output type"
                    >
                      <Trash2 size={14} />
                    </button>
                  </td>
                </>
              )}
            </tr>
          ))}

          {/* Add row */}
          {showAdd && (
            <tr className="border-b border-border-light bg-status-success-bg">
              <td className="px-4 py-2">
                <input
                  className="input-sm"
                  placeholder="e.g. 3D Thumbnail"
                  value={form.name}
                  onChange={(e) => setForm({ ...form, name: e.target.value })}
                />
              </td>
              <td className="px-4 py-2">
                <select
                  className="input-sm"
                  value={form.renderer}
                  onChange={(e) => setForm({ ...form, renderer: e.target.value })}
                >
                  {RENDERERS.map((r) => <option key={r}>{r}</option>)}
                </select>
              </td>
              <td className="px-4 py-2">
                <select
                  className="input-sm"
                  value={form.output_format}
                  onChange={(e) => setForm({ ...form, output_format: e.target.value })}
                >
                  {FORMATS.map((f) => <option key={f}>{f}</option>)}
                </select>
              </td>
              <td className="px-4 py-2">
                <input
                  type="checkbox"
                  checked={form.is_animation}
                  onChange={(e) => setForm({ ...form, is_animation: e.target.checked })}
                />
              </td>
              <td className="px-4 py-2">
                {form.is_animation ? (
                  <div className="flex flex-col gap-1">
                    <div className="flex items-center gap-1">
                      <input
                        type="number" min={1} max={3600}
                        className="input-sm w-16" placeholder="120"
                        value={form.frame_count}
                        onChange={(e) => setForm({ ...form, frame_count: e.target.value })}
                        title="Frame count"
                      />
                      <span className="text-content-muted text-xs">f</span>
                      <input
                        type="number" min={1} max={120}
                        className="input-sm w-14" placeholder="30"
                        value={form.fps}
                        onChange={(e) => setForm({ ...form, fps: e.target.value })}
                        title="FPS"
                      />
                      <span className="text-content-muted text-xs">fps</span>
                    </div>
                    <select
                      className="input-sm"
                      value={form.turntable_axis}
                      onChange={(e) => setForm({ ...form, turntable_axis: e.target.value })}
                      title="Rotation axis"
                    >
                      <option value="world_z">World Z</option>
                      <option value="world_x">World X</option>
                      <option value="world_y">World Y</option>
                    </select>
                  </div>
                ) : (
                  <span className="text-content-muted">—</span>
                )}
              </td>
              <td className="px-4 py-2">
                {showTransparentBg(form.renderer, form.output_format) ? (
                  <div className="flex flex-col gap-1">
                    <label className="flex items-center gap-1 text-xs text-content-secondary">
                      <input
                        type="checkbox"
                        checked={form.transparent_bg}
                        onChange={(e) => setForm({ ...form, transparent_bg: e.target.checked })}
                        title="Transparent background (PNG alpha)"
                      />
                      alpha
                    </label>
                    <label className="flex items-center gap-1 text-xs text-content-secondary">
                      <input
                        type="checkbox"
                        checked={!!form.bg_color}
                        onChange={(e) => setForm({ ...form, bg_color: e.target.checked ? '#000000' : '' })}
                        title="Composite over solid background color"
                      />
                      BG color
                    </label>
                    {form.bg_color && (
                      <div className="flex items-center gap-1">
                        <input
                          type="color"
                          className="w-7 h-6 rounded border border-border-default cursor-pointer p-0"
                          value={form.bg_color}
                          onChange={(e) => setForm({ ...form, bg_color: e.target.value })}
                        />
                        <input
                          type="text"
                          className="input-sm w-20 font-mono text-xs"
                          placeholder="#rrggbb"
                          value={form.bg_color}
                          onChange={(e) => setForm({ ...form, bg_color: e.target.value })}
                        />
                      </div>
                    )}
                  </div>
                ) : (
                  <span className="text-content-muted">—</span>
                )}
              </td>
              <td className="px-4 py-2">
                {showBlenderSettings(form.renderer) ? (
                  <select
                    className="input-sm"
                    value={form.cycles_device}
                    onChange={(e) => setForm({ ...form, cycles_device: e.target.value })}
                  >
                    <option value="">System default</option>
                    <option value="auto">Auto</option>
                    <option value="gpu">GPU</option>
                    <option value="cpu">CPU</option>
                  </select>
                ) : (
                  <span className="text-content-muted">—</span>
                )}
              </td>
              <td className="px-4 py-2">
                {showBlenderSettings(form.renderer) ? (
                  <select
                    className="input-sm"
                    value={form.engine}
                    onChange={(e) => setForm({ ...form, engine: e.target.value })}
                  >
                    <option value="">System default</option>
                    <option value="cycles">Cycles</option>
                    <option value="eevee">EEVEE</option>
                  </select>
                ) : (
                  <span className="text-content-muted">—</span>
                )}
              </td>
              <td className="px-4 py-2">
                {showBlenderSettings(form.renderer) ? (
                  <input
                    type="number"
                    min={1}
                    max={4096}
                    className="input-sm w-20"
                    placeholder="default"
                    value={form.samples}
                    onChange={(e) => setForm({ ...form, samples: e.target.value })}
                  />
                ) : (
                  <span className="text-content-muted">—</span>
                )}
              </td>
              <td className="px-4 py-2">
                {showBlenderSettings(form.renderer) ? (
                  <div className="flex flex-col gap-1 min-w-[120px]">
                    <select
                      className="input-sm"
                      value={form.denoiser}
                      onChange={(e) => setForm({ ...form, denoiser: e.target.value })}
                      title="Denoiser"
                    >
                      <option value="">Auto</option>
                      <option value="OPTIX">OptiX</option>
                      <option value="OPENIMAGEDENOISE">OIDN</option>
                    </select>
                    <input
                      type="number"
                      step="0.001" min="0.001" max="1"
                      className="input-sm w-20"
                      placeholder="threshold"
                      value={form.noise_threshold}
                      onChange={(e) => setForm({ ...form, noise_threshold: e.target.value })}
                      title="Noise threshold (adaptive sampling)"
                    />
                    <select
                      className="input-sm"
                      value={form.denoising_input_passes}
                      onChange={(e) => setForm({ ...form, denoising_input_passes: e.target.value })}
                      title="Input passes"
                    >
                      <option value="">Default</option>
                      <option value="RGB">RGB</option>
                      <option value="RGB_ALBEDO">RGB+Albedo</option>
                      <option value="RGB_ALBEDO_NORMAL">RGB+Albedo+Normal</option>
                    </select>
                    <select
                      className="input-sm"
                      value={form.denoising_prefilter}
                      onChange={(e) => setForm({ ...form, denoising_prefilter: e.target.value })}
                      title="Prefilter"
                    >
                      <option value="">Default</option>
                      <option value="NONE">None</option>
                      <option value="FAST">Fast</option>
                      <option value="ACCURATE">Accurate</option>
                    </select>
                    <select
                      className="input-sm"
                      value={form.denoising_quality}
                      onChange={(e) => setForm({ ...form, denoising_quality: e.target.value })}
                      title="Quality (Blender 4.2+)"
                    >
                      <option value="">Default</option>
                      <option value="HIGH">High</option>
                      <option value="BALANCED">Balanced</option>
                      <option value="FAST">Fast</option>
                    </select>
                    <select
                      className="input-sm"
                      value={form.denoising_use_gpu}
                      onChange={(e) => setForm({ ...form, denoising_use_gpu: e.target.value })}
                      title="OIDN GPU routing"
                    >
                      <option value="">Auto</option>
                      <option value="1">GPU</option>
                      <option value="0">CPU</option>
                    </select>
                  </div>
                ) : (
                  <span className="text-content-muted">—</span>
                )}
              </td>
              <td className="px-4 py-2">
                <CategoryMultiSelect
                  value={form.compatible_categories}
                  onChange={(cats) => setForm({ ...form, compatible_categories: cats })}
                />
              </td>
              <td className="px-4 py-2">
                <div className="flex items-center gap-1">
                  <input
                    type="number"
                    className="input-sm w-16"
                    placeholder="W"
                    value={form.width}
                    onChange={(e) => setForm({ ...form, width: e.target.value })}
                  />
                  <span className="text-content-muted text-xs">x</span>
                  <input
                    type="number"
                    className="input-sm w-16"
                    placeholder="H"
                    value={form.height}
                    onChange={(e) => setForm({ ...form, height: e.target.value })}
                  />
                </div>
              </td>
              <td className="px-4 py-2">
                <select
                  className="input-sm"
                  value={form.pricing_tier_id ?? ''}
                  onChange={(e) => setForm({ ...form, pricing_tier_id: e.target.value ? Number(e.target.value) : null })}
                >
                  <option value="">Category default</option>
                  {pricingTiers?.map((t) => (
                    <option key={t.id} value={t.id}>
                      {t.category_key}/{t.quality_level} — {t.price_per_item.toFixed(2)}
                    </option>
                  ))}
                </select>
              </td>
              <td className="px-4 py-2 text-content-muted">—</td>
              <td className="px-4 py-2">
                <input
                  type="number"
                  className="input-sm w-16"
                  value={form.sort_order}
                  onChange={(e) => setForm({ ...form, sort_order: Number(e.target.value) })}
                />
              </td>
              <td className="px-4 py-2 text-content-muted">—</td>
              <td className="px-4 py-2 flex items-center gap-2">
                <button
                  className="btn-icon text-status-success-text"
                  disabled={!form.name.trim() || createMut.isPending}
                  onClick={() => createMut.mutate()}
                  title="Save new output type"
                >
                  <Check size={15} />
                </button>
                <button
                  className="btn-icon text-content-muted"
                  onClick={() => { setShowAdd(false); setForm(EMPTY_FORM) }}
                  title="Cancel adding"
                >
                  <X size={15} />
                </button>
              </td>
            </tr>
          )}
        </tbody>
      </table>

      {!showAdd && (
        <div className="px-4 py-3">
          <button
            className="btn-secondary text-sm"
            onClick={() => setShowAdd(true)}
          >
            <Plus size={14} /> Add Output Type
          </button>
        </div>
      )}
    </div>
  )
}


function CategoryMultiSelect({
  value,
  onChange,
}: {
  value: string[]
  onChange: (cats: string[]) => void
}) {
  const [open, setOpen] = useState(false)
  const ref = useRef<HTMLDivElement>(null)

  useEffect(() => {
    function handleClick(e: MouseEvent) {
      if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)
    }
    document.addEventListener('mousedown', handleClick)
    return () => document.removeEventListener('mousedown', handleClick)
  }, [])

  function toggle(key: string) {
    if (value.includes(key)) {
      onChange(value.filter((k) => k !== key))
    } else {
      onChange([...value, key])
    }
  }

  return (
    <div className="relative" ref={ref}>
      <button
        type="button"
        onClick={() => setOpen(!open)}
        className="input-sm flex items-center gap-1 min-w-[100px] text-left"
      >
        <span className="flex-1 truncate text-xs">
          {value.length === 0 ? 'All' : value.map((k) => ALL_CATEGORIES.find((c) => c.key === k)?.label || k).join(', ')}
        </span>
        <ChevronDown size={12} className="text-content-muted shrink-0" />
      </button>
      {open && (
        <div className="absolute z-50 mt-1 left-0 bg-surface border border-border-default rounded-lg shadow-lg py-1 min-w-[160px]">
          {ALL_CATEGORIES.map((cat) => (
            <label
              key={cat.key}
              className="flex items-center gap-2 px-3 py-1.5 hover:bg-surface-hover cursor-pointer text-xs"
            >
              <input
                type="checkbox"
                checked={value.includes(cat.key)}
                onChange={() => toggle(cat.key)}
                className=""
              />
              {cat.label}
            </label>
          ))}
          {value.length > 0 && (
            <button
              type="button"
              onClick={() => onChange([])}
              className="w-full text-left px-3 py-1.5 text-xs text-content-muted hover:text-content-secondary border-t border-border-light"
            >
              Clear (= All)
            </button>
          )}
        </div>
      )}
    </div>
  )
}
