// <copyright file="TitreRepository.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>

namespace Webzine.Repository
{
    using Microsoft.EntityFrameworkCore;
    using Webzine.EntitiesContext;
    using Webzine.Entity;
    using Webzine.Repository.Contracts;

    /// <summary>
    /// Implémentation de l'interface ITitreRepository.
    /// </summary>
    public class TitreRepository : ITitreRepository
    {
        private readonly WebzineDbContext context;

        /// <summary>
        /// Initializes a new instance of the <see cref="TitreRepository"/> class.
        /// </summary>
        public TitreRepository(WebzineDbContext context)
        {
            this.context = context;
        }

        /// <summary>
        /// Rechercher un titre à l'aide de son nom.
        /// </summary>
        /// <param name="mot">Nom de la musique.</param>
        /// <returns>IEnumerable Titre.</returns>
        public IEnumerable<Titre> Search(string mot)
        {
            if (string.IsNullOrWhiteSpace(mot))
            {
                return Enumerable.Empty<Titre>();
            }

            return this.context.Titres
                .Where(t => !string.IsNullOrWhiteSpace(t.Libelle)
                    && t.Libelle.ToLower().Contains(mot.ToLower()))
                .OrderBy(t => t.Libelle)
                .ToList();
        }

        /// <summary>
        /// Retourne le titre demandé à partir de son identifiant.
        /// </summary>
        /// <param name="idTitre">Id du titre cherché.</param>
        /// <returns>Un titre.</returns>
        public Titre? Find(int idTitre)
        {
            var find = this.context.Titres
                    .Where(t => t.IdTitre == idTitre)
                    .First();

            return find;
        }

        /// <summary>
        /// Retourne les titres demandés (pour la pagination) triés
        /// selon la date de création(du plus récent à ancien).
        /// </summary>
        /// <returns>IEnumerable de Titre.</returns>
        public IEnumerable<Titre> FindTitres(
            int offset,
            int limit)
        {
            return this.context.Titres
                .OrderByDescending(t => t.DateCreation)
                .Include(t => t.Artiste)
                .Skip((offset - 1) * limit)
                .Take(limit)
                .ToList();
        }

        /// <summary>
        /// Retourne tous les titres.
        /// </summary>
        /// <returns>Liste de Titre.</returns>
        public IEnumerable<Titre> FindAll()
        {
            return this.context.Titres
                .AsNoTracking()
                .Include(t => t.Artiste)
                .OrderByDescending(t => t.DateCreation)
                .ToList();
        }

        /// <summary>
        /// Trouver les titres correspondant à un style.
        /// </summary>
        /// <param name="libelle">Style de musique recherché.</param>
        /// <returns>IEnumerable Titre.</returns>
        public IEnumerable<Titre> SearchByStyle(string libelle)
        {
            return this.context.Titres
                .Where(t => t.Styles.Any(s => !string.IsNullOrWhiteSpace(s.Libelle)
                    && s.Libelle.ToLower().Contains(libelle.ToLower())))
                .OrderBy(t => t.Libelle)
                .ToList();
        }
    }
}
