using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Windows.Input; using AGEHAB.RelatorioSeadIpasgo.Application.DTOs; using AGEHAB.RelatorioSeadIpasgo.Application.UseCases; using AGEHAB.RelatorioSeadIpasgo.Domain.Entities; using AGEHAB.RelatorioSeadIpasgo.Domain.ValueObjects; using AGEHAB.RelatorioSeadIpasgo.Presentation.Commands; using AGEHAB.RelatorioSeadIpasgo.Presentation.Services; namespace AGEHAB.RelatorioSeadIpasgo.Presentation.ViewModels; public class MainViewModel : ViewModelBase { private readonly CarregarCompetenciasUseCase _carregarCompetenciasUseCase; private readonly GerarRelatorioUseCase _gerarRelatorioUseCase; private readonly IUserDialogService _dialogService; private readonly RelayCommand _escolherZipCommand; private readonly RelayCommand _escolherExcelCommand; private readonly RelayCommand _escolherPastaCommand; private readonly RelayCommand _abrirPastaCommand; private readonly RelayCommand _cancelarCommand; private readonly AsyncRelayCommand _gerarArquivosCommand; private CancellationTokenSource? _cancellationTokenSource; private TipoRelatorioOpcao? _relatorioSelecionado; private Competencia? _competenciaSelecionada; private TipoCalculo? _tipoCalculoSelecionado; private string _zipPath; private string _excelPath; private string _pastaDestino; private string _status = "Pronto para gerar."; private bool _estaOcupado; public MainViewModel( CarregarCompetenciasUseCase carregarCompetenciasUseCase, GerarRelatorioUseCase gerarRelatorioUseCase, IUserDialogService dialogService) { _carregarCompetenciasUseCase = carregarCompetenciasUseCase; _gerarRelatorioUseCase = gerarRelatorioUseCase; _dialogService = dialogService; var desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); _pastaDestino = desktop; _zipPath = Path.Combine(desktop, "REM202606.zip"); _excelPath = Path.Combine(desktop, "Relatorio_SEAD_202606.xlsx"); Relatorios = new ObservableCollection(TipoRelatorioOpcao.Opcoes); TiposCalculo = new ObservableCollection(TipoCalculo.Opcoes); CarregarCommand = new AsyncRelayCommand(CarregarAsync); _gerarArquivosCommand = new AsyncRelayCommand(GerarArquivosAsync, PodeGerar); GerarArquivosCommand = _gerarArquivosCommand; _escolherZipCommand = new RelayCommand(EscolherZip, () => !EstaOcupado && ZipHabilitado); EscolherZipCommand = _escolherZipCommand; _escolherExcelCommand = new RelayCommand(EscolherExcel, () => !EstaOcupado); EscolherExcelCommand = _escolherExcelCommand; _escolherPastaCommand = new RelayCommand(EscolherPasta, () => !EstaOcupado); EscolherPastaCommand = _escolherPastaCommand; _abrirPastaCommand = new RelayCommand(AbrirPastaArquivos, () => !EstaOcupado); AbrirPastaCommand = _abrirPastaCommand; _cancelarCommand = new RelayCommand(CancelarOperacao, () => EstaOcupado); CancelarCommand = _cancelarCommand; RelatorioSelecionado = Relatorios.FirstOrDefault(); TipoCalculoSelecionado = TiposCalculo.FirstOrDefault(tipoCalculo => tipoCalculo.Valor == "1,2,3"); } public ObservableCollection Relatorios { get; } public ObservableCollection Competencias { get; } = []; public ObservableCollection TiposCalculo { get; } public TipoRelatorioOpcao? RelatorioSelecionado { get => _relatorioSelecionado; set { if (SetProperty(ref _relatorioSelecionado, value)) { OnPropertyChanged(nameof(ZipHabilitado)); OnPropertyChanged(nameof(IpasgoSelecionado)); OnPropertyChanged(nameof(AlturaJanela)); AtualizarNomeArquivos(); AtualizarComandos(); } } } public Competencia? CompetenciaSelecionada { get => _competenciaSelecionada; set { if (SetProperty(ref _competenciaSelecionada, value)) { AtualizarNomeArquivos(); AtualizarComandos(); } } } public TipoCalculo? TipoCalculoSelecionado { get => _tipoCalculoSelecionado; set { if (SetProperty(ref _tipoCalculoSelecionado, value)) { AtualizarNomeArquivos(); AtualizarComandos(); } } } public string ZipPath { get => _zipPath; set => SetProperty(ref _zipPath, value); } public string ExcelPath { get => _excelPath; set => SetProperty(ref _excelPath, value); } public string PastaDestino { get => _pastaDestino; set { if (SetProperty(ref _pastaDestino, value)) { AtualizarNomeArquivos(); } } } public string Status { get => _status; set => SetProperty(ref _status, value); } public bool EstaOcupado { get => _estaOcupado; set { if (SetProperty(ref _estaOcupado, value)) { OnPropertyChanged(nameof(ZipHabilitado)); OnPropertyChanged(nameof(CursorAtual)); AtualizarComandos(); } } } public bool ZipHabilitado => !EstaOcupado && RelatorioSelecionado?.EhIpasgo == true; public bool CamposHabilitados => !EstaOcupado; public bool CancelamentoHabilitado => EstaOcupado; public bool IpasgoSelecionado => RelatorioSelecionado?.EhIpasgo == true; public double AlturaJanela => IpasgoSelecionado ? 640 : 560; public Cursor CursorAtual => EstaOcupado ? Cursors.Wait : Cursors.Arrow; public ICommand CarregarCommand { get; } public ICommand GerarArquivosCommand { get; } public ICommand EscolherZipCommand { get; } public ICommand EscolherExcelCommand { get; } public ICommand EscolherPastaCommand { get; } public ICommand AbrirPastaCommand { get; } public ICommand CancelarCommand { get; } private async Task CarregarAsync() { _cancellationTokenSource?.Dispose(); _cancellationTokenSource = new CancellationTokenSource(); EstaOcupado = true; Status = "Carregando competências..."; try { var competencias = await _carregarCompetenciasUseCase.ExecutarAsync(_cancellationTokenSource.Token); Competencias.Clear(); foreach (var competencia in competencias) { Competencias.Add(competencia); } CompetenciaSelecionada = Competencias.FirstOrDefault(); Status = Competencias.Count > 0 ? "Pronto para gerar." : "Nenhuma competência encontrada."; if (Competencias.Count == 0) { _dialogService.Alertar("Nenhuma competência foi encontrada em FP_COMPETENCIAS.", "Competências"); } } catch (OperationCanceledException) { Status = "Operação cancelada pelo usuário."; } catch (Exception ex) { Status = "Erro ao carregar competências."; _dialogService.ExibirErro(ex.Message); } finally { _cancellationTokenSource?.Dispose(); _cancellationTokenSource = null; EstaOcupado = false; } } private async Task GerarArquivosAsync() { if (!ValidarCampos()) { return; } if (!ConfirmarSubstituicoes()) { return; } _cancellationTokenSource?.Dispose(); _cancellationTokenSource = new CancellationTokenSource(); EstaOcupado = true; Status = "Gerando arquivos..."; try { var request = new GerarRelatorioRequest( CompetenciaSelecionada!, RelatorioSelecionado!, TipoCalculoSelecionado!, ZipPath, ExcelPath); await _gerarRelatorioUseCase.ExecutarAsync(request, _cancellationTokenSource.Token); Status = "Arquivos gerados com sucesso."; _dialogService.Informar("Arquivos gerados com sucesso.", "Concluído"); } catch (OperationCanceledException) { Status = "Operação cancelada pelo usuário."; } catch (Exception ex) { if (EhCancelamentoSolicitado(ex)) { Status = "Operação cancelada pelo usuário."; return; } Status = "Erro ao gerar arquivos."; _dialogService.ExibirErro(ex.Message); } finally { _cancellationTokenSource?.Dispose(); _cancellationTokenSource = null; EstaOcupado = false; } } private void CancelarOperacao() { Status = "Cancelando..."; _cancellationTokenSource?.Cancel(); } private void EscolherZip() { var fileName = _dialogService.EscolherArquivoParaSalvar("Salvar arquivo ZIP", "Arquivo ZIP (*.zip)|*.zip", ".zip", ZipPath); if (fileName != null) { ZipPath = fileName; } } private void EscolherExcel() { var fileName = _dialogService.EscolherArquivoParaSalvar("Salvar arquivo Excel", "Arquivo Excel (*.xlsx)|*.xlsx", ".xlsx", ExcelPath); if (fileName != null) { ExcelPath = fileName; } } private void EscolherPasta() { var pasta = _dialogService.EscolherPasta("Selecionar pasta de destino", PastaDestino); if (pasta != null) { PastaDestino = pasta; } } private void AbrirPastaArquivos() { if (!Directory.Exists(PastaDestino)) { _dialogService.Alertar("Nenhuma pasta foi encontrada para abrir.", "Pastas"); return; } AbrirCaminho(PastaDestino); } private bool ValidarCampos() { if (RelatorioSelecionado == null) { _dialogService.Alertar("Selecione o relatório.", "Validação"); return false; } if (CompetenciaSelecionada == null) { _dialogService.Alertar("Selecione uma competência.", "Validação"); return false; } if (TipoCalculoSelecionado == null) { _dialogService.Alertar("Selecione um tipo de cálculo.", "Validação"); return false; } if (RelatorioSelecionado.EhIpasgo && string.IsNullOrWhiteSpace(ZipPath)) { _dialogService.Alertar("Escolha onde salvar o ZIP do IPASGO.", "Validação"); return false; } if (string.IsNullOrWhiteSpace(ExcelPath)) { _dialogService.Alertar("Escolha onde salvar o Excel.", "Validação"); return false; } return true; } private bool ConfirmarSubstituicoes() { if (RelatorioSelecionado?.EhIpasgo == true && File.Exists(ZipPath) && !_dialogService.ConfirmarSubstituicao(ZipPath)) { return false; } if (File.Exists(ExcelPath) && !_dialogService.ConfirmarSubstituicao(ExcelPath)) { return false; } return true; } private bool PodeGerar() { return !EstaOcupado && RelatorioSelecionado != null && CompetenciaSelecionada != null && TipoCalculoSelecionado != null; } private static bool EhCancelamentoSolicitado(Exception ex) { return ex.Message.Contains("Operação cancelada pelo usuário", StringComparison.OrdinalIgnoreCase) || ex.Message.Contains("Operation cancelled", StringComparison.OrdinalIgnoreCase) || ex.Message.Contains("Operation canceled", StringComparison.OrdinalIgnoreCase); } private void AtualizarNomeArquivos() { if (CompetenciaSelecionada == null || RelatorioSelecionado == null || TipoCalculoSelecionado == null) { return; } ZipPath = Path.Combine(PastaDestino, $"REM{CompetenciaSelecionada.Referencia}.zip"); ExcelPath = Path.Combine(PastaDestino, $"Relatorio_{RelatorioSelecionado.PrefixoArquivo}_{CompetenciaSelecionada.Referencia}_{TipoCalculoSelecionado.NomeArquivo}.xlsx"); } private void AtualizarComandos() { _gerarArquivosCommand.RaiseCanExecuteChanged(); _escolherZipCommand.RaiseCanExecuteChanged(); _escolherExcelCommand.RaiseCanExecuteChanged(); _escolherPastaCommand.RaiseCanExecuteChanged(); _abrirPastaCommand.RaiseCanExecuteChanged(); _cancelarCommand.RaiseCanExecuteChanged(); OnPropertyChanged(nameof(ZipHabilitado)); OnPropertyChanged(nameof(CamposHabilitados)); OnPropertyChanged(nameof(CancelamentoHabilitado)); OnPropertyChanged(nameof(CursorAtual)); OnPropertyChanged(nameof(IpasgoSelecionado)); OnPropertyChanged(nameof(AlturaJanela)); } private static void AbrirCaminho(string caminho) { Process.Start(new ProcessStartInfo(caminho) { UseShellExecute = true }); } private static void AdicionarPastaSeExistir(HashSet pastas, string caminhoArquivo) { var pasta = Path.GetDirectoryName(caminhoArquivo); if (!string.IsNullOrWhiteSpace(pasta) && Directory.Exists(pasta)) { pastas.Add(pasta); } } private static string ObterDiretorioInicial(string caminhoAtual) { var diretorio = Path.GetDirectoryName(caminhoAtual); if (!string.IsNullOrWhiteSpace(diretorio) && Directory.Exists(diretorio)) { return diretorio; } return Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); } }