using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Asp.Versioning;
using AutoMapper;
using gehGassi.Common.Data;
using gehGassi.Core.Interfaces;
using gehGassi.Domain.Common;
using gehGassi.Domain.News;
using gehGassi.Dto;
using gehGassi.Dto.Common;
using gehGassi.Dto.News;
using gehGassi.Web.Auth;
using gehGassi.Web.Helper;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.TagHelpers.Cache;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NuGet.Protocol;
using NuGet.Protocol.Plugins;
namespace gehGassi.Web.Controllers.Api
{
///
/// Controller der Zugriff auf News via API ermöglicht
///
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ApiController]
[ApiVersion(1)]
[Route("api/news")]
[Route("api/v{v:apiVersion}/news")]
public class ApiNewsController : ApiBaseController
{
private readonly ILogger _logger;
private readonly INewsCategoryService _newsCategoryService;
private readonly INewsService _newsService;
private readonly IGeoLocationService _geoLocationService;
///
/// Erstellt eine Instanz
///
/// Instanz eines IMapper
/// Instanz eines ILogger
/// Instanz von LocalizationOptions
/// Instanz eines INewsCategoryService
/// Instanz eines INewsService
/// Instanz eines IDogOwnerService
/// Instanz eines IGeoLocationService
public ApiNewsController(IMapper mapper, ILogger logger, IOptions localizationOptions, INewsCategoryService newsCategoryService, INewsService newsService,
IAppUserService appUserService, IGeoLocationService geoLocationService) : base(mapper, localizationOptions, appUserService)
{
_logger = logger;
_newsCategoryService = newsCategoryService;
_newsService = newsService;
_geoLocationService = geoLocationService;
}
///
/// Gibt eine Liste von News-Kategorien für die Synchronisierung mit der App zurück
///
/// Letztes Update oder null, wenn noch keines
/// Gewünschte Sprache
/// HTTP 200 wenn erfolgreich
[Route("GetCategories")]
[HttpGet]
public async Task GetCategories(DateTimeOffset? lastUpdate, string language)
{
var clientOffset = GetClientDateOffset();
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
var categories = await _newsCategoryService.GetForSyncAsync(lastUpdate, language, LocalizationOptions.Value.DefaultCulture);
var categoriesDto = Mapper.Map>(categories);
foreach (var newsCategoryDto in categoriesDto)
{
newsCategoryDto.Language = language;
}
return Ok(categoriesDto);
}
return NotFound(CommunicationErrors.Common_NotFound);
}
///
/// Gibt eine Liste von News-Meldungen zurück
///
/// Abfragemodel
/// HTTP 200 wenn erfolgreich
[Route("GetNews")]
[HttpPost]
public async Task GetNews(NewsQueryDto model)
{
var clientOffset = GetClientDateOffset();
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
var response = new ListResponseDto();
//Geodaten holen.
//Entweder wurde lat und lng geliefert, oder wir müssen über den benutzer und den app-mode entscheiden
var (country, state) = await GetGeoDataAsync(model);
//Wir müssen nach Geomode der News vorgehen. Zuerst alle ohne Geo-Beschränkung, dann jene mit Land, dann jene mit Land und Bundesland und dann jene mit Lat & Lng
var visibility = model.AppMode == AppModeDto.DogOwner ? NewsVisibility.DogOwners : NewsVisibility.DogWalkers;
var queryResult = await _newsService.GetForAppAsync(visibility, model.CategoryId, country, state, model.Location.Lat, model.Location.Lng, model.Language, LocalizationOptions.Value.DefaultCulture, model.Skip, model.Take);
response.Total = queryResult.total;
var dtoList = Mapper.Map>(queryResult.list);
var baseAddress = GetBaseAddress();
foreach (var newsDto in dtoList)
{
newsDto.Headline = newsDto.Headline.Ellipsis(97);
if (!string.IsNullOrWhiteSpace(newsDto.Image))
newsDto.Image = $"{baseAddress}/file/documents/thumbnails/{200}/{newsDto.Image}";
newsDto.Url = $"{baseAddress}/{LocalizationOptions.Value.DefaultCulture}/News/show?nid={newsDto.Id}";
}
response.List = dtoList;
response.Take = model.Take;
response.Skip = model.Skip;
return Ok(response);
}
return NotFound(CommunicationErrors.Common_NotFound);
}
}
}