using AutoMapper;
using gehGassi.Core.Interfaces;
using gehGassi.Core.Services;
using gehGassi.Dto.Ratings;
using gehGassi.Dto;
using gehGassi.Web.Helper;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using System.Linq;
using gehGassi.Domain.Favourites;
using gehGassi.Dto.Favourites;
using gehGassi.Domain.Ratings;
using gehGassi.Dto.Common;
using gehGassi.Dto.Advertisements;
using gehGassi.Dto.Dogs;
using gehGassi.Dto.Listings;
using gehGassi.Dto.Lookup;
using gehGassi.Web.Auth;
using gehGassi.Domain.Dogs;
using Asp.Versioning;
namespace gehGassi.Web.Controllers.Api
{
///
/// Controller der die Verwaltung von Favoriten via Api ermöglicht
///
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ApiController]
[ApiVersion(1)]
[Route("api/favourites")]
[Route("api/v{v:apiVersion}/favourites")]
public class ApiFavouritesController : ApiBaseController
{
public const string FavouriteCategory_Advertisement = "Advertisement";
public const string FavouriteCategory_Partner = "Listing";
public const string FavouriteCategory_Walker = "Walker";
public const string FavouriteCategory_Dog = "Dog";
private readonly IFavouriteService _favouriteService;
private readonly IAdvertisementService _advertisementService;
private readonly IListingService _listingService;
private readonly IDogService _dogService;
///
/// Erstellt eine Instanz
///
/// Instanz eines IMapper
/// Instanz von LocalizationOptions
/// Instanz eines IAppUserService
/// Instanz eines IFavouriteService
/// Instanz eines IAdvertisementService
/// Instanz eines IListingService
/// Instanz eines IDogService
public ApiFavouritesController(IMapper mapper, IOptions localizationOptions, IAppUserService appUserService, IFavouriteService favouriteService,
IAdvertisementService advertisementService, IListingService listingService, IDogService dogService) : base(mapper, localizationOptions, appUserService)
{
_favouriteService = favouriteService;
_advertisementService = advertisementService;
_listingService = listingService;
_dogService = dogService;
}
///
/// Abfrage der Favoriten eines AppUsers
///
/// Id des AppUsers
/// Letztes Update oder null, wenn noch keines
/// Liste der Favoriten
[HttpGet]
[Route("GetFavouritesForSync")]
public async Task GetFavouritesForSync(string appUserId, DateTimeOffset? lastUpdate)
{
var clientOffset = GetClientDateOffset();
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
var favourites = await _favouriteService.GetForSyncAppAsync(appUserId, lastUpdate);
var dtoList = Mapper.Map>(favourites);
return Ok(dtoList);
}
return NotFound(CommunicationErrors.Common_NotFound);
}
///
/// Anlegen eines Favoriten
///
/// FavouriteDto
/// HTTP 200 OK, Felher sonst
[HttpPost]
[Route("CreateFavourite")]
public async Task CreateFavourite(FavouriteDto model)
{
var clientOffset = GetClientDateOffset();
var result = new CreateResponseDto
{
Status = CreateStatusDto.Error,
Value = null
};
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
if (ModelState.IsValid)
{
var existingFavourite = await _favouriteService.GetAsync(model.Id);
if (existingFavourite == null)
{
var favourite = Mapper.Map(model);
_favouriteService.Add(favourite);
await _favouriteService.CommitAsync(User.Identity.Name);
result.Status = CreateStatusDto.Success;
result.Value = Mapper.Map(favourite);
}
else
{
result.Status = CreateStatusDto.Exists;
}
return Ok(result);
}
}
return BadRequest(CommunicationErrors.Common_Model_Invalid);
}
///
/// Aktualisieren eines Favoriten
///
/// FavouriteDto
/// HTTP 200 OK, Felher sonst
[HttpPost]
[Route("UpdateFavourite")]
public async Task UpdateFavourite(FavouriteDto model)
{
var clientOffset = GetClientDateOffset();
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
if (ModelState.IsValid)
{
var favourite = await _favouriteService.GetAsync(model.Id);
if (favourite != null)
{
if (model.UpdatedAt > favourite.UpdatedAt)
{
Mapper.Map(model, favourite);
await _favouriteService.CommitAsync(User.Identity.Name);
}
return Ok();
}
return NotFound(CommunicationErrors.Common_NotFound);
}
return BadRequest(CommunicationErrors.Common_Model_Invalid);
}
return NotFound(CommunicationErrors.Common_NotFound);
}
///
/// Löschen eines Favoriten
///
/// FavouriteDto
/// Id des App-Users
/// 200OK
[HttpPost]
[Route("DeleteFavourite")]
public async Task DeleteFavourite(FavouriteDto model, [FromQuery] string appUserId)
{
var clientOffset = GetClientDateOffset();
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
if (ModelState.IsValid)
{
var favourite = await _favouriteService.GetAsync(model.Id);
if (favourite != null)
{
var appUser = await AppUserService.GetAsync(appUserId);
if (appUser != null)
{
if (favourite.AppUserId == appUser.Id)
{
_favouriteService.Remove(favourite);
await _favouriteService.CommitAsync(User.Identity.Name);
return Ok();
}
}
}
return NotFound(CommunicationErrors.Common_NotFound);
}
return BadRequest(CommunicationErrors.Common_Model_Invalid);
}
return NotFound(CommunicationErrors.Common_NotFound);
}
///
/// Gibt eine Liste von Favoriten für einen Objekttyp und einen AppUser zurück
///
/// Abfragemodel
/// HTTP 200 wenn erfolgreich
[Route("GetFavouritesList")]
[HttpPost]
public async Task GetFavouritesList(FavouriteListQueryDto model)
{
var clientOffset = GetClientDateOffset();
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
var appUserId = User.AppUserId();
var list = new List();
var favourites = await _favouriteService.GetForAppUserAsync(model.AppUserId, model.Table);
if (favourites != null && favourites.Any())
{
foreach (var favourite in favourites.OrderByDescending(c => c.Created))
{
switch (favourite.Table)
{
case FavouriteCategory_Advertisement:
list.Add(await GetAdvertisementAsync(favourite, model.Language));
break;
case FavouriteCategory_Partner:
list.Add(await GetListingAsync(favourite, model.Language));
break;
case FavouriteCategory_Dog:
list.Add(await GetDogAsync(favourite, appUserId));
break;
case FavouriteCategory_Walker:
list.Add(await GetDogWalkerAsync(favourite, appUserId));
break;
}
}
}
return Ok(list);
}
return NotFound(CommunicationErrors.Common_NotFound);
}
#region private
///
/// Holt eine Werbung zu einem Favoriten
///
/// Favorit
/// Gewünschte Sprache
/// FavouriteListItemDto
private async Task GetAdvertisementAsync(Favourite favourite, string language)
{
var item = new FavouriteListItemDto
{
NotAvailable = true,
Id = favourite.Id,
UpdatedAt = favourite.UpdatedAt,
Deleted = favourite.Deleted,
AppUserId = favourite.AppUserId,
Key = favourite.Key,
Table = favourite.Table,
Created = favourite.Created
};
var advertisement = await _advertisementService.GetRunningWithNamesAsync(favourite.Key, language, LocalizationOptions.Value.DefaultCulture);
if (advertisement != null)
{
var baseAddress = GetBaseAddress();
item.NotAvailable = advertisement.Deleted;
item.Advertisement = Mapper.Map(advertisement);
if (!string.IsNullOrWhiteSpace(item.Advertisement.Image))
item.Advertisement.Image = $"{baseAddress}/file/documents/thumbnails/{400}/{item.Advertisement.Image}";
if (!string.IsNullOrWhiteSpace(item.Advertisement.ImageLanguage))
item.Advertisement.ImageLanguage = $"{baseAddress}/file/documents/thumbnails/{400}/{item.Advertisement.ImageLanguage}";
}
return item;
}
///
/// Holt eine Listung zu einem Favoriten
///
/// Favorit
/// Gewünschte Sprache
/// FavouriteListItemDto
private async Task GetListingAsync(Favourite favourite, string language)
{
var item = new FavouriteListItemDto
{
NotAvailable = true,
Id = favourite.Id,
UpdatedAt = favourite.UpdatedAt,
Deleted = favourite.Deleted,
AppUserId = favourite.AppUserId,
Key = favourite.Key,
Table = favourite.Table,
Created = favourite.Created
};
var listing = await _listingService.GetRunningWithNamesAsync(favourite.Key, language, LocalizationOptions.Value.DefaultCulture);
if (listing != null)
{
var baseAddress = GetBaseAddress();
item.NotAvailable = listing.Deleted;
item.Listing = Mapper.Map(listing);
if (!string.IsNullOrWhiteSpace(item.Listing.Image))
item.Listing.Image = $"{baseAddress}/file/documents/thumbnails/{200}/{item.Listing.Image}";
if (!string.IsNullOrWhiteSpace(item.Listing.ImageLanguage))
item.Listing.ImageLanguage = $"{baseAddress}/file/documents/thumbnails/{400}/{item.Listing.ImageLanguage}";
}
return item;
}
///
/// Holt einen Hund zu einem Favoriten
///
/// Favorit
/// Id des AppUsers der die Abfrage durchführt
/// FavouriteListItemDto
private async Task GetDogAsync(Favourite favourite, string appUserId)
{
var item = new FavouriteListItemDto
{
NotAvailable = true,
Id = favourite.Id,
UpdatedAt = favourite.UpdatedAt,
Deleted = favourite.Deleted,
AppUserId = favourite.AppUserId,
Key = favourite.Key,
Table = favourite.Table,
Created = favourite.Created
};
var dog = await _dogService.GetAsync(favourite.Key);
if (dog != null)
{
var baseAddress = GetBaseAddress();
item.NotAvailable = dog.Deleted;
item.Dog = Mapper.Map(dog);
item.Dog.Photo = !string.IsNullOrWhiteSpace(item.Dog.Photo) ? $"{baseAddress}/file/documents/thumbnails/{400}/{item.Dog.Photo}" : "";
item.Locked = await AppUserService.IsLockedAsync(dog.AppUserId);
item.Blocked = await AppUserService.IsBlockedAsync(appUserId, dog.AppUserId);
}
return item;
}
///
/// Holt einen DogWalker zu einem Favoriten
///
/// Favorit
/// Id des AppUsers der die Abfrage durchführt
/// FavouriteListItemDto
private async Task GetDogWalkerAsync(Favourite favourite, string appUserId)
{
var item = new FavouriteListItemDto
{
NotAvailable = true,
Id = favourite.Id,
UpdatedAt = favourite.UpdatedAt,
Deleted = favourite.Deleted,
AppUserId = favourite.AppUserId,
Key = favourite.Key,
Table = favourite.Table,
Created = favourite.Created
};
var dogWalker = await AppUserService.GetWalkerAsync(favourite.Key);
if (dogWalker != null)
{
var baseAddress = GetBaseAddress();
item.NotAvailable = dogWalker.Deleted;
item.DogWalker = Mapper.Map(dogWalker);
item.DogWalker.Photo = !string.IsNullOrWhiteSpace(item.DogWalker.Photo) ? $"{baseAddress}/file/documents/thumbnails/{400}/{item.DogWalker.Photo}" : "";
item.Locked = await AppUserService.IsLockedAsync(dogWalker.Id);
item.Blocked = await AppUserService.IsBlockedAsync(appUserId, dogWalker.Id);
}
return item;
}
#endregion
}
}