use crate::application::usecases::exportar_pdf::exportar_pdf; use crate::domain::{ entities::resultado_analise::ResultadoAnalise, services::parser_monetario::formatar_valor_br, }; use crate::infrastructure::pdf_generator::GenpdfGenerator; use crate::ui::app::{AcaoModal, App, EstadoApp}; use egui::{Context, Ui}; const OPCOES_PAGINA: &[usize] = &[50, 100, 200, 1000]; /// Renderiza a tela de resultados. pub fn renderizar(ui: &mut Ui, _ctx: &Context, app: &mut App) { // Extrair resultado do estado (sem mover) let resultado = match &app.estado { EstadoApp::ExibindoResultado(r) => r.clone(), _ => return, }; ui.heading("Resultado da Análise"); ui.add_space(8.0); ui.horizontal(|ui| { if ui.button("< Nova Análise").clicked() { app.exibir_confirmacao( "Nova Análise", "Deseja iniciar uma nova análise? O resultado atual será descartado.", AcaoModal::ConfirmarNovaAnalise, ); } if ui.button("⚙ Reconfigurar Colunas").clicked() { app.estado = EstadoApp::ConfigurandoColunas; return; } if ui.button("📄 Exportar PDF").clicked() { exportar_para_pdf(app, &resultado); } }); ui.add_space(8.0); // Controle de itens por página ui.horizontal(|ui| { ui.label("Itens por página:"); for &opcao in OPCOES_PAGINA { if ui .selectable_label(app.itens_por_pagina == opcao, opcao.to_string()) .clicked() { app.itens_por_pagina = opcao; app.pagina_faltantes = 0; app.pagina_duplicatas = 0; } } }); ui.add_space(12.0); ui.separator(); egui::ScrollArea::vertical().show(ui, |ui| { // Faltantes renderizar_faltantes(ui, app, &resultado); ui.add_space(12.0); ui.separator(); // Duplicatas renderizar_duplicatas(ui, app, &resultado); ui.add_space(12.0); ui.separator(); // Totais renderizar_totais(ui, &resultado); }); } fn renderizar_totais(ui: &mut Ui, resultado: &ResultadoAnalise) { ui.label(egui::RichText::new("Totais").heading().strong()); ui.add_space(4.0); ui.label(format!( "Total Geral: R$ {}", formatar_valor_br(&resultado.soma_total) )); let mut series: Vec<&String> = resultado.soma_por_serie.keys().collect(); series.sort(); for serie in series { let soma = &resultado.soma_por_serie[serie]; let total_notas = resultado.total_por_serie.get(serie).copied().unwrap_or(0); ui.label(format!( " Série {}: {} nota(s) — R$ {}", serie, total_notas, formatar_valor_br(soma) )); } } fn renderizar_faltantes(ui: &mut Ui, app: &mut App, resultado: &ResultadoAnalise) { let total_faltantes = resultado.total_faltantes(); ui.label( egui::RichText::new(format!( "Notas Faltantes ({} total)", total_faltantes )) .heading() .strong(), ); ui.add_space(4.0); if total_faltantes == 0 { ui.label("✔ Nenhuma nota faltante."); return; } let mut series: Vec<&String> = resultado.faltantes_por_serie.keys().collect(); series.sort(); for serie in series { let faltantes = &resultado.faltantes_por_serie[serie]; if faltantes.is_empty() { continue; } ui.label(format!( "Série {} — {} faltante(s):", serie, faltantes.len() )); // Paginação let total_paginas = (faltantes.len() + app.itens_por_pagina - 1) / app.itens_por_pagina; if app.pagina_faltantes >= total_paginas { app.pagina_faltantes = 0; } let inicio = app.pagina_faltantes * app.itens_por_pagina; let fim = (inicio + app.itens_por_pagina).min(faltantes.len()); for numero in &faltantes[inicio..fim] { ui.label(format!(" • {}", numero)); } if total_paginas > 1 { ui.horizontal(|ui| { if ui.button("◀").clicked() && app.pagina_faltantes > 0 { app.pagina_faltantes -= 1; } ui.label(format!( "Página {} / {}", app.pagina_faltantes + 1, total_paginas )); if ui.button("▶").clicked() && app.pagina_faltantes + 1 < total_paginas { app.pagina_faltantes += 1; } }); } } } fn renderizar_duplicatas(ui: &mut Ui, app: &mut App, resultado: &ResultadoAnalise) { let total_dup = resultado.total_duplicatas(); ui.label( egui::RichText::new(format!( "Notas Duplicadas ({} grupo(s))", total_dup )) .heading() .strong(), ); ui.add_space(4.0); if total_dup == 0 { ui.label("✔ Nenhuma nota duplicada."); return; } let mut series: Vec<&String> = resultado.duplicadas_por_serie.keys().collect(); series.sort(); for serie in series { let duplicatas = &resultado.duplicadas_por_serie[serie]; if duplicatas.is_empty() { continue; } ui.label(format!( "Série {} — {} grupo(s) duplicado(s):", serie, duplicatas.len() )); let total_paginas = (duplicatas.len() + app.itens_por_pagina - 1) / app.itens_por_pagina; if app.pagina_duplicatas >= total_paginas { app.pagina_duplicatas = 0; } let inicio = app.pagina_duplicatas * app.itens_por_pagina; let fim = (inicio + app.itens_por_pagina).min(duplicatas.len()); for (numero, count) in &duplicatas[inicio..fim] { ui.label(format!( " • NF {} / Série {} — {} ocorrências", numero, serie, count )); } if total_paginas > 1 { ui.horizontal(|ui| { if ui.button("◀").clicked() && app.pagina_duplicatas > 0 { app.pagina_duplicatas -= 1; } ui.label(format!( "Página {} / {}", app.pagina_duplicatas + 1, total_paginas )); if ui.button("▶").clicked() && app.pagina_duplicatas + 1 < total_paginas { app.pagina_duplicatas += 1; } }); } } } fn exportar_para_pdf(app: &mut App, resultado: &ResultadoAnalise) { if let Some(caminho) = rfd::FileDialog::new() .set_file_name("relatorio.pdf") .add_filter("PDF", &["pdf"]) .save_file() { let gerador = GenpdfGenerator; let nome_layout = if app.nome_layout_atual.is_empty() { None } else { Some(app.nome_layout_atual.as_str()) }; match exportar_pdf( &gerador, resultado, &app.nome_arquivo, nome_layout, &caminho, ) { Ok(_) => { app.exibir_aviso("Sucesso", format!("PDF exportado para: {}", caminho.display())); } Err(e) => { app.exibir_erro(format!("Erro ao exportar PDF: {}", e)); } } } }