import React, { useState, useMemo } from 'react';
import { StandardPageLayout } from '@/components/layout/StandardPageLayout';
import { KanbanPrioridadesFabricacao } from '@/components/prioridades/KanbanPrioridadesFabricacao';
import { PecaSelectorModal } from '@/components/prioridades/PecaSelectorModal';
import { PrioridadesPDF } from '@/components/prioridades/PrioridadesPDF';
import { FiltrosVisualizacao } from '@/components/prioridades/FiltrosVisualizacao';
import { useItensPrioridadeFabricacaoFiltrado } from '@/hooks/useItensPrioridadeFabricacaoFiltrado';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Plus, FileText, RefreshCw, Printer } from 'lucide-react';
import { toast } from 'sonner';
const PrioridadesFabricacao = () => {
const {
itensPorPrioridade,
loading,
atualizarQuantidade,
removerItem,
removerItensPorPrioridade,
transferirItem,
reorderItems,
refetch,
ofSelecionada,
faseSelecionada,
versaoAtual,
onFiltroChange
} = useItensPrioridadeFabricacaoFiltrado();
const [showPecaSelector, setShowPecaSelector] = useState(false);
const [showPrioridadesPDF, setShowPrioridadesPDF] = useState(false);
// Construir título dinâmico
const tituloCompleto = useMemo(() => {
if (ofSelecionada && faseSelecionada) {
return `Prioridades de Fabricação - OF: ${ofSelecionada} - FASE: ${faseSelecionada}`;
}
return 'Prioridades de Fabricação';
}, [ofSelecionada, faseSelecionada]);
const calcularTotalPecas = () => {
return Object.values(itensPorPrioridade).reduce((total, itens) => total + itens.length, 0);
};
const calcularPesoTotal = () => {
return Object.values(itensPorPrioridade).reduce((total, itens) => {
return total + itens.reduce((pesoItens, item) => pesoItens + (item.peso_total || 0), 0);
}, 0);
};
const handleAddPecas = async () => {
await refetch();
};
const generateTickBoxesHTML = (quantity: number): string => {
let boxesHtml = '';
if (quantity > 10) {
const numBigBoxes = Math.floor(quantity / 5);
const numSmallBoxes = quantity % 5;
for (let i = 0; i < numBigBoxes; i++) {
boxesHtml += `
5
`;
}
for (let i = 0; i < numSmallBoxes; i++) {
boxesHtml += ``;
}
} else {
for (let i = 0; i < quantity; i++) {
boxesHtml += ``;
}
}
return `${boxesHtml}
`;
};
const handleImprimirRelatorio = async () => {
if (!ofSelecionada || !faseSelecionada) {
toast.error('Selecione uma OF e Fase para imprimir o relatório');
return;
}
try {
// Criar nova janela para impressão
const printWindow = window.open('', '_blank');
if (!printWindow) {
throw new Error('Não foi possível abrir janela de impressão');
}
// Obter data atual formatada
const dataAtual = new Date().toLocaleDateString('pt-BR');
// Gerar conteúdo dos itens por prioridade
let itemsContent = '';
['P1', 'P2', 'P3', 'P4'].forEach((codigo, priorityIndex) => {
const itens = itensPorPrioridade[codigo] || [];
if (itens.length === 0) return;
const getPrioridadeNome = (codigo: string) => {
switch (codigo) {
case 'P1': return 'Prioridade P1 - Urgente';
case 'P2': return 'Prioridade P2 - Alta';
case 'P3': return 'Prioridade P3 - Média';
case 'P4': return 'Prioridade P4 - Baixa';
default: return 'Desconhecida';
}
};
const getCoresPrioridade = (codigo: string) => {
switch (codigo) {
case 'P1': return 'text-red-700 bg-red-100';
case 'P2': return 'text-orange-700 bg-orange-100';
case 'P3': return 'text-blue-700 bg-blue-100';
case 'P4': return 'text-gray-700 bg-gray-200';
default: return 'text-gray-700 bg-gray-200';
}
};
// Adicionar classe page-break para P2, P3 e P4
const pageBreakClass = priorityIndex > 0 ? 'page-break' : '';
itemsContent += `
${getPrioridadeNome(codigo)}
`;
// Gerar linhas de itens (3 por linha)
for (let i = 0; i < Math.ceil(itens.length / 3); i++) {
const bgColorClass = i % 2 !== 0 ? 'bg-gray-50' : 'bg-white';
const rowItems = itens.slice(i * 3, (i + 1) * 3);
itemsContent += `
`;
rowItems.forEach((item) => {
const quantidade = item.quantidade_priorizada;
const marca = item.peca?.marca || 'N/A';
const temComponentes = item.peca?.tem_componentes;
const infoType = temComponentes ? '(C/M)' : '(S/M)';
const tickBoxes = generateTickBoxesHTML(quantidade);
itemsContent += `
${marca} (${quantidade})
${infoType}
${tickBoxes}
`;
});
// Preencher células vazias se necessário
for (let j = rowItems.length; j < 3; j++) {
itemsContent += `
`;
}
itemsContent += `
`;
}
itemsContent += `
`;
});
// HTML completo seguindo exatamente o modelo fornecido
const printContent = `
Checklist de Produção por Prioridade
Checklist de Produção
Formulário para apontamento da fabricação.
Data de Emissão: ${dataAtual}
${versaoAtual ? `Rev. ${versaoAtual.revisao}` : ''}
Ordem de Fabricação (OF)
${ofSelecionada}
Legenda:
Marca (Qtd)
(S/M)
= Sem Montagem,
(C/M)
= Com Montagem. Os quadrados
indicam o controle de peças fabricadas.
${itemsContent}
`;
printWindow.document.write(printContent);
printWindow.document.close();
toast.success('Relatório enviado para impressão');
} catch (error) {
console.error('Erro ao imprimir:', error);
toast.error('Erro ao imprimir o relatório');
}
};
return (
{/* Filtros de Visualização */}
{/* Header com resumo e ações */}
Total de Peças:
{calcularTotalPecas()}
Peso Total:
{calcularPesoTotal().toFixed(1)} kg
{versaoAtual && (
Revisão:
{versaoAtual.revisao}
)}
{/* Componente Kanban */}
{loading ? (
) : ofSelecionada && faseSelecionada ? (
) : (
Selecione uma OF e Fase nos filtros acima para visualizar o Kanban de prioridades.
)}
{/* Modais */}
setShowPecaSelector(false)}
onAddPecas={handleAddPecas}
/>
setShowPrioridadesPDF(false)}
itensPorPrioridade={itensPorPrioridade}
versaoAtual={versaoAtual}
/>
{/* Componente oculto para impressão */}
{(ofSelecionada && faseSelecionada) && (
{/* Usar o mesmo template do PDF */}
Checklist de Produção
Formulário para apontamento da fabricação.
Data de Emissão: {new Date().toLocaleDateString('pt-BR')}
{versaoAtual && (
Rev. {versaoAtual.revisao}
)}
Ordem de Fabricação (OF)
{ofSelecionada}
PROCESSO
{['Corte', 'Solda', 'Pintura', 'Expedição'].map((processo) => (
))}
Legenda:
Marca (Qtd)
(S/M)
= Sem Montagem,
(C/M)
= Com Montagem. Os quadrados indicam o controle de peças fabricadas.
{/* Renderizar os itens por prioridade */}
{['P1', 'P2', 'P3', 'P4'].map((codigo, priorityIndex) => {
const itens = itensPorPrioridade[codigo] || [];
if (itens.length === 0) return null;
const getPrioridadeNome = (codigo: string) => {
switch (codigo) {
case 'P1': return 'Prioridade P1 - Urgente';
case 'P2': return 'Prioridade P2 - Alta';
case 'P3': return 'Prioridade P3 - Média';
case 'P4': return 'Prioridade P4 - Baixa';
default: return 'Desconhecida';
}
};
const getCoresPrioridade = (codigo: string) => {
switch (codigo) {
case 'P1': return 'text-red-700 bg-red-100';
case 'P2': return 'text-orange-700 bg-orange-100';
case 'P3': return 'text-blue-700 bg-blue-100';
case 'P4': return 'text-gray-700 bg-gray-200';
default: return 'text-gray-700 bg-gray-200';
}
};
return (
{getPrioridadeNome(codigo)}
{Array.from({ length: Math.ceil(itens.length / 3) }, (_, i) => {
const bgColorClass = i % 2 !== 0 ? 'bg-gray-50' : 'bg-white';
const rowItems = itens.slice(i * 3, (i + 1) * 3);
return (
{rowItems.map((item) => {
const quantidade = item.quantidade_priorizada;
const marca = item.peca?.marca || 'N/A';
const temComponentes = item.peca?.tem_componentes;
const infoType = temComponentes ? '(C/M)' : '(S/M)';
// Gerar checkboxes
const generateTickBoxes = (quantity: number) => {
const boxes = [];
if (quantity > 10) {
const numBigBoxes = Math.floor(quantity / 5);
const numSmallBoxes = quantity % 5;
for (let i = 0; i < numBigBoxes; i++) {
boxes.push(
5
);
}
for (let i = 0; i < numSmallBoxes; i++) {
boxes.push(
);
}
} else {
for (let i = 0; i < quantity; i++) {
boxes.push(
);
}
}
return
{boxes}
;
};
return (
{marca} ({quantidade})
{infoType}
{generateTickBoxes(quantidade)}
);
})}
{/* Preencher células vazias se necessário */}
{Array.from({ length: 3 - rowItems.length }, (_, emptyIndex) => (
))}
);
})}
);
})}
)}
);
};
export default PrioridadesFabricacao;