using System.Net.Http.Json; using FluentResults; using NexusReader.Application.Abstractions.Services; using NexusReader.Application.Queries.Reader; namespace NexusReader.Web.Client.Services; public class WasmEpubReader : IEpubReader { private readonly HttpClient _httpClient; public WasmEpubReader(HttpClient httpClient) { _httpClient = httpClient; } public async Task> GetEpubContentAsync( Guid ebookId, int chapterIndex, string? userId = null, CancellationToken cancellationToken = default) { try { var response = await _httpClient.GetAsync($"/api/epub/{ebookId}/{chapterIndex}", cancellationToken); if (response.IsSuccessStatusCode) { var viewModel = await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken); return viewModel != null ? Result.Ok(viewModel) : Result.Fail("Failed to deserialize response."); } var errorBody = await response.Content.ReadAsStringAsync(cancellationToken); return Result.Fail($"Server error ({response.StatusCode}): {errorBody}"); } catch (Exception ex) { return Result.Fail(new Error($"Network or parsing error: {ex.Message}").CausedBy(ex)); } } public async Task> GetEpubResourceAsync( Guid ebookId, string resourcePath, string? userId = null, CancellationToken cancellationToken = default) { try { var response = await _httpClient.GetAsync($"/api/epub/{ebookId}/resource?path={Uri.EscapeDataString(resourcePath)}", cancellationToken); if (response.IsSuccessStatusCode) { var bytes = await response.Content.ReadAsByteArrayAsync(cancellationToken); return Result.Ok(bytes); } var errorBody = await response.Content.ReadAsStringAsync(cancellationToken); return Result.Fail($"Server error fetching EPUB resource ({response.StatusCode}): {errorBody}"); } catch (Exception ex) { return Result.Fail(new Error($"Network error fetching EPUB resource: {ex.Message}").CausedBy(ex)); } } } public class WasmEpubMetadataExtractor : IEpubMetadataExtractor { public async Task> ExtractMetadataAsync(Stream epubStream) { try { using var bookRef = await VersOne.Epub.EpubReader.OpenBookAsync(epubStream); var title = bookRef.Title ?? "Unknown Title"; var author = bookRef.Author ?? "Unknown Author"; byte[]? cover = await bookRef.ReadCoverAsync(); return Result.Ok(new LocalEpubMetadata { Title = title, Author = author, CoverImage = cover }); } catch (Exception ex) { return Result.Fail(new Error($"Failed to extract EPUB metadata locally: {ex.Message}").CausedBy(ex)); } } }