import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { Link, useNavigate } from 'react-router-dom'
import { useState, useMemo, useEffect } from 'react'
import {
  Plus, Package, Trash2, X, Search, SlidersHorizontal,
  LayoutGrid, LayoutList, Calendar, FileSpreadsheet,
  Clock, CheckCircle2, XCircle, Loader2, Send, FilePen,
  ChevronRight, Filter,
} from 'lucide-react'
import { toast } from 'sonner'
import { listOrders, searchOrders, deleteOrder } from '../api/orders'
import { fetchThumbnailBlob } from '../api/cad'
import type { Order, OrderDetail, OrderItem } from '../api/orders'
import ConfirmModal from '../components/ConfirmModal'
// ── Constants ────────────────────────────────────────────────────────────────

const STATUSES = ['draft', 'submitted', 'processing', 'completed', 'rejected'] as const
type Status = typeof STATUSES[number]

const STATUS_META: Record<Status, {
  label: string
  icon: React.ElementType
  header: string
  card: string
  badge: string
  chip: string       // active chip style
  chipInactive: string
}> = {
  draft:      { label: 'Draft',      icon: FilePen,      header: 'bg-gray-500',         card: 'border-l-gray-400',   badge: 'badge-gray',   chip: 'bg-gray-500 text-white border-gray-500',          chipInactive: 'border-border-default text-content-secondary hover:border-gray-400 hover:bg-surface-hover' },
  submitted:  { label: 'Submitted',  icon: Send,         header: 'bg-blue-500',         card: 'border-l-blue-400',   badge: 'badge-blue',   chip: 'bg-blue-500 text-white border-blue-500',          chipInactive: 'border-border-default text-content-secondary hover:border-blue-300 hover:bg-status-info-bg' },
  processing: { label: 'Processing', icon: Loader2,      header: 'bg-amber-500',        card: 'border-l-amber-400',  badge: 'badge-yellow', chip: 'bg-amber-500 text-white border-amber-500',        chipInactive: 'border-border-default text-content-secondary hover:border-amber-300 hover:bg-status-warning-bg' },
  completed:  { label: 'Completed',  icon: CheckCircle2, header: 'bg-green-600',         card: 'border-l-green-500',  badge: 'badge-green',  chip: 'bg-green-600 text-white border-green-600',        chipInactive: 'border-border-default text-content-secondary hover:border-green-300 hover:bg-status-success-bg' },
  rejected:   { label: 'Rejected',   icon: XCircle,      header: 'bg-red-500',          card: 'border-l-red-400',    badge: 'badge-red',    chip: 'bg-red-500 text-white border-red-500',            chipInactive: 'border-border-default text-content-secondary hover:border-red-300 hover:bg-status-error-bg' },
}

const isDeletable = (s: string) =>
  s === 'draft' || s === 'submitted' || s === 'rejected'

// ── Page ─────────────────────────────────────────────────────────────────────

export default function OrdersPage() {
  const navigate = useNavigate()
  const qc = useQueryClient()

  const [view, setView] = useState<'kanban' | 'list'>(() => window.innerWidth < 768 ? 'list' : 'kanban')
  const [searchInput, setSearchInput] = useState('')
  const [debouncedSearch, setDebouncedSearch] = useState('')
  const [selectedStatuses, setSelectedStatuses] = useState<Set<Status>>(new Set())
  const [dateFrom, setDateFrom] = useState('')
  const [dateTo, setDateTo] = useState('')
  const [showFilters, setShowFilters] = useState(false)
  const [selected, setSelected] = useState<Set<string>>(new Set())
  const [confirmState, setConfirmState] = useState<{ open: boolean; title: string; message: string; onConfirm: () => void }>({ open: false, title: '', message: '', onConfirm: () => {} })

  // Auto-switch to list view on narrow screens
  useEffect(() => {
    const handler = () => { if (window.innerWidth < 768) setView('list') }
    window.addEventListener('resize', handler)
    return () => window.removeEventListener('resize', handler)
  }, [])

  // Debounce the search input (400 ms)
  useEffect(() => {
    const t = setTimeout(() => setDebouncedSearch(searchInput.trim()), 400)
    return () => clearTimeout(t)
  }, [searchInput])

  const isSearchMode = debouncedSearch.length > 0

  // Normal orders list
  const { data: orders = [], isLoading: ordersLoading } = useQuery({
    queryKey: ['orders'],
    queryFn: () => listOrders(),
    refetchInterval: 15000,
  })

  // Search results (backend full-text search)
  const { data: searchResults = [], isLoading: searchLoading } = useQuery({
    queryKey: [
      'orders', 'search', debouncedSearch,
      [...selectedStatuses].sort().join(','), dateFrom, dateTo,
    ],
    queryFn: () => searchOrders({
      q: debouncedSearch,
      statuses: selectedStatuses.size > 0 ? [...selectedStatuses] : undefined,
      date_from: dateFrom || undefined,
      date_to: dateTo || undefined,
    }),
    enabled: isSearchMode,
    staleTime: 10_000,
  })

  const isLoading = isSearchMode ? searchLoading : ordersLoading

  // Status chip toggle
  const toggleStatus = (s: Status) =>
    setSelectedStatuses((prev) => {
      const n = new Set(prev)
      n.has(s) ? n.delete(s) : n.add(s)
      return n
    })

  // Client-side filtering for non-search mode
  const filtered = useMemo(() => {
    let result = orders
    if (dateFrom) result = result.filter((o) => o.created_at >= dateFrom)
    if (dateTo)   result = result.filter((o) => o.created_at.slice(0, 10) <= dateTo)
    return result
  }, [orders, dateFrom, dateTo])

  // Kanban grouping
  const byStatus = useMemo(() => {
    const map: Record<Status, Order[]> = {
      draft: [], submitted: [], processing: [], completed: [], rejected: [],
    }
    for (const o of filtered) {
      if (o.status in map) map[o.status as Status].push(o)
    }
    return map
  }, [filtered])

  // Which columns to show in kanban (all if none selected, or only selected)
  const visibleStatuses: Status[] =
    selectedStatuses.size > 0
      ? STATUSES.filter((s) => selectedStatuses.has(s))
      : [...STATUSES]

  const hasDateFilter = !!(dateFrom || dateTo)
  const clearFilters = () => {
    setSelectedStatuses(new Set())
    setDateFrom('')
    setDateTo('')
    setSearchInput('')
  }

  // ── Bulk-delete helpers ──────────────────────────────────────────────────

  const listFiltered = filtered.filter(
    (o) => selectedStatuses.size === 0 || selectedStatuses.has(o.status as Status)
  )
  const deletableFiltered = listFiltered.filter((o) => isDeletable(o.status))
  const allSelected =
    deletableFiltered.length > 0 &&
    deletableFiltered.every((o) => selected.has(o.id))

  const toggleOne = (id: string) =>
    setSelected((prev) => {
      const n = new Set(prev)
      n.has(id) ? n.delete(id) : n.add(id)
      return n
    })

  const toggleAll = () =>
    setSelected(
      allSelected ? new Set() : new Set(deletableFiltered.map((o) => o.id))
    )

  const deleteMut = useMutation({
    mutationFn: async (ids: string[]) => {
      await Promise.all(ids.map((id) => deleteOrder(id)))
    },
    onSuccess: (_, ids) => {
      toast.success(`${ids.length} order${ids.length > 1 ? 's' : ''} deleted`)
      setSelected(new Set())
      qc.invalidateQueries({ queryKey: ['orders'] })
    },
    onError: (e: any) => toast.error(e.response?.data?.detail || 'Delete failed'),
  })

  const handleDeleteSelected = () => {
    const ids = [...selected]
    if (!ids.length) return
    const ordersMap = Object.fromEntries(orders.map((o) => [o.id, o]))
    const submittedCount = ids.filter((id) => ordersMap[id]?.status === 'submitted').length
    const message = submittedCount > 0
      ? `⚠️ ${submittedCount} of ${ids.length} selected order${ids.length > 1 ? 's' : ''} ${submittedCount === 1 ? 'has' : 'have'} been submitted and may be processing. Delete anyway?`
      : `Delete ${ids.length} order${ids.length > 1 ? 's' : ''}? This cannot be undone.`
    setConfirmState({
      open: true,
      title: `Delete ${ids.length} order${ids.length > 1 ? 's' : ''}`,
      message,
      onConfirm: () => {
        deleteMut.mutate(ids)
        setConfirmState((s) => ({ ...s, open: false }))
      },
    })
  }

  // ── Render ───────────────────────────────────────────────────────────────

  return (
    <div className="flex flex-col h-full">
      {/* ── Toolbar ──────────────────────────────────────────────────────── */}
      <div className="px-6 pt-5 pb-4 bg-surface border-b border-border-default shrink-0">

        {/* Row 1: title + view toggle + new order */}
        <div className="flex items-center gap-3 mb-4">
          <h1 className="text-2xl font-bold text-content">Orders</h1>
          <div className="ml-auto flex items-center gap-2">
            <div className="flex border border-border-default rounded-md overflow-hidden">
              <button
                onClick={() => setView('kanban')}
                title="Kanban view"
                className={`px-2.5 py-1.5 text-sm flex items-center transition-colors ${
                  view === 'kanban' ? 'bg-surface-muted text-content' : 'text-content-muted hover:text-content-secondary'
                }`}
              >
                <LayoutGrid size={15} />
              </button>
              <button
                onClick={() => setView('list')}
                title="List view"
                className={`px-2.5 py-1.5 text-sm flex items-center border-l border-border-default transition-colors ${
                  view === 'list' ? 'bg-surface-muted text-content' : 'text-content-muted hover:text-content-secondary'
                }`}
              >
                <LayoutList size={15} />
              </button>
            </div>
            <Link to="/orders/new" className="btn-primary">
              <Plus size={16} /> New Order
            </Link>
          </div>
        </div>

        {/* Row 2: Search bar */}
        <div className="relative mb-3">
          <Search size={15} className="absolute left-3 top-1/2 -translate-y-1/2 text-content-muted pointer-events-none" />
          <input
            type="text"
            placeholder="Search orders, products, bearings, PIM IDs, CAD model names…"
            value={searchInput}
            onChange={(e) => setSearchInput(e.target.value)}
            className="w-full pl-9 pr-9 py-2.5 text-sm border border-border-default rounded-lg
                       bg-surface-alt focus:bg-surface focus:outline-none focus:ring-2
                       focus:ring-accent focus:border-transparent transition-colors"
          />
          {searchInput && (
            <button
              onClick={() => setSearchInput('')}
              className="absolute right-3 top-1/2 -translate-y-1/2 text-content-muted hover:text-content transition-colors"
              title="Clear search"
            >
              <X size={14} />
            </button>
          )}
        </div>

        {/* Row 3: Status chips + date filter toggle */}
        <div className="flex items-center gap-2 flex-wrap">
          <span className="text-xs font-medium text-content-muted mr-1 shrink-0">
            {isSearchMode ? 'Filter results:' : 'Show:'}
          </span>
          {STATUSES.map((s) => {
            const meta = STATUS_META[s]
            const active = selectedStatuses.has(s)
            const count = byStatus[s]?.length ?? 0
            return (
              <button
                key={s}
                onClick={() => toggleStatus(s)}
                className={`flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-medium border transition-all ${
                  active ? meta.chip : meta.chipInactive
                }`}
              >
                <meta.icon size={11} className={active ? '' : 'opacity-60'} />
                {meta.label}
                {!isSearchMode && count > 0 && (
                  <span className={`text-[10px] font-bold px-1.5 py-0.5 rounded-full leading-none ${
                    active ? 'bg-white/25 text-white' : 'bg-surface-muted text-content-secondary'
                  }`}>
                    {count}
                  </span>
                )}
              </button>
            )
          })}

          <div className="ml-auto flex items-center gap-2 shrink-0">
            <button
              onClick={() => setShowFilters((v) => !v)}
              className={`flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs border transition-colors ${
                showFilters || hasDateFilter
                  ? 'border-accent bg-accent-light text-accent'
                  : 'border-border-default text-content-secondary hover:border-border-default'
              }`}
            >
              <Filter size={12} />
              Date
              {hasDateFilter && <span className="w-1.5 h-1.5 bg-accent rounded-full ml-0.5" />}
            </button>
            {(selectedStatuses.size > 0 || hasDateFilter || searchInput) && (
              <button
                onClick={clearFilters}
                className="text-xs text-content-muted hover:text-content flex items-center gap-1 transition-colors"
              >
                <X size={11} /> Clear all
              </button>
            )}
          </div>
        </div>

        {/* Date filter panel */}
        {showFilters && (
          <div className="mt-3 flex items-center gap-4 flex-wrap px-3 py-2.5 bg-surface-alt rounded-lg border border-border-default">
            <Calendar size={14} className="text-content-muted shrink-0" />
            <div className="flex items-center gap-2 text-sm">
              <label className="text-content-secondary whitespace-nowrap">From</label>
              <input
                type="date"
                value={dateFrom}
                onChange={(e) => setDateFrom(e.target.value)}
                className="px-2 py-1 border border-border-default rounded text-sm focus:outline-none focus:ring-2 focus:ring-accent"
              />
            </div>
            <div className="flex items-center gap-2 text-sm">
              <label className="text-content-secondary whitespace-nowrap">To</label>
              <input
                type="date"
                value={dateTo}
                onChange={(e) => setDateTo(e.target.value)}
                className="px-2 py-1 border border-border-default rounded text-sm focus:outline-none focus:ring-2 focus:ring-accent"
              />
            </div>
            {hasDateFilter && (
              <button
                onClick={() => { setDateFrom(''); setDateTo('') }}
                className="text-xs text-content-muted hover:text-content-secondary flex items-center gap-1"
              >
                <X size={11} /> Clear dates
              </button>
            )}
          </div>
        )}
      </div>

      {/* ── Content ──────────────────────────────────────────────────────── */}
      {isLoading && !isSearchMode && orders.length === 0 ? (
        view === 'kanban' ? <KanbanSkeleton /> : <ListSkeleton />
      ) : isLoading && isSearchMode ? (
        <div className="flex-1 flex items-center justify-center text-content-muted">
          <Loader2 size={24} className="animate-spin mr-2" />
          Searching…
        </div>
      ) : isSearchMode ? (
        <SearchResultsView
          results={searchResults}
          query={debouncedSearch}
          onNavigate={(id) => navigate(`/orders/${id}`)}
        />
      ) : orders.length === 0 ? (
        <div className="flex-1 flex flex-col items-center justify-center text-center p-12">
          <Package size={48} className="text-content-muted mb-4" />
          <p className="text-content-secondary font-medium mb-1">No orders yet</p>
          <p className="text-content-muted text-sm mb-4">Upload an Excel file to create your first order.</p>
          <Link to="/upload" className="btn-primary">
            <FileSpreadsheet size={16} /> Upload Excel
          </Link>
        </div>
      ) : view === 'kanban' ? (
        <KanbanBoard
          byStatus={byStatus}
          visibleStatuses={visibleStatuses}
          onNavigate={(id) => navigate(`/orders/${id}`)}
        />
      ) : (
        <ListView
          orders={listFiltered}
          selected={selected}
          allSelected={allSelected}
          onToggleOne={toggleOne}
          onToggleAll={toggleAll}
          onNavigate={(id) => navigate(`/orders/${id}`)}
        />
      )}

      <ConfirmModal
        open={confirmState.open}
        title={confirmState.title}
        message={confirmState.message}
        onConfirm={confirmState.onConfirm}
        onCancel={() => setConfirmState((s) => ({ ...s, open: false }))}
      />

      {/* ── Bulk delete bar ───────────────────────────────────────────────── */}
      {selected.size > 0 && (
        <div
          className="fixed bottom-6 z-50 flex items-center gap-3 px-5 py-3 bg-gray-900 text-white rounded-2xl shadow-2xl ring-1 ring-white/10"
          style={{ left: 'calc(240px + (100vw - 240px) / 2)', transform: 'translateX(-50%)' }}
        >
          <span className="text-sm font-medium">
            {selected.size} order{selected.size > 1 ? 's' : ''} selected
          </span>
          <div className="w-px h-5 bg-white/20" />
          <button
            onClick={handleDeleteSelected}
            disabled={deleteMut.isPending}
            className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-red-500
                       hover:bg-red-600 text-sm font-medium transition-colors disabled:opacity-50"
          >
            <Trash2 size={14} />
            {deleteMut.isPending ? 'Deleting…' : 'Delete'}
          </button>
          <button
            onClick={() => setSelected(new Set())}
            className="p-1.5 rounded-lg text-gray-400 hover:text-white transition-colors"
            title="Clear selection"
          >
            <X size={14} />
          </button>
        </div>
      )}
    </div>
  )
}

// ── Skeleton loaders ──────────────────────────────────────────────────────────

function ListSkeleton() {
  return (
    <div className="flex-1 overflow-y-auto">
      <div className="mx-6 my-4 card overflow-hidden animate-pulse">
        <div className="grid grid-cols-[2rem_1fr_6rem_5rem_6rem] bg-surface-alt border-b border-border-default px-4 py-2.5">
          <div className="h-3 w-3 bg-surface-muted rounded" />
          <div className="h-3 w-24 bg-surface-muted rounded" />
          <div className="h-3 w-12 bg-surface-muted rounded" />
          <div className="h-3 w-14 bg-surface-muted rounded" />
          <div className="h-3 w-16 bg-surface-muted rounded" />
        </div>
        <div className="divide-y divide-border-light">
          {Array.from({ length: 5 }, (_, i) => (
            <div key={i} className="grid grid-cols-[2rem_1fr_6rem_5rem_6rem] items-center px-4 py-3 gap-x-4">
              <div className="h-3.5 w-3.5 bg-surface-muted rounded" />
              <div className="space-y-1.5">
                <div className="h-3.5 w-32 bg-surface-muted rounded" />
                <div className="h-2.5 w-48 bg-surface-muted rounded opacity-60" />
              </div>
              <div className="h-3 w-12 bg-surface-muted rounded" />
              <div className="h-5 w-16 bg-surface-muted rounded-full" />
              <div className="h-3 w-14 bg-surface-muted rounded" />
            </div>
          ))}
        </div>
      </div>
    </div>
  )
}

function KanbanSkeleton() {
  return (
    <div className="flex-1 overflow-x-auto min-h-0">
      <div className="flex gap-4 p-6 h-full">
        {['bg-gray-400', 'bg-blue-400', 'bg-amber-400'].map((color, ci) => (
          <div key={ci} className="flex flex-col w-72 min-w-[272px] animate-pulse">
            <div className={`${color} rounded-t-xl px-4 py-3 flex items-center gap-2`}>
              <div className="h-4 w-4 bg-white/40 rounded" />
              <div className="h-3.5 w-20 bg-white/40 rounded" />
              <div className="ml-auto h-5 w-6 bg-white/30 rounded-full" />
            </div>
            <div className="flex-1 bg-surface-muted rounded-b-xl p-2 space-y-2 min-h-[120px]">
              {Array.from({ length: 2 }, (_, i) => (
                <div key={i} className="bg-surface rounded-lg p-3 border border-border-default border-l-4 border-l-border-default">
                  <div className="h-3.5 w-24 bg-surface-muted rounded mb-2" />
                  <div className="flex gap-3">
                    <div className="h-3 w-16 bg-surface-muted rounded" />
                    <div className="h-3 w-20 bg-surface-muted rounded" />
                  </div>
                </div>
              ))}
            </div>
          </div>
        ))}
      </div>
    </div>
  )
}

// ── Search results view ───────────────────────────────────────────────────────

function SearchResultsView({
  results,
  query,
  onNavigate,
}: {
  results: OrderDetail[]
  query: string
  onNavigate: (id: string) => void
}) {
  const totalItems = results.reduce((acc, o) => acc + o.items.length, 0)

  if (results.length === 0) {
    return (
      <div className="flex-1 flex flex-col items-center justify-center text-center p-12">
        <Search size={40} className="text-content-muted mb-4" />
        <p className="text-content-secondary font-medium mb-1">No results for &ldquo;{query}&rdquo;</p>
        <p className="text-content-muted text-sm">
          Try searching by product name, bearing type, PIM ID, Baureihe, or order number.
        </p>
      </div>
    )
  }

  return (
    <div className="flex-1 overflow-y-auto">
      <div className="px-6 py-4">
        <p className="text-sm text-content-secondary mb-4">
          <span className="font-semibold text-content-secondary">{results.length}</span> order{results.length !== 1 ? 's' : ''},&nbsp;
          <span className="font-semibold text-content-secondary">{totalItems}</span> matching item{totalItems !== 1 ? 's' : ''}
        </p>
        <div className="space-y-4">
          {results.map((order) => (
            <SearchOrderCard
              key={order.id}
              order={order}
              query={query}
              onNavigate={() => onNavigate(order.id)}
            />
          ))}
        </div>
      </div>
    </div>
  )
}

function SearchOrderCard({
  order,
  query,
  onNavigate,
}: {
  order: OrderDetail
  query: string
  onNavigate: () => void
}) {
  const meta = STATUS_META[order.status as Status] ?? STATUS_META.draft
  const date = new Date(order.created_at).toLocaleDateString('de-DE', {
    day: '2-digit', month: 'short', year: 'numeric',
  })

  return (
    <div className="card overflow-hidden">
      {/* Order header */}
      <div className={`flex items-center gap-3 px-4 py-3 border-l-4 ${meta.card} bg-surface-alt border-b border-border-light`}>
        <span className="font-bold font-mono text-content">{order.order_number}</span>
        <span className={`badge ${meta.badge}`}>{order.status}</span>
        <span className="text-xs text-content-muted flex items-center gap-1">
          <Clock size={11} /> {date}
        </span>
        <span className="text-xs text-content-secondary">
          {order.items.length} matching item{order.items.length !== 1 ? 's' : ''}
        </span>
        <button
          onClick={onNavigate}
          className="ml-auto text-xs text-accent font-medium hover:underline flex items-center gap-1"
        >
          Open order <ChevronRight size={12} />
        </button>
      </div>

      {/* Matching items */}
      {order.items.length > 0 && (
        <>
          {/* Column headers */}
          <div className="grid grid-cols-[3rem_1fr_1fr_1fr_1fr_1fr] gap-x-4 px-4 py-1.5
                          text-[10px] font-semibold text-content-muted uppercase tracking-wider
                          bg-surface-alt border-b border-border-light">
            <div />
            <div>PIM ID / Level</div>
            <div>Baureihe</div>
            <div>Product</div>
            <div>CAD Model</div>
            <div>Bearing type</div>
          </div>
          <div className="divide-y divide-border-light">
            {order.items.map((item) => (
              <SearchItemRow
                key={item.id}
                item={item}
                query={query}
                onNavigate={onNavigate}
              />
            ))}
          </div>
        </>
      )}
    </div>
  )
}

function Highlight({ text, query }: { text: string | null; query: string }) {
  if (!text) return null
  const idx = text.toLowerCase().indexOf(query.toLowerCase())
  if (idx === -1) return <span>{text}</span>
  return (
    <>
      {text.slice(0, idx)}
      <mark className="bg-yellow-100 text-yellow-900 rounded px-0.5 not-italic">
        {text.slice(idx, idx + query.length)}
      </mark>
      {text.slice(idx + query.length)}
    </>
  )
}

function SearchItemRow({
  item,
  query,
  onNavigate,
}: {
  item: OrderItem
  query: string
  onNavigate: () => void
}) {
  const [thumbUrl, setThumbUrl] = useState<string | null>(null)

  useEffect(() => {
    if (!item.cad_file_id) return
    let revoked = false
    fetchThumbnailBlob(item.cad_file_id).then((url) => {
      if (!revoked) setThumbUrl(url)
    }).catch(() => {})
    return () => {
      revoked = true
      if (thumbUrl) URL.revokeObjectURL(thumbUrl)
    }
  }, [item.cad_file_id])

  return (
    <div
      className="grid grid-cols-[3rem_1fr_1fr_1fr_1fr_1fr] gap-x-4 px-4 py-2.5 items-center
                 hover:bg-surface-hover cursor-pointer transition-colors"
      onClick={onNavigate}
    >
      {/* Thumbnail */}
      <div className="w-10 h-10 rounded bg-surface-muted overflow-hidden flex items-center justify-center shrink-0">
        {thumbUrl ? (
          <img src={thumbUrl} alt="" className="w-full h-full object-cover" />
        ) : (
          <Package size={16} className="text-content-muted" />
        )}
      </div>

      <div className="text-xs min-w-0">
        {item.pim_id && (
          <p className="font-semibold text-content truncate">
            <Highlight text={item.pim_id} query={query} />
          </p>
        )}
        {item.ebene2 && (
          <p className="text-content-muted truncate">
            <Highlight text={item.ebene2} query={query} />
          </p>
        )}
      </div>

      <div className="text-xs text-content-secondary truncate">
        <Highlight text={item.baureihe} query={query} />
      </div>

      <div className="text-xs text-content-secondary truncate">
        <Highlight text={item.gewaehltes_produkt} query={query} />
      </div>

      <div className="text-xs font-mono text-content-secondary truncate">
        <Highlight text={item.name_cad_modell} query={query} />
      </div>

      <div className="text-xs text-content-muted truncate">
        <Highlight text={item.lagertyp} query={query} />
      </div>
    </div>
  )
}

// ── Kanban board ─────────────────────────────────────────────────────────────

function KanbanBoard({
  byStatus,
  visibleStatuses,
  onNavigate,
}: {
  byStatus: Record<Status, Order[]>
  visibleStatuses: Status[]
  onNavigate: (id: string) => void
}) {
  return (
    <div className="flex-1 overflow-x-auto min-h-0">
      <div className="flex gap-4 p-6 h-full min-w-max">
        {visibleStatuses.map((status) => {
          const meta = STATUS_META[status]
          const cards = byStatus[status]
          return (
            <div key={status} className="flex flex-col w-72 min-w-[272px]">
              <div className={`${meta.header} rounded-t-xl px-4 py-3 flex items-center gap-2`}>
                <meta.icon size={16} className="text-white/80 shrink-0" />
                <span className="text-white font-semibold text-sm">{meta.label}</span>
                <span className="ml-auto bg-white/20 text-white text-xs font-bold px-2 py-0.5 rounded-full">
                  {cards.length}
                </span>
              </div>
              <div className="flex-1 bg-surface-muted rounded-b-xl p-2 overflow-y-auto space-y-2 min-h-[120px]">
                {cards.length === 0 ? (
                  <div className="h-20 flex items-center justify-center text-content-muted text-xs">
                    No orders
                  </div>
                ) : (
                  cards.map((order) => (
                    <KanbanCard
                      key={order.id}
                      order={order}
                      meta={meta}
                      onNavigate={() => onNavigate(order.id)}
                    />
                  ))
                )}
              </div>
            </div>
          )
        })}
      </div>
    </div>
  )
}

function RenderProgressBar({ progress }: {
  progress: { total: number; completed: number; processing: number; failed: number; pending: number; cancelled?: number }
}) {
  const { total, completed, processing, failed, pending, cancelled = 0 } = progress
  if (total === 0) return null
  const pct = (n: number) => `${(n / total) * 100}%`
  const allDone = completed === total

  return (
    <div className="mt-2">
      <div className="flex h-1.5 rounded-full overflow-hidden bg-surface-muted">
        {completed > 0 && <div className="bg-green-500 transition-all duration-300" style={{ width: pct(completed) }} />}
        {processing > 0 && <div className="bg-blue-500 transition-all duration-300" style={{ width: pct(processing) }} />}
        {failed > 0 && <div className="bg-red-400 transition-all duration-300" style={{ width: pct(failed) }} />}
        {cancelled > 0 && <div className="bg-orange-300 transition-all duration-300" style={{ width: pct(cancelled) }} />}
        {pending > 0 && <div className="bg-gray-200 transition-all duration-300" style={{ width: pct(pending) }} />}
      </div>
      <p className={`text-[10px] mt-0.5 font-medium ${allDone ? 'text-green-600' : 'text-content-muted'}`}>
        {allDone ? `${total}/${total}` : `Rendered ${completed}/${total}`}
        {failed > 0 && <span className="text-red-400 ml-1">({failed} failed)</span>}
        {cancelled > 0 && <span className="text-orange-400 ml-1">({cancelled} cancelled)</span>}
      </p>
    </div>
  )
}

function KanbanCard({
  order,
  meta,
  onNavigate,
}: {
  order: Order
  meta: typeof STATUS_META[Status]
  onNavigate: () => void
}) {
  const date = new Date(order.created_at).toLocaleDateString('de-DE', {
    day: '2-digit', month: 'short', year: 'numeric',
  })

  const rp = order.render_progress

  return (
    <button
      onClick={onNavigate}
      className={`w-full text-left bg-surface rounded-lg shadow-sm border border-border-default
                  border-l-4 ${meta.card} hover:shadow-md hover:-translate-y-0.5
                  transition-all duration-150 p-3 group`}
    >
      <div className="flex items-start justify-between gap-2 mb-2">
        <span className="text-sm font-bold text-content font-mono leading-tight">
          {order.order_number}
        </span>
      </div>
      <div className="flex items-center gap-3 text-xs text-content-secondary">
        <span className="flex items-center gap-1">
          <Package size={11} />
          {order.item_count} item{order.item_count !== 1 ? 's' : ''}
        </span>
        <span className="flex items-center gap-1">
          <Clock size={11} />
          {date}
        </span>
      </div>
      {rp && rp.total > 0 && (
        <RenderProgressBar progress={rp} />
      )}
      {order.status === 'rejected' && order.rejection_reason && (
        <p className="mt-2 text-xs text-red-500 italic truncate" title={order.rejection_reason}>
          {order.rejection_reason}
        </p>
      )}
      {order.notes && !rp && order.status !== 'rejected' && (
        <p className="mt-2 text-xs text-content-muted truncate">{order.notes}</p>
      )}
      <div className="mt-2 flex items-center justify-end opacity-0 group-hover:opacity-100 transition-opacity">
        <span className="text-xs text-accent font-medium">Open →</span>
      </div>
    </button>
  )
}

// ── List view ─────────────────────────────────────────────────────────────────

function ListView({
  orders,
  selected,
  allSelected,
  onToggleOne,
  onToggleAll,
  onNavigate,
}: {
  orders: Order[]
  selected: Set<string>
  allSelected: boolean
  onToggleOne: (id: string) => void
  onToggleAll: () => void
  onNavigate: (id: string) => void
}) {
  const deletable = orders.filter((o) => isDeletable(o.status))

  return (
    <div className="flex-1 overflow-y-auto">
      <div className="mx-6 my-4 card overflow-hidden">
        <div className="grid grid-cols-[2rem_1fr_6rem_5rem_6rem] bg-surface-alt border-b border-border-default px-4 py-2.5 text-xs font-semibold text-content-secondary uppercase tracking-wide">
          <div>
            {deletable.length > 0 && (
              <input
                type="checkbox"
                checked={allSelected}
                onChange={onToggleAll}
                className="w-3.5 h-3.5 rounded accent-red-500 cursor-pointer"
              />
            )}
          </div>
          <div>Order</div>
          <div>Items</div>
          <div>Status</div>
          <div>Created</div>
        </div>

        {orders.length === 0 ? (
          <div className="p-10 text-center text-content-muted text-sm">
            No orders match the current filters.
          </div>
        ) : (
          <div className="divide-y divide-border-light">
            {orders.map((order) => {
              const canSelect = isDeletable(order.status)
              const isSelected = selected.has(order.id)
              const meta = STATUS_META[order.status as Status]
              return (
                <div
                  key={order.id}
                  className={`grid grid-cols-[2rem_1fr_6rem_5rem_6rem] items-center px-4 py-3
                              hover:bg-surface-hover transition-colors cursor-pointer
                              ${isSelected ? 'bg-red-50 hover:bg-red-50' : ''}`}
                  onClick={() => onNavigate(order.id)}
                >
                  <div onClick={(e) => e.stopPropagation()}>
                    {canSelect ? (
                      <input
                        type="checkbox"
                        checked={isSelected}
                        onChange={() => onToggleOne(order.id)}
                        className="w-3.5 h-3.5 rounded accent-red-500 cursor-pointer"
                      />
                    ) : <span className="w-3.5 h-3.5 inline-block" />}
                  </div>
                  <div className="min-w-0">
                    <p className="text-sm font-semibold text-content font-mono">{order.order_number}</p>
                    {order.notes && (
                      <p className="text-xs text-content-muted truncate mt-0.5">{order.notes}</p>
                    )}
                  </div>
                  <div className="text-sm text-content-secondary">
                    {order.item_count} item{order.item_count !== 1 ? 's' : ''}
                  </div>
                  <div>
                    <span className={`badge ${meta?.badge ?? 'badge-gray'}`}>{order.status}</span>
                  </div>
                  <div className="text-xs text-content-muted">
                    {new Date(order.created_at).toLocaleDateString('de-DE')}
                  </div>
                </div>
              )
            })}
          </div>
        )}
      </div>
    </div>
  )
}
