using MahApps.Metro.Controls; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Net; using System.Net.Http; using System.Runtime.CompilerServices; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Web; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; namespace PrototypWPFHAG { /// /// Interaktionslogik für SearchWindow.xaml /// public class DocumentResponse { [JsonPropertyName("documents")] public List Documents { get; set; } } public partial class SearchWindow : MetroWindow { public readonly HttpClient _httpClient; private bool _isSearchInProgress; private readonly PdfServiceClient _pdfServiceClient = new(); private const string BaseUrl = "http://localhost:8000"; // Microservice-URL private string _selectedPdfPath; private List _selectedPdfPaths = new List(); public SearchWindow() { InitializeComponent(); _httpClient = new HttpClient { BaseAddress = new Uri(BaseUrl), Timeout = TimeSpan.FromSeconds(30) }; } private void BackToLogIn_Click(object sender, RoutedEventArgs e) { MainWindow loginWindow = new(); loginWindow.Show(); // Open new window this.Close(); // Close this window } private async void SearchButton_Click(object sender, RoutedEventArgs e) { if (_isSearchInProgress) return; try { _isSearchInProgress = true; SearchButton.IsEnabled = false; if (SearchByIdRadio.IsChecked == true) { await SearchByIdAsync(); } else { await SearchBySimilarityAsync(); } } catch (Exception ex) { MessageBox.Show($"Fehler bei der Suche: {ex.Message}", "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } finally { _isSearchInProgress = false; SearchButton.IsEnabled = true; } } private async Task SearchByIdAsync() { if (!int.TryParse(SearchTextBox.Text, out int documentId)) { MessageBox.Show("Bitte eine gültige ID eingeben"); return; } try { var response = await _httpClient.GetAsync($"/documents/{documentId}"); response.EnsureSuccessStatusCode(); var json = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize(json); await Dispatcher.InvokeAsync(() => { SearchResultsListBox.ItemsSource = new List { result }; ContentTextBox.Text = result.Content; SearchResultsListBox.DisplayMemberPath = "DocumentName"; }); } catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { MessageBox.Show("Dokument nicht gefunden"); } catch (Exception ex) { MessageBox.Show($"Fehler: {ex.Message}"); } } private async Task SearchBySimilarityAsync() { try { var encodedQuery = HttpUtility.UrlEncode(SearchTextBox.Text); var response = await _httpClient.GetAsync($"/documents/search/similarity?query={encodedQuery}"); var json = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize(json); await Dispatcher.InvokeAsync(() => { SearchResultsListBox.ItemsSource = result?.Documents; SearchResultsListBox.DisplayMemberPath = "DocumentName"; }); } catch (Exception ex) { MessageBox.Show($"Fehler: {ex.Message}"); } } private void PdfDropCanvas_DragEnter(object sender, DragEventArgs e) { // Nur PDF-Dateien erlauben if (e.Data.GetDataPresent(DataFormats.FileDrop)) { var files = (string[])e.Data.GetData(DataFormats.FileDrop); if (files.Any(f => System.IO.Path.GetExtension(f).Equals(".pdf", StringComparison.OrdinalIgnoreCase))) { e.Effects = DragDropEffects.Copy; DropHintText.Visibility = Visibility.Collapsed; // Platzhalter ausblenden } } else { e.Effects = DragDropEffects.None; } e.Handled = true; } private void ChoosePdfButton_Click(object sender, RoutedEventArgs e) { var openFileDialog = new Microsoft.Win32.OpenFileDialog { Filter = "PDF Files (*.pdf)|*.pdf", Multiselect = true }; if (openFileDialog.ShowDialog() == true) { _selectedPdfPaths.AddRange(openFileDialog.FileNames); PdfIcon.Visibility = Visibility.Visible; PdfFileNameText.Text = string.Join(", ", _selectedPdfPaths.Select(System.IO.Path.GetFileName)); PdfFileNameText.Visibility = Visibility.Visible; DropHintText.Visibility = Visibility.Collapsed; } } private void PdfDropCanvas_Drop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); var pdfFiles = files.Where(f => System.IO.Path.GetExtension(f).Equals(".pdf", StringComparison.OrdinalIgnoreCase)).ToList(); if (pdfFiles.Any()) { _selectedPdfPaths.AddRange(pdfFiles); // 更新UI以显示所有文件 PdfIcon.Visibility = Visibility.Visible; PdfFileNameText.Text = string.Join(", ", _selectedPdfPaths.Select(System.IO.Path.GetFileName)); PdfFileNameText.Visibility = Visibility.Visible; DropHintText.Visibility = Visibility.Collapsed; } } } // Response-Klassen public class ApiResponse { [JsonPropertyName("success")] public bool Success { get; set; } [JsonPropertyName("document")] public DocumentDetail Document { get; set; } [JsonPropertyName("documents")] public List Documents { get; set; } } public class DocumentDetail : INotifyPropertyChanged { [JsonPropertyName("id")] public int Id { get; set; } [JsonPropertyName("document_name")] public string DocumentName { get; set; } [JsonPropertyName("content")] public string Content { get; set; } [JsonPropertyName("distance")] public double Distance { get; set; } private bool _isSelected; public bool IsSelected { get => _isSelected; set { if (_isSelected != value) { _isSelected = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } public class ApiError { public string Detail { get; set; } } private async void UploadButton_Click(object sender, RoutedEventArgs e) { if (!_selectedPdfPaths.Any()) { MessageBox.Show("Keine PDF ausgewählt!"); return; } UploadProgressBar.Visibility = Visibility.Visible; UploadProgressBar.Value = 0; UploadStatusText.Text = "Upload läuft..."; try { using var formData = new MultipartFormDataContent(); foreach (var pdfPath in _selectedPdfPaths) { var fileContent = new StreamContent(File.OpenRead(pdfPath)); formData.Add(fileContent, "files", Path.GetFileName(pdfPath)); } var response = await _httpClient.PostAsync("/upload-pdfs/", formData); response.EnsureSuccessStatusCode(); var json = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize(json); if (result?.Success == true) { UploadStatusText.Text = "Upload erfolgreich!"; } } catch (Exception ex) { UploadStatusText.Text = $"Fehler: {ex.Message}"; } finally { UploadProgressBar.Visibility = Visibility.Collapsed; _selectedPdfPaths.Clear(); PdfIcon.Visibility = Visibility.Collapsed; PdfFileNameText.Visibility = Visibility.Collapsed; DropHintText.Visibility = Visibility.Visible; } } private async void DeleteButton_Click(object sender, RoutedEventArgs e) { if (SearchResultsListBox.SelectedItems.Count == 0) { MessageBox.Show("Bitte Dokumente auswählen."); return; } var result = MessageBox.Show( $"{SearchResultsListBox.SelectedItems.Count} Dokument(e) löschen?", "Bestätigung", MessageBoxButton.YesNo, MessageBoxImage.Warning ); if (result != MessageBoxResult.Yes) return; var deletedIds = new List(); var errorIds = new List(); foreach (var item in SearchResultsListBox.SelectedItems.Cast().ToList()) { try { var response = await _httpClient.DeleteAsync($"/documents/{item.Id}"); if (response.IsSuccessStatusCode) { deletedIds.Add(item.Id); } else { errorIds.Add(item.Id); } } catch { errorIds.Add(item.Id); } } // Aktualisiere die Liste if (SearchByIdRadio.IsChecked == true) { await SearchByIdAsync(); } else { await SearchBySimilarityAsync(); } // Feedback var message = new StringBuilder(); if (deletedIds.Count > 0) message.AppendLine($"{deletedIds.Count} Dokument(e) gelöscht."); if (errorIds.Count > 0) message.AppendLine($"{errorIds.Count} Dokument(e) konnten nicht gelöscht werden."); MessageBox.Show(message.ToString()); } private async void SearchResultsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (SearchResultsListBox.SelectedItem is DocumentDetail selected) { try { var response = await _httpClient.GetAsync($"/documents/{selected.Id}/markdown"); var content = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize(content); ContentTextBox.Text = result.GetProperty("document") .GetProperty("content") .GetString(); } catch (Exception ex) { ContentTextBox.Text = $"Fehler: {ex.Message}"; } } } } }