using System.Linq; using System.Threading.Tasks; using API.Data; using API.Data.Repositories; using API.DTOs.SeriesDetail; using API.Entities.Enums; using API.Extensions; using API.Helpers.Builders; using API.Services.Plus; using AutoMapper; using Hangfire; using Microsoft.AspNetCore.Mvc; namespace API.Controllers; #nullable enable public class ReviewController : BaseApiController { private readonly IUnitOfWork _unitOfWork; private readonly IMapper _mapper; private readonly IScrobblingService _scrobblingService; public ReviewController(IUnitOfWork unitOfWork, IMapper mapper, IScrobblingService scrobblingService) { _unitOfWork = unitOfWork; _mapper = mapper; _scrobblingService = scrobblingService; } /// /// Updates the review for a given series /// /// /// [HttpPost] public async Task> UpdateReview(UpdateUserReviewDto dto) { var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.Ratings); if (user == null) return Unauthorized(); var ratingBuilder = new RatingBuilder(user.Ratings.FirstOrDefault(r => r.SeriesId == dto.SeriesId)); var rating = ratingBuilder .WithBody(dto.Body) .WithSeriesId(dto.SeriesId) .WithTagline(string.Empty) .WithRating(dto.Rating) .Build(); if (rating.Id == 0) { user.Ratings.Add(rating); } _unitOfWork.UserRepository.Update(user); await _unitOfWork.CommitAsync(); BackgroundJob.Enqueue(() => _scrobblingService.ScrobbleReviewUpdate(user.Id, dto.SeriesId, string.Empty, dto.Body)); return Ok(_mapper.Map(rating)); } /// /// Updates the review for a given series /// /// /// /// [HttpPost("chapter/{chapterId}")] public async Task> UpdateChapterReview(int chapterId, UpdateUserReviewDto dto) { var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.ChapterRatings); if (user == null) return Unauthorized(); var chapter = await _unitOfWork.ChapterRepository.GetChapterAsync(chapterId, ChapterIncludes.None); if (chapter == null) return BadRequest(); var builder = new ChapterRatingBuilder(user.ChapterRatings.FirstOrDefault(r => r.SeriesId == dto.SeriesId)); var rating = builder .WithSeriesId(dto.SeriesId) .WithVolumeId(chapter.VolumeId) .WithChapterId(chapter.Id) .WithRating(dto.Rating) .WithReview(dto.Body) .WithProvider(RatingProvider.Kavita) .Build(); if (rating.Id == 0) { user.ChapterRatings.Add(rating); } _unitOfWork.UserRepository.Update(user); await _unitOfWork.CommitAsync(); // Do I need this? //BackgroundJob.Enqueue(() => // _scrobblingService.ScrobbleReviewUpdate(user.Id, dto.SeriesId, string.Empty, dto.Body)); return Ok(_mapper.Map(rating)); } /// /// Deletes the user's review for the given series /// /// [HttpDelete] public async Task DeleteReview(int seriesId) { var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.Ratings); if (user == null) return Unauthorized(); user.Ratings = user.Ratings.Where(r => r.SeriesId != seriesId).ToList(); _unitOfWork.UserRepository.Update(user); await _unitOfWork.CommitAsync(); return Ok(); } /// /// Deletes the user's review for a given chapter /// /// /// [HttpDelete("chapter/{chapterId}")] public async Task DeleteChapterReview(int chapterId) { var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.ChapterRatings); if (user == null) return Unauthorized(); user.ChapterRatings = user.ChapterRatings.Where(c => c.ChapterId != chapterId).ToList(); _unitOfWork.UserRepository.Update(user); await _unitOfWork.CommitAsync(); return Ok(); } }