import React, { useState, useMemo } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Badge } from '@/components/ui/badge'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Package, Search, CheckSquare, Loader2, Weight, Info, ArrowUpDown, Undo2 } from 'lucide-react'; import { toast } from 'sonner'; import { applyMarcaFilter } from '@/utils/rangeFilter'; import { naturalSort } from '@/utils/naturalSort'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from '@/components/ui/alert-dialog'; interface ItemDisponivel { id: string; marca: string; descricao: string; tipo: 'peca' | 'componente'; quantidade_disponivel: number; processo_atual_permitido: number; peso_unitario?: number; } interface SeletorPecasSimplesProps { pecasDisponiveis: ItemDisponivel[]; componentesDisponiveis: ItemDisponivel[]; onItemSelect: (item: ItemDisponivel) => void; onBatchSelect: (items: ItemDisponivel[], tipo: 'peca' | 'componente') => void; loading: boolean; onSubmit?: () => void; submitDisabled?: boolean; submitLoading?: boolean; // Props para o botão de desfazer canUndo?: boolean; onUndo?: () => void; undoLoading?: boolean; lastApontamentoId?: string; } export const SeletorPecasSimples: React.FC = ({ pecasDisponiveis = [], componentesDisponiveis = [], onItemSelect, onBatchSelect, loading, onSubmit, submitDisabled = false, submitLoading = false, canUndo = false, onUndo, undoLoading = false, lastApontamentoId }) => { const [filtro, setFiltro] = useState(''); const [activeTab, setActiveTab] = useState('pecas'); const [itemSelecionado, setItemSelecionado] = useState(null); const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc'); // Filtrar e ordenar peças com suporte a range const pecasFiltradas = useMemo(() => { let pecas = pecasDisponiveis; if (filtro) { pecas = pecasDisponiveis.filter(peca => applyMarcaFilter(peca.marca, filtro) || peca.descricao.toLowerCase().includes(filtro.toLowerCase()) ); } // Ordenar numericamente usando naturalSort return [...pecas].sort((a, b) => { const comparison = naturalSort(a.marca, b.marca); return sortOrder === 'asc' ? comparison : -comparison; }); }, [pecasDisponiveis, filtro, sortOrder]); // Filtrar e ordenar componentes com suporte a range const componentesFiltrados = useMemo(() => { let componentes = componentesDisponiveis; if (filtro) { componentes = componentesDisponiveis.filter(comp => applyMarcaFilter(comp.marca, filtro) || comp.descricao.toLowerCase().includes(filtro.toLowerCase()) ); } // Ordenar numericamente usando naturalSort return [...componentes].sort((a, b) => { const comparison = naturalSort(a.marca, b.marca); return sortOrder === 'asc' ? comparison : -comparison; }); }, [componentesDisponiveis, filtro, sortOrder]); // Calcular peso total das peças disponíveis/filtradas const pesoTotalPecas = useMemo(() => { return pecasFiltradas.reduce((total, peca) => { const pesoUnitario = peca.peso_unitario || 0; return total + (pesoUnitario * peca.quantidade_disponivel); }, 0); }, [pecasFiltradas]); // Calcular peso total dos componentes disponíveis/filtrados const pesoTotalComponentes = useMemo(() => { return componentesFiltrados.reduce((total, comp) => { const pesoUnitario = comp.peso_unitario || 0; return total + (pesoUnitario * comp.quantidade_disponivel); }, 0); }, [componentesFiltrados]); const handleItemClick = (item: ItemDisponivel) => { setItemSelecionado(item); onItemSelect(item); }; const handleBatchPecas = () => { if (pecasFiltradas.length === 0) { toast.error('Nenhuma peça disponível para apontamento em lote'); return; } onBatchSelect(pecasFiltradas, 'peca'); }; const handleBatchComponentes = () => { if (componentesFiltrados.length === 0) { toast.error('Nenhum componente disponível para apontamento em lote'); return; } onBatchSelect(componentesFiltrados, 'componente'); }; const formatarPeso = (peso: number) => { return peso.toFixed(2); }; const handleToggleSort = () => { setSortOrder(current => current === 'asc' ? 'desc' : 'asc'); }; if (loading) { return (
Carregando itens disponíveis...
); } return (
Itens Disponíveis

Ordenar {sortOrder === 'asc' ? 'crescente' : 'decrescente'}

Clique para alternar

{/* Botão Desfazer Último Apontamento */} {onUndo && (

Desfazer o último apontamento realizado

{canUndo ? 'Clique para desfazer' : 'Nenhum apontamento para desfazer'}

Confirmar Reversão Tem certeza que deseja desfazer o último apontamento?
Esta ação não pode ser desfeita.
Cancelar Confirmar Reversão
)} {onSubmit && ( )}
{/* Campo de busca com tooltip */}
setFiltro(e.target.value)} className="pl-10 pr-8 bg-background border-border" />

Filtro por range:

Use @ para filtrar intervalos

Exemplo: 32@47 (peças de 32 a 47)

Busca normal: Digite parte da marca

Peças ({pecasFiltradas.length}) - {formatarPeso(pesoTotalPecas)} kg Componentes ({componentesFiltrados.length}) - {formatarPeso(pesoTotalComponentes)} kg {pecasFiltradas.length > 0 && ( )}
{pecasFiltradas.length === 0 ? (

Nenhuma peça disponível

) : ( pecasFiltradas.map((peca) => (
handleItemClick(peca)} className={`p-3 rounded-lg border cursor-pointer transition-all duration-200 ${ itemSelecionado?.id === peca.id ? 'bg-primary/10 border-primary text-foreground' : 'bg-background border-border hover:bg-muted text-foreground' }`} >
{peca.marca}
{peca.descricao}
{peca.peso_unitario && (
Peso unitário: {formatarPeso(peca.peso_unitario)} kg
)}
{peca.quantidade_disponivel} un.
)) )}
{componentesFiltrados.length > 0 && ( )}
{componentesFiltrados.length === 0 ? (

Nenhum componente disponível

) : ( componentesFiltrados.map((comp) => (
handleItemClick(comp)} className={`p-3 rounded-lg border cursor-pointer transition-all duration-200 ${ itemSelecionado?.id === comp.id ? 'bg-primary/10 border-primary text-foreground' : 'bg-background border-border hover:bg-muted text-foreground' }`} >
{comp.marca}
{comp.descricao}
{comp.peso_unitario && (
Peso unitário: {formatarPeso(comp.peso_unitario)} kg
)}
{comp.quantidade_disponivel} un.
)) )}
); };